From 5ddf20f85da519e60ebf41c168aca71a726cc4db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Mon, 6 Jan 2020 20:02:44 +0800 Subject: [PATCH 001/156] =?UTF-8?q?=E9=A2=98=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/modules/question/component/Contentpart.js | 14 +------------- .../src/modules/question/component/SiderBars.js | 5 +++++ .../modules/question/questioncss/questioncom.css | 10 ++++++++++ 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/public/react/src/modules/question/component/Contentpart.js b/public/react/src/modules/question/component/Contentpart.js index 859ab9dd2..60960585f 100644 --- a/public/react/src/modules/question/component/Contentpart.js +++ b/public/react/src/modules/question/component/Contentpart.js @@ -71,7 +71,7 @@ class Contentpart extends Component { const contents = (

this.props.setoj_status(null)}>全部

@@ -173,18 +173,6 @@ class Contentpart extends Component { } - - - - {/* trigger.parentNode} placement="bottom" trigger="hover" content={content} onVisibleChange={()=>this.props.handleVisibleChanges(true)}>*/} - {/*
*/} - {/*
*/} - {/* 题型*/} - {/*
*/} - {/* */} - {/*
*/} - {/*
*/} - { defaultActiveKey===0||defaultActiveKey==="0"? +
this.props.showDrawer()} > +
+ 132 +
+ diff --git a/public/react/src/modules/question/questioncss/questioncom.css b/public/react/src/modules/question/questioncss/questioncom.css index f61cfb8fd..fb33d40df 100644 --- a/public/react/src/modules/question/questioncss/questioncom.css +++ b/public/react/src/modules/question/questioncss/questioncom.css @@ -882,3 +882,13 @@ border-radius: 4px; top: -50%; } +.shitikussmys{ + width:29px; + height:20px; + background:#FF6601; + border-radius:10px; + position: absolute; + font-size:11px; + color:#ffffff; + line-height:14px; +} From 8836be0717922173c7ab7b3d395d9519d4d09df1 Mon Sep 17 00:00:00 2001 From: daiao <358551898@qq.com> Date: Mon, 6 Jan 2020 20:45:50 +0800 Subject: [PATCH 002/156] =?UTF-8?q?=E7=BC=96=E7=A0=81=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/shixuns_controller.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/controllers/shixuns_controller.rb b/app/controllers/shixuns_controller.rb index 7009726d8..4e749ab0d 100644 --- a/app/controllers/shixuns_controller.rb +++ b/app/controllers/shixuns_controller.rb @@ -888,9 +888,10 @@ class ShixunsController < ApplicationController def upload_git_file upload_file = params["file"] - uid_logger("#########################file_params####{params["#{params[:file]}"]}") + uid_logger("#########################file_params##: #{params["file"]}") raise "未上传文件" unless upload_file content = upload_file.tempfile.read + uid_logger("#########################content####{content}") author_name = current_user.real_name author_email = current_user.git_mail message = params[:message] || "upload file by browser" From 5578c687897b545a160048e18f54d7c154a64bbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Mon, 6 Jan 2020 20:51:24 +0800 Subject: [PATCH 003/156] =?UTF-8?q?=E9=A2=98=E5=BA=93=E5=88=86=E6=94=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modules/question/questioncss/questioncom.css | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/public/react/src/modules/question/questioncss/questioncom.css b/public/react/src/modules/question/questioncss/questioncom.css index fb33d40df..8db839b31 100644 --- a/public/react/src/modules/question/questioncss/questioncom.css +++ b/public/react/src/modules/question/questioncss/questioncom.css @@ -883,12 +883,12 @@ top: -50%; } .shitikussmys{ - width:29px; - height:20px; - background:#FF6601; - border-radius:10px; - position: absolute; - font-size:11px; - color:#ffffff; - line-height:14px; + width:29px !important; + height:20px!important; + background:#FF6601 !important; + border-radius:10px !important; + position: absolute !important; + font-size:11px !important; + color:#ffffff !important; + line-height:14px !important; } From 37bbeee28ebe1dfce22764047af9f97794caad71 Mon Sep 17 00:00:00 2001 From: daiao <358551898@qq.com> Date: Tue, 7 Jan 2020 09:11:08 +0800 Subject: [PATCH 004/156] =?UTF-8?q?=E6=89=93=E5=8D=B0=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/shixuns_controller.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/controllers/shixuns_controller.rb b/app/controllers/shixuns_controller.rb index 4e749ab0d..35aee9ffa 100644 --- a/app/controllers/shixuns_controller.rb +++ b/app/controllers/shixuns_controller.rb @@ -895,6 +895,7 @@ class ShixunsController < ApplicationController author_name = current_user.real_name author_email = current_user.git_mail message = params[:message] || "upload file by browser" + uid_logger("-----author_email: #{author_email}") update_file_content(content, @repo_path, @path, author_email, author_name, message) render_ok end From 0f6103a04452b963a197bc2036d8fb5fcce4dbd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Tue, 7 Jan 2020 09:57:27 +0800 Subject: [PATCH 005/156] =?UTF-8?q?=E9=A2=98=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/react/src/modules/question/Question.js | 63 ++++++++++++++----- .../modules/question/animation/parabola.js | 51 +++++++++++++++ .../modules/question/component/SiderBars.js | 17 +++-- .../question/questioncss/questioncom.css | 24 ++++++- public/react/src/modules/tpm/TPMIndex.css | 28 ++++++++- 5 files changed, 159 insertions(+), 24 deletions(-) create mode 100644 public/react/src/modules/question/animation/parabola.js diff --git a/public/react/src/modules/question/Question.js b/public/react/src/modules/question/Question.js index 51d50932e..44d42ac6c 100644 --- a/public/react/src/modules/question/Question.js +++ b/public/react/src/modules/question/Question.js @@ -11,6 +11,7 @@ import { Input, Tooltip } from "antd"; +import {parabola} from './animation/parabola' import Headplugselections from "./component/Headplugselections"; import QuestionModal from "./component/QuestionModal"; import QuestionModals from "./component/QuestionModals"; @@ -63,6 +64,7 @@ class Question extends Component { disciplinesdatazsd:0, selectallquestionsonthispages:false, oj_status:null, + isVisible: false, } } @@ -206,6 +208,7 @@ class Question extends Component { } + //刷新加载 getdata = (data) => { const url = `/item_banks.json`; this.setState({ @@ -240,6 +243,34 @@ class Question extends Component { }); } + //不刷新加载 + getdatasy = (data) => { + const url = `/item_banks.json`; + + axios.get((url), {params: data}).then((response) => { + setTimeout(()=>{ + + },1000); + if (response === null || response === undefined) { + + return + } + if (response.data.status === 403 || response.data.status === 401 || response.data.status === 500) { + + } else { + + } + ////console.log("item_banks"); + ////console.log(response); + this.setState({ + Contentdata: response.data, + items_count: response.data.items_count, + }) + }).catch((error) => { + + }); + } + paginationonChange = (pageNumber) => { this.setState({ page: pageNumber, @@ -574,11 +605,11 @@ class Question extends Component { page: this.state.page, per_page:10, }; - this.getdata(data); + this.getdatasy(data); this.getbasket_listdata(); - this.setState({ - visible:true - }) + // this.setState({ + // visible:true + // }) } }).catch((error) => { //console.log(error); @@ -689,6 +720,10 @@ class Question extends Component { }; this.getdata(data); } + + + + render() { let { page, per_page, items_count, Headertop, visible, placement, modalsType, modalsTypes,basket_list, @@ -701,8 +736,11 @@ class Question extends Component { + program_questions_count + single_questions_count + subjective_questions_count; + + + return ( -
+
{ visible===true? this.showDrawer()} - Headertop={Headertop}/> + Headertop={Headertop} + + /> {/*顶部*/} @@ -781,6 +822,7 @@ class Question extends Component { /> {/*头部*/} this.getitem_basketss(id)} selectallquestionsonthispage={()=>this.selectallquestionsonthispage()} getitem_baskets={(e)=>this.getitem_baskets(e)} @@ -957,12 +999,3 @@ class Question extends Component { } export default SnackbarHOC()(TPMIndexHOC(Question)); -{/* this.onClose()}*/} -{/* visible={visible}*/} -{/* mask={false}*/} -{/* closable={true}*/} -{/*>*/} diff --git a/public/react/src/modules/question/animation/parabola.js b/public/react/src/modules/question/animation/parabola.js new file mode 100644 index 000000000..439babd9d --- /dev/null +++ b/public/react/src/modules/question/animation/parabola.js @@ -0,0 +1,51 @@ +/** + * 抛物线动画函数 + * @param ballWrapper 小球的父容器 + * @param origin 动画起点DOM + * @param target 动画目标DOM + * @param time 持续时间 + * @param a 抛物线参数 + * @param offset 动画尺寸 + * @param callback 回调 + */ + +export function parabola(config) { + const { + ballWrapper, + origin, + target, + time = 1000, + a = 0.004, + callback, + finish, + offset = 0 + } = + config || {}; + const ballWrapperDimension = ballWrapper.getBoundingClientRect(); + const originDimension = origin.getBoundingClientRect(); + const targetDimension = target.getBoundingClientRect(); + const x1 = originDimension.left + 0.5 * originDimension.width; + const y1 = originDimension.top + 0.5 * originDimension.height; + const x2 = targetDimension.left + 0.5 * targetDimension.width; + const y2 = targetDimension.top + 0.5 * targetDimension.height; + const diffx = x2 - x1; + const diffy = y2 - y1; + const speedx = diffx / time; + const b = (diffy - a * diffx * diffx) / diffx; + + const refPoint_x = x1 - ballWrapperDimension.left - 0.5 * offset; + const refPoint_y = y1 - ballWrapperDimension.top - 0.5 * offset; + + const start = Date.now(); + const timer = setInterval(() => { + if (Date.now() - start > time) { + finish(); + clearInterval(timer); + return; + } + + const x = speedx * (Date.now() - start); + const y = a * x * x + b * x; + callback && callback(refPoint_x + x, refPoint_y + y); + }, 15); +} diff --git a/public/react/src/modules/question/component/SiderBars.js b/public/react/src/modules/question/component/SiderBars.js index ae5d16136..66ccb77dc 100644 --- a/public/react/src/modules/question/component/SiderBars.js +++ b/public/react/src/modules/question/component/SiderBars.js @@ -93,10 +93,10 @@ class SiderBars extends Component { // console.log(this.props); var mypath= this.props&&this.props.match&&this.props.match.path; - let{myvisible}=this.props; + let{myvisible,Datacount,animateStyle}=this.props; return ( -
+
0?"-task-sidebar mystask-sidebars":"-task-sidebar mystask-sidebarss"} > {this.props.mygetHelmetapi&&this.props.mygetHelmetapi.main_site===true?
@@ -104,10 +104,15 @@ class SiderBars extends Component { mypath&&mypath==="/question"? -
this.props.showDrawer()} > -
- 132 -
+
this.props.showDrawer()} > + + { + Datacount&&Datacount>0? +
+ {Datacount} +
+ :"" + } diff --git a/public/react/src/modules/question/questioncss/questioncom.css b/public/react/src/modules/question/questioncss/questioncom.css index 8db839b31..b6c068a50 100644 --- a/public/react/src/modules/question/questioncss/questioncom.css +++ b/public/react/src/modules/question/questioncss/questioncom.css @@ -890,5 +890,27 @@ position: absolute !important; font-size:11px !important; color:#ffffff !important; - line-height:14px !important; + line-height:20px !important; + top: -14px !important; + right: -14px !important; +} + + +.maxnamewidth30{ + max-width: 30px; + overflow:hidden; + text-overflow:ellipsis; + white-space:nowrap; + cursor: default; +} +.ball { + width: 8px; + height: 8px; + background: #FF6601; + position: absolute; + left: 0; + top: 0; + border-radius: 50%; + opacity: 0; + z-index: 1; } diff --git a/public/react/src/modules/tpm/TPMIndex.css b/public/react/src/modules/tpm/TPMIndex.css index d5b8ef5c2..4f19260aa 100644 --- a/public/react/src/modules/tpm/TPMIndex.css +++ b/public/react/src/modules/tpm/TPMIndex.css @@ -268,8 +268,32 @@ body>.-task-title { background: #EEEEEE; } .mystask-sidebar{ - right: 210px !important; + right: 220px !important; } .mystask-sidebars{ - right: 10px !important; + right: 20px !important; +} +.shitikussmys{ + width:29px !important; + height:20px!important; + background:#FF6601 !important; + border-radius:10px !important; + position: absolute !important; + font-size:11px !important; + color:#ffffff !important; + line-height:20px !important; + top: -13px !important; + right: -10px !important; +} + + +.maxnamewidth30{ + max-width: 30px; + overflow:hidden; + text-overflow:ellipsis; + white-space:nowrap; + cursor: default; +} +.mystask-sidebarss{ + right: 5px !important; } From db82ed009b17feb778d809ef881431715d1ee034 Mon Sep 17 00:00:00 2001 From: daiao <358551898@qq.com> Date: Tue, 7 Jan 2020 10:42:56 +0800 Subject: [PATCH 006/156] base64 --- app/controllers/concerns/git_helper.rb | 6 ++++++ app/controllers/shixuns_controller.rb | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/controllers/concerns/git_helper.rb b/app/controllers/concerns/git_helper.rb index 7c031f24c..d8479d458 100644 --- a/app/controllers/concerns/git_helper.rb +++ b/app/controllers/concerns/git_helper.rb @@ -46,6 +46,12 @@ module GitHelper content: content, author_name: username, author_email: mail) end + def update_file_base64_content(content, repo_path, path, mail, username, message) + content = Base64.encode64(content) + GitService.update_file_base64(repo_path: repo_path, file_path: path, message: message, + content: content, author_name: username, author_email: mail) + end + # 添加目录 def git_add_folder(folder_path, author_name, author_email, message) GitService.add_tree(file_path: folder_path, message: message, author_name: author_name, author_email: author_email) diff --git a/app/controllers/shixuns_controller.rb b/app/controllers/shixuns_controller.rb index 35aee9ffa..de69bf033 100644 --- a/app/controllers/shixuns_controller.rb +++ b/app/controllers/shixuns_controller.rb @@ -896,7 +896,7 @@ class ShixunsController < ApplicationController author_email = current_user.git_mail message = params[:message] || "upload file by browser" uid_logger("-----author_email: #{author_email}") - update_file_content(content, @repo_path, @path, author_email, author_name, message) + update_file_base64_content(content, @repo_path, @path, author_email, author_name, message) render_ok end From 742f7cc3a9573c1983cb160d9d69c23adb041626 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Tue, 7 Jan 2020 13:40:58 +0800 Subject: [PATCH 007/156] =?UTF-8?q?=E9=A2=98=E5=BA=93=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../react/src/modules/question/Paperreview.js | 2 +- .../src/modules/question/Paperreview_item.js | 16 +-- public/react/src/modules/question/Question.js | 104 ++++++++++++++---- .../modules/question/Questionitem_banks.js | 12 +- .../modules/question/component/Contentpart.js | 10 +- .../question/component/Contentquestionbank.js | 9 +- .../question/component/Itembankstop.js | 2 +- .../modules/question/component/Listjihe.js | 12 +- .../modules/question/component/NoneData.js | 2 +- .../comthetestpaper/Comthetestpaperst.js | 2 +- .../question/questioncss/questioncom.css | 12 +- .../modules/testpaper/Paperlibraryeditid.js | 2 +- .../src/modules/testpaper/Testpaperlibrary.js | 4 +- .../testpaper/component/Contentpart.js | 2 +- .../modules/testpaper/component/Listjihe.js | 4 +- .../component/Paperlibraryseeid_item.js | 12 +- .../component/Paperlibraryseeid_itemss.js | 16 +-- .../testpaper/testioncss/testioncss.css | 10 +- 18 files changed, 158 insertions(+), 75 deletions(-) diff --git a/public/react/src/modules/question/Paperreview.js b/public/react/src/modules/question/Paperreview.js index 47593ea2d..9014ba92b 100644 --- a/public/react/src/modules/question/Paperreview.js +++ b/public/react/src/modules/question/Paperreview.js @@ -214,7 +214,7 @@ class Paperreview extends Component { axios.post(url, data) .then((result) => { if (result.data.status === 0) { - this.props.showNotification(`组卷成功`); + // this.props.showNotification(`组卷成功`); this.props.history.replace('/paperlibrary'); } }).catch((error) => { diff --git a/public/react/src/modules/question/Paperreview_item.js b/public/react/src/modules/question/Paperreview_item.js index 562da69c1..cbd2f19fa 100644 --- a/public/react/src/modules/question/Paperreview_item.js +++ b/public/react/src/modules/question/Paperreview_item.js @@ -91,7 +91,7 @@ class Paperreview_item extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`拖动成功`); + // this.props.showNotification(`拖动成功`); this.props.getdata({}); } }).catch((error) => { @@ -110,7 +110,7 @@ class Paperreview_item extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`拖动成功`); + // this.props.showNotification(`拖动成功`); this.props.getdata({}); } }).catch((error) => { @@ -131,7 +131,7 @@ class Paperreview_item extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`拖动成功`); + // this.props.showNotification(`拖动成功`); this.props.getdata({}); } }).catch((error) => { @@ -151,7 +151,7 @@ class Paperreview_item extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`拖动成功`); + // this.props.showNotification(`拖动成功`); this.props.getdata({}); } }).catch((error) => { @@ -185,7 +185,7 @@ class Paperreview_item extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`调分成功`); + // this.props.showNotification(`调分成功`); this.props.getdata({}); this.Singlemagazine("", false); } @@ -202,7 +202,7 @@ class Paperreview_item extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`调分成功`); + // this.props.showNotification(`调分成功`); this.props.getdata({}); this.Singlemagazines(false); } @@ -247,7 +247,7 @@ class Paperreview_item extends Component { }) .then((response) => { if (response.data.status == 0) { - this.props.showNotification('大题删除成功'); + // this.props.showNotification('大题删除成功'); this.props.getdata({}); this.setState({ titilesms: "" @@ -275,7 +275,7 @@ class Paperreview_item extends Component { axios.delete((url)) .then((response) => { if (response.data.status == 0) { - this.props.showNotification('试题删除成功'); + // this.props.showNotification('试题删除成功'); this.props.getdata({}); } }) diff --git a/public/react/src/modules/question/Question.js b/public/react/src/modules/question/Question.js index 44d42ac6c..8120b1860 100644 --- a/public/react/src/modules/question/Question.js +++ b/public/react/src/modules/question/Question.js @@ -65,6 +65,7 @@ class Question extends Component { selectallquestionsonthispages:false, oj_status:null, isVisible: false, + selectionbools:false, } } @@ -213,6 +214,7 @@ class Question extends Component { const url = `/item_banks.json`; this.setState({ booljupyterurls:true, + selectionbools:false, }) axios.get((url), {params: data}).then((response) => { setTimeout(()=>{ @@ -235,6 +237,7 @@ class Question extends Component { Contentdata: response.data, items_count: response.data.items_count, }) + this.getdataslen(response.data.items); }).catch((error) => { ////console.log(error) this.setState({ @@ -246,7 +249,9 @@ class Question extends Component { //不刷新加载 getdatasy = (data) => { const url = `/item_banks.json`; - + this.setState({ + selectionbools:false, + }) axios.get((url), {params: data}).then((response) => { setTimeout(()=>{ @@ -265,12 +270,57 @@ class Question extends Component { this.setState({ Contentdata: response.data, items_count: response.data.items_count, + }) + + this.getdataslen(response.data.items); }).catch((error) => { }); } + //计算 + getdataslen=(arr)=>{ + var contes=0; + for(let data of arr) { + if(data.item_type==="PROGRAM"){ + //编程题 + if(data.choosed===true){ + + }else{ + //未选用 + if(data.program_attr.status===1){ + //已发布 + contes=contes+1; + } + + } + + }else{ + //不是编程题 + if(data.choosed===true){ + + }else{ + //未选用 + contes=contes+1; + } + } + + } + + if(contes>0){ + this.setState({ + selectionbools:false, + selectallquestionsonthispages:false, + }) + }else { + this.setState({ + selectionbools:true, + selectallquestionsonthispages:true, + }) + } + } + paginationonChange = (pageNumber) => { this.setState({ page: pageNumber, @@ -466,19 +516,6 @@ class Question extends Component { this.setState({ keywords: e.target.value }) - // var data = { - // discipline_id:this.state.discipline_id, - // sub_discipline_id:this.state.sub_discipline_id, - // tag_discipline_id:this.state.tag_discipline_id, - // public: this.state.defaultActiveKey, - // difficulty: this.state.difficulty, - // item_type: this.state.item_type, - // keywords: e.target.value, - // page: this.state.page, - // per_page:10, - // }; - // - // this.getdata(data); } setdatafuns = (value) => { @@ -507,7 +544,7 @@ class Question extends Component { axios.delete(url) .then((response) => { if (response.data.status == 0) { - this.props.showNotification('删除试题成功') + // this.props.showNotification('删除试题成功') // props.history.push(response.data.right_url) var data = { discipline_id:this.state.discipline_id, @@ -533,7 +570,7 @@ class Question extends Component { axios.post(url) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`公开题目成功`); + // this.props.showNotification(`公开题目成功`); var data = { discipline_id:this.state.discipline_id, sub_discipline_id:this.state.sub_discipline_id, @@ -593,7 +630,7 @@ class Question extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`选用成功`); + // this.props.showNotification(`选用成功`); var data = { discipline_id:this.state.discipline_id, sub_discipline_id:this.state.sub_discipline_id, @@ -623,7 +660,7 @@ class Question extends Component { axios.delete(url) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`撤销成功`); + // this.props.showNotification(`撤销成功`); var data = { discipline_id:this.state.discipline_id, sub_discipline_id:this.state.sub_discipline_id, @@ -635,7 +672,7 @@ class Question extends Component { page: this.state.page, per_page:10, }; - this.getdata(data); + this.getdatasy(data); this.getbasket_listdata(); } }).catch((error) => { @@ -648,7 +685,29 @@ class Question extends Component { var arr= this.state.Contentdata.items; for(let data of arr) { - item_idsdata.push(data.id); + if(data.item_type==="PROGRAM"){ + //编程题 + if(data.choosed===true){ + + }else{ + //未选用 + if(data.program_attr.status===1){ + //已发布 + item_idsdata.push(data.id); + } + + } + + }else{ + //不是编程题 + if(data.choosed===true){ + + }else{ + //未选用 + item_idsdata.push(data.id); + } + } + } const data={ item_ids:item_idsdata @@ -669,7 +728,7 @@ class Question extends Component { }}) .then((response) => { if (response.data.status == 0) { - this.props.showNotification('删除成功'); + // this.props.showNotification('删除成功'); var data = { discipline_id:this.state.discipline_id, sub_discipline_id:this.state.sub_discipline_id, @@ -728,7 +787,7 @@ class Question extends Component { let { page, per_page, items_count, Headertop, visible, placement, modalsType, modalsTypes,basket_list, completion_questions_count, judgement_questions_count, multiple_questions_count, practical_questions_count, - program_questions_count, single_questions_count, subjective_questions_count + program_questions_count, single_questions_count, subjective_questions_count,selectionbools } = this.state; const Datacount = completion_questions_count + judgement_questions_count @@ -812,6 +871,7 @@ class Question extends Component { this.setdifficulty(e)} diff --git a/public/react/src/modules/question/Questionitem_banks.js b/public/react/src/modules/question/Questionitem_banks.js index 097528656..129e29d69 100644 --- a/public/react/src/modules/question/Questionitem_banks.js +++ b/public/react/src/modules/question/Questionitem_banks.js @@ -282,7 +282,7 @@ class Questionitem_banks extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`新增单选题成功`); + // this.props.showNotification(`新增单选题成功`); this.props.history.replace('/question'); } @@ -293,7 +293,7 @@ class Questionitem_banks extends Component { axios.put(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`编辑单选题成功`); + // this.props.showNotification(`编辑单选题成功`); this.props.history.replace('/question'); @@ -360,7 +360,7 @@ class Questionitem_banks extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`新增多选题成功`); + // this.props.showNotification(`新增多选题成功`); this.props.history.replace('/question'); @@ -373,7 +373,7 @@ class Questionitem_banks extends Component { axios.put(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`编辑多选题成功`); + // this.props.showNotification(`编辑多选题成功`); this.props.history.replace('/question'); @@ -427,7 +427,7 @@ class Questionitem_banks extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`新增判断题成功`); + // this.props.showNotification(`新增判断题成功`); this.props.history.replace('/question'); } @@ -439,7 +439,7 @@ class Questionitem_banks extends Component { axios.put(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`编辑判断题成功`); + // this.props.showNotification(`编辑判断题成功`); this.props.history.replace('/question'); } diff --git a/public/react/src/modules/question/component/Contentpart.js b/public/react/src/modules/question/component/Contentpart.js index 60960585f..6cca91f93 100644 --- a/public/react/src/modules/question/component/Contentpart.js +++ b/public/react/src/modules/question/component/Contentpart.js @@ -49,7 +49,7 @@ class Contentpart extends Component { render() { let {page}=this.state; - let {defaultActiveKey}=this.props; + let {defaultActiveKey,item_type,booljupyterurls}=this.props; const content = (
+
trigger.parentNode} placement="bottom" trigger="hover" content={contents} onVisibleChange={()=>this.props.handleVisibleChange(true)}>
@@ -169,7 +169,7 @@ class Contentpart extends Component {
: - "" + "":"" } @@ -203,7 +203,7 @@ class Contentpart extends Component { :
{ - defaultActiveKey===1||defaultActiveKey==="1"? + defaultActiveKey===1||defaultActiveKey==="1"? this.props.selectallquestionsonthispage()} > :"" } diff --git a/public/react/src/modules/question/component/Contentquestionbank.js b/public/react/src/modules/question/component/Contentquestionbank.js index 4f7441956..8ec8cf955 100644 --- a/public/react/src/modules/question/component/Contentquestionbank.js +++ b/public/react/src/modules/question/component/Contentquestionbank.js @@ -40,6 +40,7 @@ class Contentquestionbank extends Component { render() { let {page}=this.state; + let {selectionbools}=this.props; return ( @@ -47,7 +48,13 @@ class Contentquestionbank extends Component {
- this.props.selectallquestionsonthispage()}> + { + selectionbools===true? + this.props.selectallquestionsonthispage()} disabled> + : + this.props.selectallquestionsonthispage()}> + + }

选用本页全部试题

diff --git a/public/react/src/modules/question/component/Itembankstop.js b/public/react/src/modules/question/component/Itembankstop.js index 8ff1307b8..46668c979 100644 --- a/public/react/src/modules/question/component/Itembankstop.js +++ b/public/react/src/modules/question/component/Itembankstop.js @@ -443,7 +443,7 @@ class Itembankstop extends Component { axios.post(url,data) .then((result) => { if (result.data.status === 0) { - this.props.showNotification(`新增知识点成功!`); + // this.props.showNotification(`新增知识点成功!`); var leydata={ id: result.data.tag_discipline_id, name:value, diff --git a/public/react/src/modules/question/component/Listjihe.js b/public/react/src/modules/question/component/Listjihe.js index 3c24c6a6b..64559596b 100644 --- a/public/react/src/modules/question/component/Listjihe.js +++ b/public/react/src/modules/question/component/Listjihe.js @@ -167,18 +167,18 @@ class Listjihe extends Component { items.item_type==="PROGRAM"? items.program_attr.status===0?

- - 选用 + + 选用

:

this.Selectingpracticaltraining(items.id)}> - - 选用 + + 选用

:

this.Selectingpracticaltraining(items.id)}> - - 选用 + + 选用

} { diff --git a/public/react/src/modules/question/component/NoneData.js b/public/react/src/modules/question/component/NoneData.js index 123b7524e..f993190d5 100644 --- a/public/react/src/modules/question/component/NoneData.js +++ b/public/react/src/modules/question/component/NoneData.js @@ -21,7 +21,7 @@ class NoneData extends Component{ margin: 40px auto 20px; } .zenwuxgsj{ - font-size:17px; + font-size:14px; font-family:MicrosoftYaHei; color:rgba(136,136,136,1); } diff --git a/public/react/src/modules/question/comthetestpaper/Comthetestpaperst.js b/public/react/src/modules/question/comthetestpaper/Comthetestpaperst.js index 53f073656..8b3010ed5 100644 --- a/public/react/src/modules/question/comthetestpaper/Comthetestpaperst.js +++ b/public/react/src/modules/question/comthetestpaper/Comthetestpaperst.js @@ -518,7 +518,7 @@ class Comthetestpaperst extends Component { axios.post(url,data) .then((result) => { if (result.data.status === 0) { - this.props.showNotification(`新增知识点成功!`); + // this.props.showNotification(`新增知识点成功!`); var leydata={ id: result.data.tag_discipline_id, name:value, diff --git a/public/react/src/modules/question/questioncss/questioncom.css b/public/react/src/modules/question/questioncss/questioncom.css index b6c068a50..4bf767b0f 100644 --- a/public/react/src/modules/question/questioncss/questioncom.css +++ b/public/react/src/modules/question/questioncss/questioncom.css @@ -372,7 +372,7 @@ .selectionss{ width:88px; height:30px; - background:#eeeeee; + background:#CCCCCC; border-radius:4px; text-align: center; line-height: 30px; @@ -399,7 +399,7 @@ padding-bottom: 20px; } .icontianjiadaohangcolor{ - color: #FFFFFF; + color: #ffffff; } .icontianjiadaohangcolors{ @@ -914,3 +914,11 @@ opacity: 0; z-index: 1; } + +.mt25{ + margin-top: 25px; +} + +.mr15{ + margin-right: 15px; +} diff --git a/public/react/src/modules/testpaper/Paperlibraryeditid.js b/public/react/src/modules/testpaper/Paperlibraryeditid.js index ba8cb6926..1497a12ec 100644 --- a/public/react/src/modules/testpaper/Paperlibraryeditid.js +++ b/public/react/src/modules/testpaper/Paperlibraryeditid.js @@ -163,7 +163,7 @@ class Paperlibraryeditid extends Component { axios.put(url, data) .then((result) => { if (result.data.status === 0) { - this.props.showNotification(`试卷更新成功`); + // this.props.showNotification(`试卷更新成功`); this.props.history.push('/paperlibrary'); } }).catch((error) => { diff --git a/public/react/src/modules/testpaper/Testpaperlibrary.js b/public/react/src/modules/testpaper/Testpaperlibrary.js index 2c23d15bf..fdd290ed8 100644 --- a/public/react/src/modules/testpaper/Testpaperlibrary.js +++ b/public/react/src/modules/testpaper/Testpaperlibrary.js @@ -290,7 +290,7 @@ class Testpaperlibrary extends Component { axios.post(url) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`公开试卷成功`); + // this.props.showNotification(`公开试卷成功`); var data = { discipline_id:this.state.discipline_id, sub_discipline_id:this.state.sub_discipline_id, @@ -315,7 +315,7 @@ class Testpaperlibrary extends Component { axios.delete(url) .then((response) => { if (response.data.status == 0) { - this.props.showNotification('删除试卷成功') + // this.props.showNotification('删除试卷成功'); // props.history.push(response.data.right_url) var data = { discipline_id:this.state.discipline_id, diff --git a/public/react/src/modules/testpaper/component/Contentpart.js b/public/react/src/modules/testpaper/component/Contentpart.js index 2ff4b92a5..e69f1b0b5 100644 --- a/public/react/src/modules/testpaper/component/Contentpart.js +++ b/public/react/src/modules/testpaper/component/Contentpart.js @@ -57,7 +57,7 @@ class Contentpart extends Component {
); return ( -
+
-
- +
+

this.gotoseesj(items.id)}>{names}

diff --git a/public/react/src/modules/testpaper/component/Paperlibraryseeid_item.js b/public/react/src/modules/testpaper/component/Paperlibraryseeid_item.js index e4615caa1..f85ab67d0 100644 --- a/public/react/src/modules/testpaper/component/Paperlibraryseeid_item.js +++ b/public/react/src/modules/testpaper/component/Paperlibraryseeid_item.js @@ -81,7 +81,7 @@ class Paperreview_item extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`拖动成功`); + // this.props.showNotification(`拖动成功`); this.props.getdata(); } }).catch((error) => { @@ -101,7 +101,7 @@ class Paperreview_item extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`拖动成功`); + // this.props.showNotification(`拖动成功`); this.props.getdata(); } }).catch((error) => { @@ -125,7 +125,7 @@ class Paperreview_item extends Component { .then((result) => { debugger if (result.data.status == 0) { - this.props.showNotification(`拖动成功`); + // this.props.showNotification(`拖动成功`); this.props.getdata(); } }).catch((error) => { @@ -147,7 +147,7 @@ class Paperreview_item extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`拖动成功`); + // this.props.showNotification(`拖动成功`); this.props.getdata(); } }).catch((error) => { @@ -181,7 +181,7 @@ class Paperreview_item extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`调分成功`); + // this.props.showNotification(`调分成功`); this.props.getdata({}); this.Singlemagazine("", false); } @@ -198,7 +198,7 @@ class Paperreview_item extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`调分成功`); + // this.props.showNotification(`调分成功`); this.props.getdata({}); this.Singlemagazines(false); } diff --git a/public/react/src/modules/testpaper/component/Paperlibraryseeid_itemss.js b/public/react/src/modules/testpaper/component/Paperlibraryseeid_itemss.js index 25f588977..066b0e4ef 100644 --- a/public/react/src/modules/testpaper/component/Paperlibraryseeid_itemss.js +++ b/public/react/src/modules/testpaper/component/Paperlibraryseeid_itemss.js @@ -89,7 +89,7 @@ class Paperlibraryseeid_itemss extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`拖动成功`); + // this.props.showNotification(`拖动成功`); this.props.getdata({}); } }).catch((error) => { @@ -108,7 +108,7 @@ class Paperlibraryseeid_itemss extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`拖动成功`); + // this.props.showNotification(`拖动成功`); this.props.getdata({}); } }).catch((error) => { @@ -129,7 +129,7 @@ class Paperlibraryseeid_itemss extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`拖动成功`); + // this.props.showNotification(`拖动成功`); this.props.getdata({}); } }).catch((error) => { @@ -149,7 +149,7 @@ class Paperlibraryseeid_itemss extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`拖动成功`); + // this.props.showNotification(`拖动成功`); this.props.getdata({}); } }).catch((error) => { @@ -184,7 +184,7 @@ class Paperlibraryseeid_itemss extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`调分成功`); + // this.props.showNotification(`调分成功`); this.props.getdata({}); this.Singlemagazine("", false); } @@ -201,7 +201,7 @@ class Paperlibraryseeid_itemss extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - this.props.showNotification(`调分成功`); + // this.props.showNotification(`调分成功`); this.props.getdata({}); this.Singlemagazines(false); } @@ -247,7 +247,7 @@ class Paperlibraryseeid_itemss extends Component { }) .then((response) => { if (response.data.status == 0) { - this.props.showNotification('大题删除成功'); + // this.props.showNotification('大题删除成功'); this.props.getdata({}); this.setState({ titilesms: "" @@ -275,7 +275,7 @@ class Paperlibraryseeid_itemss extends Component { axios.delete((url)) .then((response) => { if (response.data.status == 0) { - this.props.showNotification('试题删除成功'); + // this.props.showNotification('试题删除成功'); this.props.getdata({}); } }) diff --git a/public/react/src/modules/testpaper/testioncss/testioncss.css b/public/react/src/modules/testpaper/testioncss/testioncss.css index fa87531b0..a1de362d1 100644 --- a/public/react/src/modules/testpaper/testioncss/testioncss.css +++ b/public/react/src/modules/testpaper/testioncss/testioncss.css @@ -366,7 +366,7 @@ .selectionss{ width:88px; height:30px; - background:#eeeeee; + background:#CCCCCC; border-radius:4px; text-align: center; line-height: 30px; @@ -884,3 +884,11 @@ text-align: center; line-height: 20px; } +.mt25{ + margin-top: 25px; +} + +.imgtp{ + width: 39px; + height: 44px; +} From 893e637b99f3efdfe851b7ed648441dacafdaf38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Tue, 7 Jan 2020 14:22:56 +0800 Subject: [PATCH 008/156] =?UTF-8?q?=E9=A2=98=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modules/question/component/Listjihe.js | 171 +++++++++++------- 1 file changed, 102 insertions(+), 69 deletions(-) diff --git a/public/react/src/modules/question/component/Listjihe.js b/public/react/src/modules/question/component/Listjihe.js index 64559596b..0b1f012f5 100644 --- a/public/react/src/modules/question/component/Listjihe.js +++ b/public/react/src/modules/question/component/Listjihe.js @@ -15,6 +15,11 @@ const tagArray = [ 'J.', 'K.', 'L.', 'M.', 'N.', 'O.', 'P.', 'Q.', 'R.', 'S.', 'T.', 'U.', 'V.', 'W.', 'X.', 'Y.', 'Z.' ] +const tagArrays = [ + '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' +] class Listjihe extends Component { constructor(props) { super(props); @@ -32,10 +37,10 @@ class Listjihe extends Component { //选用 Selectingpracticaltraining=(id)=>{ - let data={ - item_ids:[id] - } - this.props.getitem_baskets(data); + let data={ + item_ids:[id] + } + this.props.getitem_baskets(data); } //撤销 Selectingpracticaltrainings=(id)=>{ @@ -57,18 +62,36 @@ class Listjihe extends Component { if(items){ if(items.item_type){ if(items.item_type==="PROGRAM"){ + }else{ - if(items.choices){ - if(items.choices.length>0){ - - var arr= items.choices; - for(let data of arr) { - if(data.is_answer===true){ - rightkey=data.choice_text; - break; + if(items.item_type==="JUDGMENT") { + + + if(items.choices){ + if(items.choices.length>0){ + var arr= items.choices; + for(let data of arr) { + if(data.is_answer===true){ + rightkey=data.choice_text; + break; + } } } } + }else { + if (items.choices) { + if (items.choices.length > 0) { + var arr = items.choices; + for (var i = 0; i < arr.length; i++) { + if (arr[i].is_answer === true) { + rightkey = i; + break; + } + } + } + } + + } } } @@ -94,38 +117,38 @@ class Listjihe extends Component { {/*内容*/}
{items.item_type==="JUDGMENT"? -

- { - items === undefined ||items === null? "" : items.choices.map((object, index) => { - return ( -

- - {object.choice_text} - -

- ) - }) - } -

: +

+ { + items === undefined ||items === null? "" : items.choices.map((object, index) => { + return ( +

+ + {object.choice_text} + +

+ ) + }) + } +

: items.item_type==="PROGRAM"?

-

-

+

+

+

+

+ : +

+ { + items === undefined ||items === null? "" : items.choices.map((object, index) => { + return ( +

+ {tagArray[index]} +

+ ) + }) + }

- : -

- { - items === undefined ||items === null? "" : items.choices.map((object, index) => { - return ( -

- {tagArray[index]} -

-

- ) - }) - } -

}
@@ -137,18 +160,18 @@ class Listjihe extends Component { {/*更新时间*/}
-

更新时间:{items.update_time}

+

更新时间:{items.update_time}

{ this.props.defaultActiveKey==="0"||this.props.defaultActiveKey===0? "" :

创建者:{items.author.name}

} - { - items.item_type==="PROGRAM"? -

编程语言:{items.program_attr.language}

- :"" - } + { + items.item_type==="PROGRAM"? +

编程语言:{items.program_attr.language}

+ :"" + } { items.item_type==="PROGRAM"? items.program_attr.status===0? @@ -164,22 +187,22 @@ class Listjihe extends Component { 撤销

: - items.item_type==="PROGRAM"? - items.program_attr.status===0? -

- - 选用 -

- : -

this.Selectingpracticaltraining(items.id)}> + items.item_type==="PROGRAM"? + items.program_attr.status===0? +

选用

: -

this.Selectingpracticaltraining(items.id)}> - - 选用 -

+

this.Selectingpracticaltraining(items.id)}> + + 选用 +

+ : +

this.Selectingpracticaltraining(items.id)}> + + 选用 +

} { defaultActiveKey===0||defaultActiveKey==="0"? @@ -210,17 +233,17 @@ class Listjihe extends Component { items.program_attr.status===0? "" : +

this.props.showmodels(items.id)}> + + 公开 +

+ :

this.props.showmodels(items.id)}> 公开

- : -

this.props.showmodels(items.id)}> - - 公开 -

: - "" + "" }
@@ -228,7 +251,7 @@ class Listjihe extends Component { } { items.item_type==="PROGRAM"? - "" + "" :

this.props.chakanjiexibool(keindex)}> @@ -245,10 +268,20 @@ class Listjihe extends Component {

-

-

+ + { + items.item_type==="SINGLE" || items.item_type==="MULTIPLE"? +

+

+ : +

+

+ } +
{ items&&items.analysis? From 8a82882a4aeecbdf246bcafa9310cfae957e72a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Tue, 7 Jan 2020 14:28:11 +0800 Subject: [PATCH 009/156] =?UTF-8?q?=E9=A2=98=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../react/src/modules/question/component/Itembankstop.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/public/react/src/modules/question/component/Itembankstop.js b/public/react/src/modules/question/component/Itembankstop.js index 46668c979..36dff4fc0 100644 --- a/public/react/src/modules/question/component/Itembankstop.js +++ b/public/react/src/modules/question/component/Itembankstop.js @@ -495,7 +495,7 @@ class Itembankstop extends Component { height: 33px !important; } .ant-input-group{ - width:258px !important; + width:270px !important; } .ant-input { height: 33px !important; @@ -530,7 +530,7 @@ class Itembankstop extends Component { )(
- @@ -544,7 +544,7 @@ class Itembankstop extends Component { )(
- From 8776449234ce9c2f9f323109e55206f0a366ac04 Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Tue, 7 Jan 2020 15:41:46 +0800 Subject: [PATCH 010/156] =?UTF-8?q?=E9=A2=98=E5=BA=93=E9=80=89=E9=A1=B9?= =?UTF-8?q?=E5=AD=97=E7=AC=A6=E6=8E=A7=E5=88=B6=E5=9C=A8300=E4=BB=A5?= =?UTF-8?q?=E5=86=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/forms/item_banks/save_item_form.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/forms/item_banks/save_item_form.rb b/app/forms/item_banks/save_item_form.rb index 2bfd99fc3..7e788067e 100644 --- a/app/forms/item_banks/save_item_form.rb +++ b/app/forms/item_banks/save_item_form.rb @@ -27,7 +27,7 @@ class ItemBanks::SaveItemForm attr_accessor :choice_text, :is_answer - validates :choice_text, presence: true, length: { maximum: 100 } + validates :choice_text, presence: true, length: { maximum: 300 } validates :is_answer, presence: true, inclusion: {in: 0..1}, numericality: { only_integer: true } end end \ No newline at end of file From 5e0907195544c004751a57dd1adc9ae7f94186dc Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Tue, 7 Jan 2020 15:52:25 +0800 Subject: [PATCH 011/156] =?UTF-8?q?=E8=AF=95=E5=8D=B7=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E6=97=B6=E6=92=A4=E9=94=80=E9=80=89=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/examination_banks_controller.rb | 11 ++++++++++- app/controllers/item_banks_controller.rb | 3 ++- config/routes.rb | 1 + 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/app/controllers/examination_banks_controller.rb b/app/controllers/examination_banks_controller.rb index ef545e06e..9ffbd6630 100644 --- a/app/controllers/examination_banks_controller.rb +++ b/app/controllers/examination_banks_controller.rb @@ -2,7 +2,7 @@ class ExaminationBanksController < ApplicationController include PaginateHelper before_action :require_login before_action :find_exam, except: [:index, :create] - before_action :edit_auth, only: [:update, :destroy, :set_public] + before_action :edit_auth, only: [:update, :destroy, :set_public, :revoke_item] def index exams = ExaminationBankQuery.call(params) @@ -62,6 +62,15 @@ class ExaminationBanksController < ApplicationController render_ok end + def revoke_item + item = @exam.examination_items.find_by!(item_bank_id: params[:item_id]) + ActiveRecord::Base.transaction do + @exam.examination_items.where(item_type: item.item_type).where("position > #{item.position}").update_all("position = position -1") + item.destroy! + end + render_ok + end + private def form_params diff --git a/app/controllers/item_banks_controller.rb b/app/controllers/item_banks_controller.rb index 8b77e3e9a..24d9c44a9 100644 --- a/app/controllers/item_banks_controller.rb +++ b/app/controllers/item_banks_controller.rb @@ -8,7 +8,8 @@ class ItemBanksController < ApplicationController items = ItemBankQuery.call(params) @items_count = items.size @items = paginate items.includes(:item_analysis, :user, :container) - @item_basket_ids = current_user.item_baskets.pluck(:item_bank_id) + exam = ExaminationBank.find_by(id: params[:exam_id]) if params[:exam_id].present? + @item_basket_ids = exam ? exam.examination_items.pluck(:item_bank_id) : current_user.item_baskets.pluck(:item_bank_id) end def create diff --git a/config/routes.rb b/config/routes.rb index a65a7f4c1..065d12099 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -80,6 +80,7 @@ Rails.application.routes.draw do resources :examination_banks do member do post :set_public + delete :revoke_item end end From 25a22d24a531442978017d36d78e89d66f17f00b Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Tue, 7 Jan 2020 16:12:39 +0800 Subject: [PATCH 012/156] =?UTF-8?q?=E5=88=9B=E5=BB=BA=E7=9F=A5=E8=AF=86?= =?UTF-8?q?=E7=82=B9=E7=9A=84check?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/tag_disciplines_controller.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/controllers/tag_disciplines_controller.rb b/app/controllers/tag_disciplines_controller.rb index 2650f51eb..afc2dfa19 100644 --- a/app/controllers/tag_disciplines_controller.rb +++ b/app/controllers/tag_disciplines_controller.rb @@ -2,7 +2,10 @@ class TagDisciplinesController < ApplicationController before_action :require_login def create + render_error("请输入知识点") if params[:name].blank? + render_error("输入字符长度限制在15个以内") if params[:name].length > 15 sub_discipline = SubDiscipline.find_by!(id: params[:sub_discipline_id]) + render_error("重复的知识点") if sub_discipline.tag_disciplines.exists?(name: params[:name].to_s.strip) tag_discipline = TagDiscipline.create!(name: params[:name].to_s.strip, sub_discipline: sub_discipline, user_id: current_user.id) render_ok({tag_discipline_id: tag_discipline.id}) end From db6062b0c4286f0a547d68878fbacad53d89865c Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Tue, 7 Jan 2020 16:14:15 +0800 Subject: [PATCH 013/156] =?UTF-8?q?=E5=88=9B=E5=BB=BA=E7=9F=A5=E8=AF=86?= =?UTF-8?q?=E7=82=B9=E7=9A=84check?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/tag_disciplines_controller.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/tag_disciplines_controller.rb b/app/controllers/tag_disciplines_controller.rb index afc2dfa19..c978762ad 100644 --- a/app/controllers/tag_disciplines_controller.rb +++ b/app/controllers/tag_disciplines_controller.rb @@ -2,10 +2,10 @@ class TagDisciplinesController < ApplicationController before_action :require_login def create - render_error("请输入知识点") if params[:name].blank? - render_error("输入字符长度限制在15个以内") if params[:name].length > 15 + tip_exception("请输入知识点") if params[:name].blank? + tip_exception("输入字符长度限制在15个以内") if params[:name].length > 15 sub_discipline = SubDiscipline.find_by!(id: params[:sub_discipline_id]) - render_error("重复的知识点") if sub_discipline.tag_disciplines.exists?(name: params[:name].to_s.strip) + tip_exception("重复的知识点") if sub_discipline.tag_disciplines.exists?(name: params[:name].to_s.strip) tag_discipline = TagDiscipline.create!(name: params[:name].to_s.strip, sub_discipline: sub_discipline, user_id: current_user.id) render_ok({tag_discipline_id: tag_discipline.id}) end From a15a2f51c7064c9f3ef582c515f0b5b11aee4d46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Tue, 7 Jan 2020 16:41:44 +0800 Subject: [PATCH 014/156] =?UTF-8?q?=E9=A2=98=E5=BA=93=20=E7=BB=A7=E7=BB=AD?= =?UTF-8?q?=E9=80=89=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/modules/question/NewMyShixunModel.js | 919 ++++++++++++++++++ .../modules/question/component/Contentpart.js | 2 +- .../modules/question/component/Listjihe.js | 19 +- .../question/questioncss/questioncom.css | 14 + .../modules/testpaper/Paperlibraryeditid.js | 45 +- .../testpaper/component/Seeoagertits.js | 2 +- public/react/src/modules/tpm/NewHeader.js | 22 +- 7 files changed, 997 insertions(+), 26 deletions(-) create mode 100644 public/react/src/modules/question/NewMyShixunModel.js diff --git a/public/react/src/modules/question/NewMyShixunModel.js b/public/react/src/modules/question/NewMyShixunModel.js new file mode 100644 index 000000000..e8acf2202 --- /dev/null +++ b/public/react/src/modules/question/NewMyShixunModel.js @@ -0,0 +1,919 @@ +import React, {Component} from "react"; +import {Link, NavLink} from 'react-router-dom'; +import {WordsBtn, ActionBtn, SnackbarHOC, getImageUrl} from 'educoder'; +import axios from 'axios'; +import { + notification, + Spin, + Table, + Pagination, + Drawer, + Input, + Tooltip +} from "antd"; +import {parabola} from './animation/parabola' +import Headplugselections from "./component/Headplugselections"; +import QuestionModal from "./component/QuestionModal"; +import QuestionModals from "./component/QuestionModals"; +import Contentpart from "./component/Contentpart"; +import {TPMIndexHOC} from "../tpm/TPMIndexHOC"; +import NoneData from './component/NoneData'; +import './questioncss/questioncom.css'; +import Bottomsubmit from "../modals/Bottomsubmit"; + +//exam_id 试卷的id +class NewMyShixunModel extends Component { + constructor(props) { + super(props); + this.state = { + count: 50, + defaultActiveKey:"0", + Headertop: "", + Footerdown: "", + visible: false, + placement: 'right', + modalsType: false, + modalsTypes:false, + titilesm: "设为公开后,所有成员均可使用试题", + titiless: "是否设置为公开?", + titilesms:"单选题", + titbool: false, + Contentdata: [], + difficulty: null, + visiblemys: false, + visiblemyss: false, + item_type: null, + keyword: null, + timuid: null, + items_count: 0, + basket_list: [], + completion_questions_count: 0, + judgement_questions_count: 0, + multiple_questions_count: 0, + practical_questions_count: 0, + program_questions_count: 0, + single_questions_count: 0, + subjective_questions_count: 0, + page:1, + per_page:10, + disciplinesdata:[], + discipline_id:null, + sub_discipline_id:null, + tag_discipline_id:null, + booljupyterurls:false, + disciplinesdatakc:0, + disciplinesdatazsd:0, + selectallquestionsonthispages:false, + oj_status:null, + isVisible: false, + selectionbools:false, + } + + } + setdiscipline_id=(discipline_id)=>{ + this.setState({ + discipline_id:discipline_id, + sub_discipline_id:null, + tag_discipline_id:null, + keywords:"", + page:1, + per_page:10, + oj_status:null + }) + var data = { + discipline_id:discipline_id, + sub_discipline_id:null, + tag_discipline_id:null, + public: this.state.defaultActiveKey, + difficulty: this.state.difficulty, + item_type: this.state.item_type, + keywords: null, + page: this.state.page, + per_page:10, + oj_status:null, + exam_id:this.props.exam_id + }; + this.getdata(data); + + } + + setsub_discipline_id=(sub_discipline_id)=>{ + this.setState({ + sub_discipline_id:sub_discipline_id, + tag_discipline_id:null, + keywords:"", + page:1, + per_page:10, + oj_status:null + }) + var data = { + discipline_id:this.state.discipline_id, + sub_discipline_id:sub_discipline_id, + tag_discipline_id:null, + public: this.state.defaultActiveKey, + difficulty: this.state.difficulty, + item_type: this.state.item_type, + keywords:null, + page: 1, + per_page:10, + oj_status:null, + exam_id:this.props.exam_id + }; + this.getdata(data); + } + + settag_discipline_id=(tag_discipline_id)=>{ + this.setState({ + tag_discipline_id:tag_discipline_id, + keywords:"", + page:1, + per_page:10, + oj_status:null + }) + var data = { + discipline_id:this.state.discipline_id, + sub_discipline_id:this.state.sub_discipline_id, + tag_discipline_id:tag_discipline_id, + public: this.state.defaultActiveKey, + difficulty: this.state.difficulty, + item_type: this.state.item_type, + keywords: null, + page: 1, + per_page:10, + oj_status:null, + exam_id:this.props.exam_id + }; + this.getdata(data); + } + + //初始化 + componentDidMount() { + let {defaultActiveKey} = this.state; + var data = { + discipline_id:this.state.discipline_id, + sub_discipline_id:this.state.sub_discipline_id, + tag_discipline_id:this.state.tag_discipline_id, + public: defaultActiveKey, + page:1, + per_page:10, + exam_id:this.props.exam_id + }; + this.getdata(data); + + let url = `/users/get_navigation_info.json`; + axios.get(url, {}).then((response) => { + // ////console.log("开始请求/get_navigation_info.json"); + // ////console.log(response); + if (response != undefined) { + if (response.status === 200) { + this.setState({ + Headertop: response.data.top, + Footerdown: response.data.down + }) + } + } + }); + + this.getbasket_listdata(); + + //获取题库筛选资料 + let urls = `/disciplines.json`; + axios.get(urls, {params: { + source:"question" + }}).then((response) => { + console.log("Questiondisciplines"); + console.log(response.data); + if (response) { + this.setState({ + disciplinesdata: response.data.disciplines, + }) + } + }); + } + //公共和我的 + callback = (key) => { + this.setState({ + defaultActiveKey: key, + selectallquestionsonthispages:false, + difficulty:null, + page:1, + oj_status:null + }) + var data = { + discipline_id:this.state.discipline_id, + sub_discipline_id:this.state.sub_discipline_id, + tag_discipline_id:this.state.tag_discipline_id, + public: key, + item_type: this.state.item_type, + difficulty: null, + page: 1, + per_page:10, + oj_status:null, + exam_id:this.props.exam_id + }; + this.getdata(data); + + } + + //刷新加载 + getdata = (data) => { + const url = `/item_banks.json`; + this.setState({ + booljupyterurls:true, + selectionbools:false, + }) + axios.get((url), {params: data}).then((response) => { + setTimeout(()=>{ + this.setState({ + booljupyterurls:false, + }) + },1000); + if (response === null || response === undefined) { + + return + } + if (response.data.status === 403 || response.data.status === 401 || response.data.status === 500) { + + } else { + + } + ////console.log("item_banks"); + ////console.log(response); + this.setState({ + Contentdata: response.data, + items_count: response.data.items_count, + }) + this.getdataslen(response.data.items); + }).catch((error) => { + ////console.log(error) + this.setState({ + booljupyterurls:false, + }) + }); + } + + //不刷新加载 + getdatasy = (data) => { + const url = `/item_banks.json`; + this.setState({ + selectionbools:false, + }) + axios.get((url), {params: data}).then((response) => { + setTimeout(()=>{ + + },1000); + if (response === null || response === undefined) { + + return + } + if (response.data.status === 403 || response.data.status === 401 || response.data.status === 500) { + + } else { + + } + ////console.log("item_banks"); + ////console.log(response); + this.setState({ + Contentdata: response.data, + items_count: response.data.items_count, + + }) + + this.getdataslen(response.data.items); + }).catch((error) => { + + }); + } + + //计算 + getdataslen=(arr)=>{ + var contes=0; + for(let data of arr) { + if(data.item_type==="PROGRAM"){ + //编程题 + if(data.choosed===true){ + + }else{ + //未选用 + if(data.program_attr.status===1){ + //已发布 + contes=contes+1; + } + + } + + }else{ + //不是编程题 + if(data.choosed===true){ + + }else{ + //未选用 + contes=contes+1; + } + } + + } + + if(contes>0){ + this.setState({ + selectionbools:false, + selectallquestionsonthispages:false, + }) + }else { + this.setState({ + selectionbools:true, + selectallquestionsonthispages:true, + }) + } + } + + paginationonChange = (pageNumber) => { + this.setState({ + page: pageNumber, + }) + var data = { + discipline_id:this.state.discipline_id, + sub_discipline_id:this.state.sub_discipline_id, + tag_discipline_id:this.state.tag_discipline_id, + public: this.state.defaultActiveKey, + difficulty: this.state.difficulty, + item_type: this.state.item_type, + keywords: this.state.keywords, + page: pageNumber, + per_page:10, + oj_status:this.state.oj_status, + exam_id:this.props.exam_id + + }; + this.getdata(data); + } + showDrawer = () => { + if(this.state.visible===true){ + this.setState({ + visible: false, + }); + }else{ + this.setState({ + visible: true, + }); + this.getbasket_listdata(); + } + + + + }; + + onClose = () => { + this.setState({ + visible: false, + }); + }; + + onChange = e => { + this.setState({ + placement: e.target.value, + }); + }; + + getContainer = () => { + return this.container; + }; + saveContainer = container => { + this.container = container; + }; + + showmodels = (id) => { + + this.setState({ + modalsType: true, + titilesm: "设为公开后,所有成员均可使用试题", + titiless: "是否设置为公开?", + titbool: true, + timuid: id + }) + }; + showmodelysl = (id) => { + this.setState({ + modalsType: true, + titilesm: "确认删除后,无法撤销", + titiless: "是否确认删除?", + titbool: false, + timuid: id + }) + }; + + + modalCancel = () => { + this.setState({ + modalsType: false + }) + } + modalCancels=()=>{ + this.setState({ + modalsTypes: false + }) + } + showQuestionModals =(item_type)=>{ + this.setState({ + modalsTypes: true, + titilesms:item_type, + }) + + } + setDownloads=(item_type)=>{ + this.Deletebigquestiontype(item_type); + this.setState({ + modalsTypes: false + }) + } + setDownload = () => { + //确认 + if (this.state.titbool === true) { + //公开 + this.publicopentimu(this.state.timuid); + } else { + // 删除 + this.deletetimu(this.state.timuid); + } + this.setState({ + modalsType: false + }) + } + + setdifficulty = (difficulty) => { + this.setState({ + difficulty: difficulty, + visiblemys: false, + page: 1, + per_page:10, + keywords:"", + oj_status:null + }) + + var data = { + discipline_id:this.state.discipline_id, + sub_discipline_id:this.state.sub_discipline_id, + tag_discipline_id:this.state.tag_discipline_id, + public: this.state.defaultActiveKey, + difficulty: difficulty, + item_type: this.state.item_type, + keywords:null, + page:1, + per_page:10, + oj_status:null, + exam_id:this.props.exam_id + }; + + this.getdata(data); + + } + setitem_types = (item_type) => { + this.setState({ + item_type: item_type, + visiblemyss: false, + page: 1, + per_page:10, + keywords:"", + oj_status:null + }) + + var data = { + discipline_id:this.state.discipline_id, + sub_discipline_id:this.state.sub_discipline_id, + tag_discipline_id:this.state.tag_discipline_id, + public: this.state.defaultActiveKey, + difficulty: this.state.difficulty, + item_type: item_type, + page: 1, + per_page:10, + keywords:null, + oj_status:null, + exam_id:this.props.exam_id + }; + + this.getdata(data); + } + + handleVisibleChange = (boll) => { + if (this.state.visiblemyss === true) { + this.setState({ + visiblemys: boll, + visiblemyss: false, + }) + } else { + this.setState({ + visiblemys: boll, + }) + } + + } + + handleVisibleChanges = (boll) => { + if (this.state.visiblemys === true) { + this.setState({ + visiblemyss: boll, + visiblemys: false, + }) + } else { + this.setState({ + visiblemyss: boll, + }) + } + + } + + setdatafunsval = (e) => { + this.setState({ + keywords: e.target.value + }) + } + + setdatafuns = (value) => { + this.setState({ + keywords: value, + }) + var data = { + discipline_id:this.state.discipline_id, + sub_discipline_id:this.state.sub_discipline_id, + tag_discipline_id:this.state.tag_discipline_id, + public: this.state.defaultActiveKey, + difficulty: this.state.difficulty, + item_type: this.state.item_type, + keywords: value, + page: this.state.page, + per_page:10, + oj_status:this.state.oj_status, + exam_id:this.props.exam_id + }; + + this.getdata(data); + } + + deletetimu = (id) => { + + const url = `/item_banks/${id}.json`; + axios.delete(url) + .then((response) => { + if (response.data.status == 0) { + // this.props.showNotification('删除试题成功') + // props.history.push(response.data.right_url) + var data = { + discipline_id:this.state.discipline_id, + sub_discipline_id:this.state.sub_discipline_id, + tag_discipline_id:this.state.tag_discipline_id, + public: this.state.defaultActiveKey, + difficulty: this.state.difficulty, + item_type: this.state.item_type, + keywords: this.state.keywords, + page: this.state.page, + per_page:10, + exam_id:this.props.exam_id + }; + this.getdata(data); + } + }) + .catch(function (error) { + //console.log(error); + }); + } + publicopentimu = (id) => { + + const url = `/item_banks/${id}/set_public.json`; + axios.post(url) + .then((result) => { + if (result.data.status == 0) { + // this.props.showNotification(`公开题目成功`); + var data = { + discipline_id:this.state.discipline_id, + sub_discipline_id:this.state.sub_discipline_id, + tag_discipline_id:this.state.tag_discipline_id, + public: this.state.defaultActiveKey, + difficulty: this.state.difficulty, + item_type: this.state.item_type, + keywords: this.state.keywords, + page: this.state.page, + per_page:10, + exam_id:this.props.exam_id + + }; + this.getdata(data); + } + }).catch((error) => { + //console.log(error); + }) + } + + getbasket_listdata = () => { + // 获取试题篮展开的数据 + // const url = "/item_baskets/basket_list.json"; + // axios.get(url) + // .then((result) => { + // // //console.log("getbasket_listdata"); + // // //console.log(result.data); + // this.setState({ + // completion_questions_count: result.data.completion_questions_count, + // judgement_questions_count: result.data.judgement_questions_count, + // multiple_questions_count: result.data.multiple_questions_count, + // practical_questions_count: result.data.practical_questions_count, + // program_questions_count: result.data.program_questions_count, + // single_questions_count: result.data.single_questions_count, + // subjective_questions_count: result.data.subjective_questions_count, + // }) + // + // }).catch((error) => { + // // //console.log(error); + // this.setState({ + // completion_questions_count: 0, + // judgement_questions_count: 0, + // multiple_questions_count: 0, + // practical_questions_count: 0, + // program_questions_count: 0, + // single_questions_count: 0, + // subjective_questions_count: 0, + // }) + // }) + + } + + + //选用 + getitem_baskets=(data)=>{ + //选用题型可以上传单个 或者多个题型 + let url="/examination_items.json"; + + axios.post(url, data) + .then((result) => { + if (result.data.status == 0) { + // this.props.showNotification(`选用成功`); + var data = { + discipline_id:this.state.discipline_id, + sub_discipline_id:this.state.sub_discipline_id, + tag_discipline_id:this.state.tag_discipline_id, + public: this.state.defaultActiveKey, + difficulty: this.state.difficulty, + item_type: this.state.item_type, + keywords: this.state.keywords, + page: this.state.page, + per_page:10, + exam_id:this.props.exam_id + }; + this.getdatasy(data); + this.getbasket_listdata(); + // this.setState({ + // visible:true + // }) + } + }).catch((error) => { + //console.log(error); + }) + } + // 撤销 + getitem_basketss=(id)=>{ + //选用题型可以上传单个 或者多个题型 + let url=`/examination_banks/${id}/revoke_item.json`; + + axios.delete(url,{ data: { + item_id:this.props.exam_id + }}) + .then((result) => { + if (result.data.status == 0) { + // this.props.showNotification(`撤销成功`); + var data = { + discipline_id:this.state.discipline_id, + sub_discipline_id:this.state.sub_discipline_id, + tag_discipline_id:this.state.tag_discipline_id, + public: this.state.defaultActiveKey, + difficulty: this.state.difficulty, + item_type: this.state.item_type, + keywords: this.state.keywords, + page: this.state.page, + per_page:10, + exam_id:this.props.exam_id + }; + this.getdatasy(data); + this.getbasket_listdata(); + } + }).catch((error) => { + //console.log(error); + }) + } + //全选试题库 + selectallquestionsonthispage=()=>{ + var item_idsdata=[]; + + var arr= this.state.Contentdata.items; + for(let data of arr) { + if(data.item_type==="PROGRAM"){ + //编程题 + if(data.choosed===true){ + + }else{ + //未选用 + if(data.program_attr.status===1){ + //已发布 + item_idsdata.push(data.id); + } + + } + + }else{ + //不是编程题 + if(data.choosed===true){ + + }else{ + //未选用 + item_idsdata.push(data.id); + } + } + + } + const data={ + item_ids:item_idsdata, + exam_id:this.props.exam_id + } + this.getitem_baskets(data); + this.setState({ + selectallquestionsonthispages:true, + }) + } + + //全选的状态 + + //删除大题型 + Deletebigquestiontype =(item_type)=>{ + const url=`/item_baskets/delete_item_type.json`; + axios.delete((url), { data: { + item_type:item_type + }}) + .then((response) => { + if (response.data.status == 0) { + // this.props.showNotification('删除成功'); + var data = { + discipline_id:this.state.discipline_id, + sub_discipline_id:this.state.sub_discipline_id, + tag_discipline_id:this.state.tag_discipline_id, + public: this.state.defaultActiveKey, + difficulty: this.state.difficulty, + item_type: this.state.item_type, + keywords: this.state.keywords, + page: this.state.page, + per_page:10, + exam_id:this.props.exam_id + }; + this.getdata(data); + this.getbasket_listdata(); + } + }) + .catch(function (error) { + //console.log(error); + }); + + } + + + //跳转 + gotopaperreview=()=>{ + + this.props.history.replace("/paperreview"); + + } + + setoj_status=(oj_status)=>{ + //编程题发布未发布 + this.setState({ + selectallquestionsonthispages:false, + difficulty:null, + oj_status:oj_status + }) + var data = { + discipline_id:this.state.discipline_id, + sub_discipline_id:this.state.sub_discipline_id, + tag_discipline_id:this.state.tag_discipline_id, + public: this.state.defaultActiveKey, + difficulty: this.state.difficulty, + item_type: this.state.item_type, + keywords: this.state.keywords, + page: this.state.page, + per_page:10, + oj_status:oj_status, + exam_id:this.props.exam_id + }; + this.getdata(data); + } + + + render() { + let { + page, per_page, items_count, Headertop, visible, placement, modalsType, modalsTypes,basket_list, + completion_questions_count, judgement_questions_count, multiple_questions_count, practical_questions_count, + program_questions_count, single_questions_count, subjective_questions_count,selectionbools + } = this.state; + + const Datacount = completion_questions_count + judgement_questions_count + + multiple_questions_count + practical_questions_count + + program_questions_count + + single_questions_count + + subjective_questions_count; + + return ( +
+ + + { + visible===true? + + :"" + } + { + visible===true? +
+ :""} + { + modalsTypes===true? + this.modalCancels()} + setDownloads={(e) => this.setDownloads(e)}> + :"" + } + { + modalsType===true? + this.modalCancel()} + setDownload={() => this.setDownload()}> + :"" + } + + {/*顶部*/} + + this.setdifficulty(e)} + setitem_types={(e) => this.setitem_types(e)} + setdiscipline_id={(e)=>this.setdiscipline_id(e)} + setsub_discipline_id={(e)=>this.setsub_discipline_id(e)} + settag_discipline_id={(e)=>this.settag_discipline_id(e)} + /> + {/*头部*/} + this.getitem_basketss(id)} + selectallquestionsonthispage={()=>this.selectallquestionsonthispage()} + getitem_baskets={(e)=>this.getitem_baskets(e)} + setdatafuns={(e) => this.setdatafuns(e)} + setdatafunsval={(e) => this.setdatafunsval(e)} + handleVisibleChanges={(e) => this.handleVisibleChanges(e)} + handleVisibleChange={(e) => this.handleVisibleChange(e)} + showmodels={(e) => this.showmodels(e)} + showmodelysl={(e) => this.showmodelysl(e)} + callback={(e) => this.callback(e)} + setoj_status={(e)=>this.setoj_status(e)}> + + { + items_count&&items_count>10? +
+ +
+ :
+ +
+ } + + + this.props.setnewmyshixunmodelbool(false)} + onSubmits={() => this.props.setnewmyshixunmodelbool(false)} url={'/paperlibrary'}> +
+ ) + + } + +} + +export default NewMyShixunModel; diff --git a/public/react/src/modules/question/component/Contentpart.js b/public/react/src/modules/question/component/Contentpart.js index 6cca91f93..ee5b49e6b 100644 --- a/public/react/src/modules/question/component/Contentpart.js +++ b/public/react/src/modules/question/component/Contentpart.js @@ -132,7 +132,7 @@ class Contentpart extends Component { } .xaxisreverseorder .ant-input-lg { - height: 41px;} + height: 41px !important;} .xaxisreverseorder .ant-popover{ top: 30px !important; diff --git a/public/react/src/modules/question/component/Listjihe.js b/public/react/src/modules/question/component/Listjihe.js index 0b1f012f5..986e6e08f 100644 --- a/public/react/src/modules/question/component/Listjihe.js +++ b/public/react/src/modules/question/component/Listjihe.js @@ -37,9 +37,18 @@ class Listjihe extends Component { //选用 Selectingpracticaltraining=(id)=>{ - let data={ - item_ids:[id] - } + let data={} + if(this.props.exam_id===undefined){ + data={ + item_ids:[id] + } + }else{ + data={ + item_ids:[id], + exam_id:this.props.exam_id + } + } + this.props.getitem_baskets(data); } //撤销 @@ -184,8 +193,8 @@ class Listjihe extends Component { { items.choosed===true?

this.Selectingpracticaltrainings(items.id)}> - - 撤销

+ + 撤销

: items.item_type==="PROGRAM"? items.program_attr.status===0? diff --git a/public/react/src/modules/question/questioncss/questioncom.css b/public/react/src/modules/question/questioncss/questioncom.css index 4bf767b0f..c117ce20a 100644 --- a/public/react/src/modules/question/questioncss/questioncom.css +++ b/public/react/src/modules/question/questioncss/questioncom.css @@ -922,3 +922,17 @@ .mr15{ margin-right: 15px; } +.fangdatwo{ + background: #fefefe; + background-color: #fefefe; + height: 100%; + overflow-y: scroll !important; + width: 100%; + margin-top: 60px !important; + position: fixed; + top:0px; + bottom: 0px; + left: 0px; + z-index: 999999; + right: 0px; +} diff --git a/public/react/src/modules/testpaper/Paperlibraryeditid.js b/public/react/src/modules/testpaper/Paperlibraryeditid.js index 1497a12ec..4845ba757 100644 --- a/public/react/src/modules/testpaper/Paperlibraryeditid.js +++ b/public/react/src/modules/testpaper/Paperlibraryeditid.js @@ -22,7 +22,7 @@ import Paperlibraryseeid_item from './component/Paperlibraryseeid_item'; import Comthetestpaperst from '../question/comthetestpaper/Comthetestpaperst'; import Paperlibraryseeid_itemss from './component/Paperlibraryseeid_itemss'; import JudquestionEditor from "../question/component/JudquestionEditor"; - +import NewMyShixunModel from "../question/NewMyShixunModel" //人工组卷预览 class Paperlibraryeditid extends Component { constructor(props) { @@ -33,7 +33,8 @@ class Paperlibraryeditid extends Component { disciplinesdata: [], knowledgepoints: [], disciplmy: [], - item_banksedit: [] + item_banksedit: [], + newmyshixunmodelbool:false, } @@ -185,14 +186,39 @@ class Paperlibraryeditid extends Component { this.contentMdRef = Ref; } + setnewmyshixunmodelbool=(bool)=>{ + this.setState({ + newmyshixunmodelbool:bool + }) + } + render() { - let {paperlibrartdata} = this.state; + let {paperlibrartdata,newmyshixunmodelbool} = this.state; const params = this.props && this.props.match && this.props.match.params; - // //console.log(params); + // console.log("newmyshixunmodelbool"); + // console.log(newmyshixunmodelbool); return (
+ { + newmyshixunmodelbool===true? + + :"" + } + + { + newmyshixunmodelbool===true? +
+ this.setnewmyshixunmodelbool(e)}> +
+ : + "" + } - {/*
  • */} - {/* */} - {/*
    */} - {/*
    */} - {/* 题库*/} - {/*
    */} - {/*
    */} - {/*
    */} - {/*
  • */} +
  • + +
    +
    + 题库 +
    +
    +
    +
  • Date: Tue, 7 Jan 2020 16:53:35 +0800 Subject: [PATCH 015/156] ti --- public/react/src/AppConfig.js | 4 +-- .../src/modules/question/NewMyShixunModel.js | 34 +++++++++---------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/public/react/src/AppConfig.js b/public/react/src/AppConfig.js index a18e395dd..177328dfa 100644 --- a/public/react/src/AppConfig.js +++ b/public/react/src/AppConfig.js @@ -82,8 +82,8 @@ export function initAxiosInterceptors(props) { // proxy = "https://testeduplus2.educoder.net" //proxy="http://47.96.87.25:48080" proxy="https://pre-newweb.educoder.net" - // proxy="https://test-newweb.educoder.net" - proxy="https://test-jupyterweb.educoder.net" + proxy="https://test-newweb.educoder.net" + // proxy="https://test-jupyterweb.educoder.net" //proxy="http://192.168.2.63:3001" // 在这里使用requestMap控制,避免用户通过双击等操作发出重复的请求; diff --git a/public/react/src/modules/question/NewMyShixunModel.js b/public/react/src/modules/question/NewMyShixunModel.js index e8acf2202..6c922b037 100644 --- a/public/react/src/modules/question/NewMyShixunModel.js +++ b/public/react/src/modules/question/NewMyShixunModel.js @@ -91,7 +91,7 @@ class NewMyShixunModel extends Component { page: this.state.page, per_page:10, oj_status:null, - exam_id:this.props.exam_id + item_id:parseInt(this.props.exam_id), }; this.getdata(data); @@ -117,7 +117,7 @@ class NewMyShixunModel extends Component { page: 1, per_page:10, oj_status:null, - exam_id:this.props.exam_id + item_id:parseInt(this.props.exam_id), }; this.getdata(data); } @@ -141,7 +141,7 @@ class NewMyShixunModel extends Component { page: 1, per_page:10, oj_status:null, - exam_id:this.props.exam_id + item_id:parseInt(this.props.exam_id), }; this.getdata(data); } @@ -156,7 +156,7 @@ class NewMyShixunModel extends Component { public: defaultActiveKey, page:1, per_page:10, - exam_id:this.props.exam_id + item_id:parseInt(this.props.exam_id), }; this.getdata(data); @@ -209,7 +209,7 @@ class NewMyShixunModel extends Component { page: 1, per_page:10, oj_status:null, - exam_id:this.props.exam_id + item_id:parseInt(this.props.exam_id), }; this.getdata(data); @@ -342,7 +342,7 @@ class NewMyShixunModel extends Component { page: pageNumber, per_page:10, oj_status:this.state.oj_status, - exam_id:this.props.exam_id + item_id:parseInt(this.props.exam_id), }; this.getdata(data); @@ -461,7 +461,7 @@ class NewMyShixunModel extends Component { page:1, per_page:10, oj_status:null, - exam_id:this.props.exam_id + item_id:parseInt(this.props.exam_id), }; this.getdata(data); @@ -488,7 +488,7 @@ class NewMyShixunModel extends Component { per_page:10, keywords:null, oj_status:null, - exam_id:this.props.exam_id + item_id:parseInt(this.props.exam_id), }; this.getdata(data); @@ -543,7 +543,7 @@ class NewMyShixunModel extends Component { page: this.state.page, per_page:10, oj_status:this.state.oj_status, - exam_id:this.props.exam_id + item_id:parseInt(this.props.exam_id), }; this.getdata(data); @@ -567,7 +567,7 @@ class NewMyShixunModel extends Component { keywords: this.state.keywords, page: this.state.page, per_page:10, - exam_id:this.props.exam_id + item_id:parseInt(this.props.exam_id), }; this.getdata(data); } @@ -593,7 +593,7 @@ class NewMyShixunModel extends Component { keywords: this.state.keywords, page: this.state.page, per_page:10, - exam_id:this.props.exam_id + item_id:parseInt(this.props.exam_id), }; this.getdata(data); @@ -655,7 +655,7 @@ class NewMyShixunModel extends Component { keywords: this.state.keywords, page: this.state.page, per_page:10, - exam_id:this.props.exam_id + item_id:parseInt(this.props.exam_id), }; this.getdatasy(data); this.getbasket_listdata(); @@ -673,7 +673,7 @@ class NewMyShixunModel extends Component { let url=`/examination_banks/${id}/revoke_item.json`; axios.delete(url,{ data: { - item_id:this.props.exam_id + item_id:parseInt(this.props.exam_id), }}) .then((result) => { if (result.data.status == 0) { @@ -688,7 +688,7 @@ class NewMyShixunModel extends Component { keywords: this.state.keywords, page: this.state.page, per_page:10, - exam_id:this.props.exam_id + item_id:parseInt(this.props.exam_id), }; this.getdatasy(data); this.getbasket_listdata(); @@ -729,7 +729,7 @@ class NewMyShixunModel extends Component { } const data={ item_ids:item_idsdata, - exam_id:this.props.exam_id + item_id:parseInt(this.props.exam_id), } this.getitem_baskets(data); this.setState({ @@ -758,7 +758,7 @@ class NewMyShixunModel extends Component { keywords: this.state.keywords, page: this.state.page, per_page:10, - exam_id:this.props.exam_id + item_id:parseInt(this.props.exam_id), }; this.getdata(data); this.getbasket_listdata(); @@ -796,7 +796,7 @@ class NewMyShixunModel extends Component { page: this.state.page, per_page:10, oj_status:oj_status, - exam_id:this.props.exam_id + item_id:parseInt(this.props.exam_id), }; this.getdata(data); } From 2ec66eb9450ed461cb30022881573fcf43413e60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Tue, 7 Jan 2020 17:30:40 +0800 Subject: [PATCH 016/156] tiku --- .../src/modules/question/NewMyShixunModel.js | 50 +++++++++++-------- .../react/src/modules/question/Paperreview.js | 41 +++++++++++++-- .../src/modules/question/Paperreview_item.js | 2 +- .../modules/question/component/Listjihe.js | 2 +- .../modules/testpaper/Paperlibraryeditid.js | 16 +++++- 5 files changed, 84 insertions(+), 27 deletions(-) diff --git a/public/react/src/modules/question/NewMyShixunModel.js b/public/react/src/modules/question/NewMyShixunModel.js index 6c922b037..9db5d242f 100644 --- a/public/react/src/modules/question/NewMyShixunModel.js +++ b/public/react/src/modules/question/NewMyShixunModel.js @@ -91,7 +91,7 @@ class NewMyShixunModel extends Component { page: this.state.page, per_page:10, oj_status:null, - item_id:parseInt(this.props.exam_id), + item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdata(data); @@ -117,7 +117,7 @@ class NewMyShixunModel extends Component { page: 1, per_page:10, oj_status:null, - item_id:parseInt(this.props.exam_id), + item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdata(data); } @@ -141,7 +141,7 @@ class NewMyShixunModel extends Component { page: 1, per_page:10, oj_status:null, - item_id:parseInt(this.props.exam_id), + item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdata(data); } @@ -156,7 +156,7 @@ class NewMyShixunModel extends Component { public: defaultActiveKey, page:1, per_page:10, - item_id:parseInt(this.props.exam_id), + item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdata(data); @@ -209,7 +209,7 @@ class NewMyShixunModel extends Component { page: 1, per_page:10, oj_status:null, - item_id:parseInt(this.props.exam_id), + item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdata(data); @@ -342,7 +342,7 @@ class NewMyShixunModel extends Component { page: pageNumber, per_page:10, oj_status:this.state.oj_status, - item_id:parseInt(this.props.exam_id), + item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdata(data); @@ -461,7 +461,7 @@ class NewMyShixunModel extends Component { page:1, per_page:10, oj_status:null, - item_id:parseInt(this.props.exam_id), + item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdata(data); @@ -488,7 +488,7 @@ class NewMyShixunModel extends Component { per_page:10, keywords:null, oj_status:null, - item_id:parseInt(this.props.exam_id), + item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdata(data); @@ -543,7 +543,7 @@ class NewMyShixunModel extends Component { page: this.state.page, per_page:10, oj_status:this.state.oj_status, - item_id:parseInt(this.props.exam_id), + item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdata(data); @@ -567,7 +567,7 @@ class NewMyShixunModel extends Component { keywords: this.state.keywords, page: this.state.page, per_page:10, - item_id:parseInt(this.props.exam_id), + item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdata(data); } @@ -593,7 +593,7 @@ class NewMyShixunModel extends Component { keywords: this.state.keywords, page: this.state.page, per_page:10, - item_id:parseInt(this.props.exam_id), + item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdata(data); @@ -639,7 +639,13 @@ class NewMyShixunModel extends Component { //选用 getitem_baskets=(data)=>{ //选用题型可以上传单个 或者多个题型 - let url="/examination_items.json"; + let url=""; + if(this.props.exam_id===undefined){ + url="/item_baskets.json"; + }else{ + url="/examination_items.json"; + } + axios.post(url, data) .then((result) => { @@ -655,7 +661,7 @@ class NewMyShixunModel extends Component { keywords: this.state.keywords, page: this.state.page, per_page:10, - item_id:parseInt(this.props.exam_id), + item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdatasy(data); this.getbasket_listdata(); @@ -669,11 +675,15 @@ class NewMyShixunModel extends Component { } // 撤销 getitem_basketss=(id)=>{ - //选用题型可以上传单个 或者多个题型 - let url=`/examination_banks/${id}/revoke_item.json`; + let url=""; + if(this.props.exam_id===undefined){ + url=`/item_baskets/${id}.json`; + }else{ + url=`/examination_banks/${id}/revoke_item.json`; + } axios.delete(url,{ data: { - item_id:parseInt(this.props.exam_id), + item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }}) .then((result) => { if (result.data.status == 0) { @@ -688,7 +698,7 @@ class NewMyShixunModel extends Component { keywords: this.state.keywords, page: this.state.page, per_page:10, - item_id:parseInt(this.props.exam_id), + item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdatasy(data); this.getbasket_listdata(); @@ -729,7 +739,7 @@ class NewMyShixunModel extends Component { } const data={ item_ids:item_idsdata, - item_id:parseInt(this.props.exam_id), + item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), } this.getitem_baskets(data); this.setState({ @@ -758,7 +768,7 @@ class NewMyShixunModel extends Component { keywords: this.state.keywords, page: this.state.page, per_page:10, - item_id:parseInt(this.props.exam_id), + item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdata(data); this.getbasket_listdata(); @@ -796,7 +806,7 @@ class NewMyShixunModel extends Component { page: this.state.page, per_page:10, oj_status:oj_status, - item_id:parseInt(this.props.exam_id), + item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdata(data); } diff --git a/public/react/src/modules/question/Paperreview.js b/public/react/src/modules/question/Paperreview.js index 9014ba92b..67495dae3 100644 --- a/public/react/src/modules/question/Paperreview.js +++ b/public/react/src/modules/question/Paperreview.js @@ -24,6 +24,7 @@ import JudquestionEditor from "./component/JudquestionEditor"; import Paperreview_item from "./Paperreview_item" import Bottomsubmit from "../../modules/modals/Bottomsubmit"; import Comthetestpaperst from "./comthetestpaper/Comthetestpaperst"; +import NewMyShixunModel from "../question/NewMyShixunModel"; //人工组卷预览 class Paperreview extends Component { constructor(props) { @@ -49,7 +50,7 @@ class Paperreview extends Component { difficulty:null, name:null, duration:null, - + newmyshixunmodelbool:false, } // single_questions:null, 单选题 @@ -245,14 +246,48 @@ class Paperreview extends Component { getcontentMdRef = (Ref) => { this.contentMdRef = Ref; } + + setnewmyshixunmodelbool=(bool)=>{ + if(bool===true){ + let scrollToTop = window.setInterval(function() { + let pos = window.pageYOffset; + if ( pos > 0 ) { + window.scrollTo( 0, pos - 20 ); // how far to scroll on each step + } else { + window.clearInterval( scrollToTop ); + } + }, 2); + } + this.setState({ + newmyshixunmodelbool:bool + }) + } render() { - let {page, limit, count, Headertop, visible, placement, modalsType, item_type,Cohetepaperbool} = this.state; + let {page, limit, count, Headertop, visible, placement, modalsType, item_type,Cohetepaperbool,newmyshixunmodelbool} = this.state; const params = this.props && this.props.match && this.props.match.params; // //console.log(params); return (
    + { + newmyshixunmodelbool===true? + + :"" + } + + { + newmyshixunmodelbool===true? +
    + this.setnewmyshixunmodelbool(e)}> +
    + : + "" + }
    - {getFieldDecorator('rbnd', - { + {getFieldDecorator('rbnd' + , + {initialValue: this.state.rbnd, rules: [{required: true, message: '请选择难度'}], } )( - + 简单 适中 困难 diff --git a/public/react/src/modules/question/questioncss/questioncom.css b/public/react/src/modules/question/questioncss/questioncom.css index c117ce20a..5d37aeccd 100644 --- a/public/react/src/modules/question/questioncss/questioncom.css +++ b/public/react/src/modules/question/questioncss/questioncom.css @@ -928,7 +928,6 @@ height: 100%; overflow-y: scroll !important; width: 100%; - margin-top: 60px !important; position: fixed; top:0px; bottom: 0px; @@ -936,3 +935,7 @@ z-index: 999999; right: 0px; } + +.searchwidth{ + width: 347px !important; +} From d56e75324b95d98a14256be1e3aad48f309d61c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Wed, 8 Jan 2020 11:28:55 +0800 Subject: [PATCH 020/156] =?UTF-8?q?=E9=A2=98=E5=BA=93=E6=96=B0=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../react/src/common/quillForEditor/README.md | 1 + public/react/src/modules/question/Question.js | 23 ++ .../question/component/ChoquesEditor.js | 158 ++++++---- .../modules/question/component/Contentpart.js | 13 +- .../question/component/JudquestionEditor.js | 181 ++++++----- .../modules/question/component/Listjihe.js | 287 ++++++++++++------ .../question/component/SingleEditor.js | 194 +++++++----- .../question/questioncss/questioncom.css | 9 + 8 files changed, 562 insertions(+), 304 deletions(-) diff --git a/public/react/src/common/quillForEditor/README.md b/public/react/src/common/quillForEditor/README.md index 0369164c7..eea4de5cc 100644 --- a/public/react/src/common/quillForEditor/README.md +++ b/public/react/src/common/quillForEditor/README.md @@ -61,6 +61,7 @@ ### 使用 ```` + 编辑模式是放不大图片的 import QuillForEditor from 'xxx'; // 指定需要显示的工具栏信息, 不指定加载全部 diff --git a/public/react/src/modules/question/Question.js b/public/react/src/modules/question/Question.js index 171a2f2d7..0d51f4972 100644 --- a/public/react/src/modules/question/Question.js +++ b/public/react/src/modules/question/Question.js @@ -66,9 +66,28 @@ class Question extends Component { oj_status:null, isVisible: false, selectionbools:false, + chakanjiexiboolindex:"无", } } + + chakanjiexibool=(index)=>{ + debugger + if(this.state.chakanjiexiboolindex===index){ + this.setState({ + chakanjiexiboolindex:"无", + }) + return + } + this.setState({ + chakanjiexiboolindex:index, + }) + } + setmychakanjiexibool=(str)=>{ + this.setState({ + chakanjiexiboolindex:str, + }) + } setdiscipline_id=(discipline_id)=>{ this.setState({ discipline_id:discipline_id, @@ -338,6 +357,8 @@ class Question extends Component { oj_status:this.state.oj_status }; this.getdata(data); + this.setmychakanjiexibool("无") + } showDrawer = () => { if(this.state.visible===true){ @@ -882,6 +903,8 @@ class Question extends Component { /> {/*头部*/} this.chakanjiexibool(e)} getitem_basketss={(id)=>this.getitem_basketss(id)} selectallquestionsonthispage={()=>this.selectallquestionsonthispage()} getitem_baskets={(e)=>this.getitem_baskets(e)} diff --git a/public/react/src/modules/question/component/ChoquesEditor.js b/public/react/src/modules/question/component/ChoquesEditor.js index 99a713d7f..e31e4b41a 100644 --- a/public/react/src/modules/question/component/ChoquesEditor.js +++ b/public/react/src/modules/question/component/ChoquesEditor.js @@ -10,6 +10,7 @@ import axios from 'axios' import update from 'immutability-helper' import './../questioncss/questioncom.css'; import {getUrl, ActionBtn, DMDEditor, ConditionToolTip} from 'educoder'; +import QuillForEditor from '../../../common/quillForEditor'; const { TextArea } = Input; const confirm = Modal.confirm; const $ = window.$ @@ -70,10 +71,13 @@ class ChoquesEditor extends Component{ this.state = { question_choices: _question_choices || ['', '', '', ''], standard_answers: _standard_answers || [false, false, false, false], - question_title: this.props.question_title || '', + question_title: this.props.question_title!==undefined?JSON.parse(this.props.question_title):"", question_type: this.props.question_type || 0, question_score: this.props.question_score || this.props.init_question_score, - question_titles:this.props.question_titles||'', + question_titles: this.props.question_titles!==undefined?JSON.parse(this.props.question_titles):"", + question_titlesysl:this.props.question_titlesysl||'', + question_titleysl:this.props.question_title || '', + item_banksedit:[], } } addOption = () => { @@ -122,12 +126,11 @@ class ChoquesEditor extends Component{ } onSave = () => { var editordata=[]; - const {question_title, question_score, question_type,question_titles, question_choices, standard_answers } = this.state; + const {question_title, question_score,question_titleysl,question_titlesysl, question_type,question_titles, question_choices, standard_answers } = this.state; const { question_id_to_insert_after, question_id } = this.props // TODO check const answerArray = standard_answers.map((item, index) => { return item == true ? index+1 : -1 }).filter(item => item != -1); - if(!question_title) { - this.refs['titleEditor'].showError() + if(!question_titleysl) { this.props.showNotification('请您输入题干'); return editordata; } @@ -143,14 +146,12 @@ class ChoquesEditor extends Component{ for(let i = 0; i < question_choices.length; i++) { if (!question_choices[i]) { - this.refs[`optionEditor${i}`].showError() this.props.showNotification(`请先输入 ${tagArray[i]} 选项的内容`); return editordata; } } - if(!question_titles) { - this.refs['titleEditor2'].showError() + if(!question_titlesysl) { this.props.showNotification('请您输入题目解析'); return editordata; } @@ -162,7 +163,7 @@ class ChoquesEditor extends Component{ "question_choices":["a答案","b答案","c答案","d答案"], "standard_answers":[1] }*/ - editordata=[question_title,answerArray,question_choices,question_titles]; + editordata=[question_titleysl,answerArray,question_choices,question_titlesysl]; // question_title, // question_type: answerArray.length > 1 ? 1 : 0, // question_score, @@ -186,8 +187,10 @@ class ChoquesEditor extends Component{ try { this.setState({ item_banksedit:this.props.item_banksedit, - question_title:this.props.item_banksedit.name, - question_titles:this.props.item_banksedit.analysis, + question_title: this.props.item_banksedit.name!==undefined?JSON.parse(this.props.item_banksedit.name):"", + question_titleysl:this.props.item_banksedit.name|| '', + question_titles: this.props.item_banksedit.analysis!==undefined?JSON.parse(this.props.item_banksedit.analysis):"", + question_titlesysl:this.props.item_banksedit.analysis||'', mychoicess:this.props.item_banksedit.choices, }) @@ -205,8 +208,10 @@ class ChoquesEditor extends Component{ if(prevProps.item_banksedit !== this.props.item_banksedit) { this.setState({ item_banksedit: this.props.item_banksedit, - question_title: this.props.item_banksedit.name, - question_titles: this.props.item_banksedit.analysis, + question_title: this.props.item_banksedit.name!==undefined?JSON.parse(this.props.item_banksedit.name):"", + question_titleysl:this.props.item_banksedit.name|| '', + question_titles: this.props.item_banksedit.analysis!==undefined?JSON.parse(this.props.item_banksedit.analysis):"", + question_titlesysl:this.props.item_banksedit.analysis||'', mychoicess: this.props.item_banksedit.choices, }) @@ -217,15 +222,28 @@ class ChoquesEditor extends Component{ standard_answers[index] = !standard_answers[index] this.setState({ standard_answers }) } - onOptionContentChange = (value, index) => { + onOptionContentChange = (value,quill,index) => { if (index >= this.state.question_choices.length) { // TODO 新建,然后删除CD选项,再输入题干,会调用到这里,且index是3 return; } + var texts; + const _text = quill.getText(); + const reg = /^[\s\S]*.*[^\s][\s\S]*$/; + if (!reg.test(_text)) { + // 处理编辑器内容为空 + texts=""; + } else { + // 提交到后台的内容需要处理一下; + value = JSON.stringify(value) + texts=value; + } let question_choices = this.state.question_choices.slice(0); - question_choices[index] = value; - this.setState({ question_choices }) + question_choices[index] = texts; + console.log(question_choices); + this.setState({ question_choices }); } + on_question_score_change = (e) => { this.setState({ question_score: e }) } @@ -241,6 +259,41 @@ class ChoquesEditor extends Component{ toShowMode = () => { } + + onContentChange=(value,quill)=>{ + const _text = quill.getText(); + const reg = /^[\s\S]*.*[^\s][\s\S]*$/; + if (!reg.test(_text)) { + // 处理编辑器内容为空 + this.setState({ + question_titleysl:"" + }) + } else { + // 提交到后台的内容需要处理一下; + value = JSON.stringify(value) + this.setState({ + question_titleysl:value + }) + } + } + onContentChanges=(value,quill)=>{ + const _text = quill.getText(); + const reg = /^[\s\S]*.*[^\s][\s\S]*$/; + if (!reg.test(_text)) { + // 处理编辑器内容为空 + this.setState({ + question_titlesysl:"" + }) + } else { + // 提交到后台的内容需要处理一下; + value = JSON.stringify(value) + this.setState({ + question_titlesysl:value + }) + } + } + + render() { let { question_title, question_score, question_type, question_choices, standard_answers,question_titles} = this.state; let { question_id, index, exerciseIsPublish, @@ -271,7 +324,7 @@ class ChoquesEditor extends Component{ flex:1 } .optionRow { - margin:0px!important; + /* margin:0px!important; */ /* margin-bottom: 20px!important; */ } .signleEditor .content_editorMd_show{ @@ -291,11 +344,14 @@ class ChoquesEditor extends Component{ 题干:

    - this.setState({ question_title: val})} - ref="titleEditor" + + />
    {/* {!question_id ? '新建' : '编辑'} */} @@ -305,7 +361,7 @@ class ChoquesEditor extends Component{ {question_choices.map( (item, index) => { const bg = standard_answers[index] ? 'check-option-bg' : '' - return
    + return
    0?"df optionRow mt15": "df optionRow"} > {/* 点击设置答案 */} {/* TODO 加了tooltip后,会丢失掉span的class */} {/* */} @@ -317,13 +373,26 @@ class ChoquesEditor extends Component{ {/* */}
    - this.onOptionContentChange(value, index)} - initValue={item} - > + + { + item===undefined||item===null||item===""? + this.onOptionContentChange(value,quill,index)} + /> + : + this.onOptionContentChange(value,quill,index)} + /> + + }
    {exerciseIsPublish || index<=2? @@ -346,32 +415,19 @@ class ChoquesEditor extends Component{ -

    +

    {/* {!question_id ? '新建' : '编辑'} */} * 题目解析:

    - - this.setState({ question_titles: val})} - ref="titleEditor2" - - > +
    +
    diff --git a/public/react/src/modules/question/component/Contentpart.js b/public/react/src/modules/question/component/Contentpart.js index 0768c86b6..5ed610920 100644 --- a/public/react/src/modules/question/component/Contentpart.js +++ b/public/react/src/modules/question/component/Contentpart.js @@ -25,7 +25,6 @@ class Contentpart extends Component { this.state = { page:1, chakanjiexibool:false, - chakanjiexiboolindex:"无", } } //初始化 @@ -35,16 +34,7 @@ class Contentpart extends Component { } chakanjiexibool=(index)=>{ - debugger - if(this.state.chakanjiexiboolindex===index){ - this.setState({ - chakanjiexiboolindex:"无", - }) - return - } - this.setState({ - chakanjiexiboolindex:index, - }) + this.props.chakanjiexibool(index); } render() { @@ -230,6 +220,7 @@ class Contentpart extends Component { : this.props.Contentdata.items.map((object, index) => { return ( this.chakanjiexibool(keindex)} listjihe={index+1} keindex={index} diff --git a/public/react/src/modules/question/component/JudquestionEditor.js b/public/react/src/modules/question/component/JudquestionEditor.js index ff491125c..eb68308db 100644 --- a/public/react/src/modules/question/component/JudquestionEditor.js +++ b/public/react/src/modules/question/component/JudquestionEditor.js @@ -10,6 +10,8 @@ import axios from 'axios' import update from 'immutability-helper' import './../questioncss/questioncom.css'; import {getUrl, ActionBtn, DMDEditor, ConditionToolTip} from 'educoder'; +import QuillForEditor from '../../../common/quillForEditor'; + const { TextArea } = Input; const confirm = Modal.confirm; const $ = window.$ @@ -46,10 +48,12 @@ class JudquestionEditor extends Component{ this.state = { question_choices: _question_choices || ['', '', '', ''], standard_answers: _standard_answers || [false, false, false, false], - question_title: this.props.question_title || '', + question_title: this.props.question_title!==undefined?JSON.parse(this.props.question_title):"", question_type: this.props.question_type || 0, question_score: this.props.question_score || this.props.init_question_score, - question_titles:this.props.question_titles||'', + question_titles: this.props.question_titles!==undefined?JSON.parse(this.props.question_titles):"", + question_titlesysl:this.props.question_titlesysl||'', + question_titleysl:this.props.question_title || '', zqda:null, item_banksedit:[], mychoicess:[], @@ -99,12 +103,11 @@ class JudquestionEditor extends Component{ } onSave = () => { var editordata=[]; - const {question_title, question_score, question_type,question_titles, zqda,question_choices, standard_answers } = this.state; + const {question_title, question_score,question_titleysl,question_titlesysl, question_type,question_titles, zqda,question_choices, standard_answers } = this.state; const { question_id_to_insert_after, question_id } = this.props // TODO check const answerArray = standard_answers.map((item, index) => { return item == true ? index+1 : -1 }).filter(item => item != -1); - if(!question_title) { - this.refs['titleEditor'].showError() + if(!question_titleysl) { this.props.showNotification('请您输入题干'); return editordata; } @@ -117,8 +120,7 @@ class JudquestionEditor extends Component{ - if(!question_titles) { - this.refs['titleEditor2'].showError() + if(!question_titlesysl) { this.props.showNotification('请您输入题目解析'); return editordata; } @@ -132,7 +134,7 @@ class JudquestionEditor extends Component{ }*/ - editordata=[question_title,zqda,question_titles]; + editordata=[question_titleysl,zqda,question_titlesysl]; // question_title, // question_type: answerArray.length > 1 ? 1 : 0, // question_score, @@ -156,31 +158,31 @@ class JudquestionEditor extends Component{ try { this.setState({ item_banksedit:this.props.item_banksedit, - question_title:this.props.item_banksedit.name, - question_titles:this.props.item_banksedit.analysis, + question_title: this.props.item_banksedit.name!==undefined?JSON.parse(this.props.item_banksedit.name):"", + question_titles: this.props.item_banksedit.analysis!==undefined?JSON.parse(this.props.item_banksedit.analysis):"", mychoicess:this.props.item_banksedit.choices, }) - if(this.props.item_banksedit){ - if(this.props.item_banksedit.choices){ - for(var ik=0;ik{ + const _text = quill.getText(); + const reg = /^[\s\S]*.*[^\s][\s\S]*$/; + if (!reg.test(_text)) { + // 处理编辑器内容为空 + this.setState({ + question_titleysl:"" + }) + } else { + // 提交到后台的内容需要处理一下; + value = JSON.stringify(value) + this.setState({ + question_titleysl:value + }) + } + } + onContentChanges=(value,quill)=>{ + const _text = quill.getText(); + const reg = /^[\s\S]*.*[^\s][\s\S]*$/; + if (!reg.test(_text)) { + // 处理编辑器内容为空 + this.setState({ + question_titlesysl:"" + }) + } else { + // 提交到后台的内容需要处理一下; + value = JSON.stringify(value) + this.setState({ + question_titlesysl:value + }) + } + } render() { let { question_title, question_score, question_type, question_choices, standard_answers,question_titles} = this.state; let { question_id, index, exerciseIsPublish, @@ -325,11 +360,14 @@ class JudquestionEditor extends Component{ 题干:

    - this.setState({ question_title: val})} - ref="titleEditor" + + />
    {/* {!question_id ? '新建' : '编辑'} */} @@ -363,36 +401,23 @@ class JudquestionEditor extends Component{
    - +

    {/* {!question_id ? '新建' : '编辑'} */} * 题目解析:

    - - this.setState({ question_titles: val})} - ref="titleEditor2" - > +
    - +
    ) diff --git a/public/react/src/modules/question/component/Listjihe.js b/public/react/src/modules/question/component/Listjihe.js index f796a3f45..e793859cd 100644 --- a/public/react/src/modules/question/component/Listjihe.js +++ b/public/react/src/modules/question/component/Listjihe.js @@ -1,6 +1,6 @@ import React, {Component} from "react"; import {Link, NavLink} from 'react-router-dom'; -import {WordsBtn, ActionBtn,SnackbarHOC,getImageUrl,markdownToHTML} from 'educoder'; +import {WordsBtn, ActionBtn, SnackbarHOC, getImageUrl, markdownToHTML} from 'educoder'; import axios from 'axios'; import { notification, @@ -10,6 +10,8 @@ import { Radio } from "antd"; import './../questioncss/questioncom.css'; +import QuillForEditor from "../../../common/quillForEditor"; + const tagArray = [ 'A.', 'B.', 'C.', 'D.', 'E.', 'F.', 'G.', 'H.', 'I.', 'J.', 'K.', 'L.', 'M.', 'N.', 'O.', 'P.', 'Q.', 'R.', @@ -20,74 +22,73 @@ const tagArrays = [ 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' ] + class Listjihe extends Component { constructor(props) { super(props); this.state = { - page:1, - name:"单选题", - nd:"简单", + page: 1, + name: "单选题", + nd: "简单", } } + //初始化 - componentDidMount(){ + componentDidMount() { } //选用 - Selectingpracticaltraining=(id)=>{ - let data={} - if(this.props.exam_id===undefined){ - data={ - item_ids:[id] + Selectingpracticaltraining = (id) => { + let data = {} + if (this.props.exam_id === undefined) { + data = { + item_ids: [id] } - }else{ - data={ - item_ids:[id], - exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + } else { + data = { + item_ids: [id], + exam_id: this.props.exam_id === undefined ? "" : parseInt(this.props.exam_id), } - } + } this.props.getitem_baskets(data); } //撤销 - Selectingpracticaltrainings=(id)=>{ + Selectingpracticaltrainings = (id) => { this.props.getitem_basketss(id); } - - - render() { - let {page,name,nd}=this.state; - let {defaultActiveKey,items,listjihe,chakanjiexiboolindex,keindex}=this.props; + let {page, name, nd} = this.state; + let {defaultActiveKey, items, listjihe, chakanjiexiboolindex, keindex} = this.props; // 编程答案 - var rightkey=null + var rightkey = null - if(items){ - if(items.item_type){ - if(items.item_type==="PROGRAM"){ + if (items) { + if (items.item_type) { + if (items.item_type === "PROGRAM") { - }else{ - if(items.item_type==="JUDGMENT") { + } else { + if (items.item_type === "JUDGMENT") { - if(items.choices){ - if(items.choices.length>0){ - var arr= items.choices; - for(let data of arr) { - if(data.is_answer===true){ - rightkey=data.choice_text; + if (items.choices) { + if (items.choices.length > 0) { + var arr = items.choices; + for (let data of arr) { + if (data.is_answer === true) { + rightkey = data.choice_text; break; } } } } - }else { + } else { if (items.choices) { if (items.choices.length > 0) { var arr = items.choices; @@ -106,11 +107,41 @@ class Listjihe extends Component { } } - + var itemssname=""; + try { + itemssname= JSON.parse(items.name); + }catch (e) { + } + if(itemssname===undefined){ + itemssname=items.name + } return ( -
    +
    {/*顶部*/} +
    { @@ -120,17 +151,36 @@ class Listjihe extends Component {
    .
    -
    -
    + { + items.item_type==="PROGRAM"? + +
    + + : +
    + { items===undefined||items===null||items===""?"": + items.name === undefined || items.name === null || items.name === "" ? + "" + : + items.name.length>0? + + :"" + } +
    + } +
    {/*内容*/}
    - {items.item_type==="JUDGMENT"? -

    + {items.item_type === "JUDGMENT" ? +

    { - items === undefined ||items === null? "" : items.choices.map((object, index) => { + items === undefined || items === null ? "" : items.choices.map((object, index) => { return ( -

    +

    {object.choice_text} @@ -138,21 +188,52 @@ class Listjihe extends Component { ) }) } -

    : - items.item_type==="PROGRAM"? +

    : + items.item_type === "PROGRAM" ?

    -

    -

    +

    + { + items&&items.program_attr&&items.program_attr.description? +

    + + +

    + :"" + } + + +

    : -

    +

    { - items === undefined ||items === null? "" : items.choices.map((object, index) => { + items === undefined || items === null ? "" : items.choices.map((object, index) => { return ( -

    - {tagArray[index]} -

    +

    +

    {tagArray[index]}

    +

    + {object ? + object.choice_text === undefined || object.choice_text=== null || object.choice_text === "" ? + + "" + : + object.choice_text.length>0? + + :"" + + + : + "" + } +

    ) }) @@ -163,91 +244,95 @@ class Listjihe extends Component {
    -

    难度:{items.difficulty===1?"简单":items.difficulty===2?"适中":items.difficulty===3?"困难":""}

    -

    题型:{items.item_type==="SINGLE"?"单选题":items.item_type==="MULTIPLE"?"多选题":items.item_type==="JUDGMENT"?"判断题":items.item_type==="PROGRAM"?"编程题":""}

    +

    难度:{items.difficulty === 1 ? "简单" : items.difficulty === 2 ? "适中" : items.difficulty === 3 ? "困难" : ""} +

    +

    题型:{items.item_type === "SINGLE" ? "单选题" : items.item_type === "MULTIPLE" ? "多选题" : items.item_type === "JUDGMENT" ? "判断题" : items.item_type === "PROGRAM" ? "编程题" : ""} +

    {/*更新时间*/}

    更新时间:{items.update_time}

    { - this.props.defaultActiveKey==="0"||this.props.defaultActiveKey===0? + this.props.defaultActiveKey === "0" || this.props.defaultActiveKey === 0 ? "" :

    创建者:{items.author.name}

    } { - items.item_type==="PROGRAM"? + items.item_type === "PROGRAM" ?

    编程语言:{items.program_attr.language}

    - :"" + : "" } { - items.item_type==="PROGRAM"? - items.program_attr.status===0? + items.item_type === "PROGRAM" ? + items.program_attr.status === 0 ?

    未发布

    - :"" - :"" + : "" + : "" }
    { - items.choosed===true? -

    this.Selectingpracticaltrainings(items.id)}> + items.choosed === true ? +

    this.Selectingpracticaltrainings(items.id)}> 撤销

    : - items.item_type==="PROGRAM"? - items.program_attr.status===0? -

    + items.item_type === "PROGRAM" ? + items.program_attr.status === 0 ? +

    选用

    : -

    this.Selectingpracticaltraining(items.id)}> +

    this.Selectingpracticaltraining(items.id)}> 选用

    : -

    this.Selectingpracticaltraining(items.id)}> +

    this.Selectingpracticaltraining(items.id)}> 选用

    } { - defaultActiveKey===0||defaultActiveKey==="0"? + defaultActiveKey === 0 || defaultActiveKey === "0" ?
    -

    this.props.showmodelysl(items.id)}> +

    this.props.showmodelysl(items.id)}> 删除

    { - items.item_type==="PROGRAM"? + items.item_type === "PROGRAM" ? -

    +

    编辑

    : -

    +

    编辑

    } { - items.public===false? - items.item_type==="PROGRAM"? - items.program_attr.status===0? + items.public === false ? + items.item_type === "PROGRAM" ? + items.program_attr.status === 0 ? "" : -

    this.props.showmodels(items.id)}> +

    this.props.showmodels(items.id)}> 公开

    : -

    this.props.showmodels(items.id)}> +

    this.props.showmodels(items.id)}> 公开

    @@ -256,54 +341,65 @@ class Listjihe extends Component { }
    - :"" + : "" } { - items.item_type==="PROGRAM"? + items.item_type === "PROGRAM" ? "" : -

    this.props.chakanjiexibool(keindex)}> +

    this.props.chakanjiexibool(keindex)}> 查看解析

    } -
    { - chakanjiexiboolindex===keindex?
    + chakanjiexiboolindex === keindex ?
    -
    +
    { - items.item_type==="SINGLE" || items.item_type==="MULTIPLE"? + items.item_type === "SINGLE" || items.item_type === "MULTIPLE" ?

    :

    }
    - { - items&&items.analysis? - "" - :"" - } -
    -

    +

    + {items ? + items.analysis=== undefined || items.analysis=== null || items.analysis === "" ? + + "" + : + items.analysis.length>0? + + : + "" + : + "" + }

    -
    :"" +
    : "" } @@ -313,4 +409,5 @@ class Listjihe extends Component { } } + export default Listjihe; diff --git a/public/react/src/modules/question/component/SingleEditor.js b/public/react/src/modules/question/component/SingleEditor.js index c111aa41b..c0135ac1f 100644 --- a/public/react/src/modules/question/component/SingleEditor.js +++ b/public/react/src/modules/question/component/SingleEditor.js @@ -75,10 +75,12 @@ class SingleEditor extends Component{ this.state = { question_choices: _question_choices || ['', '', '', ''], standard_answers: _standard_answers || [false, false, false, false], - question_title: this.props.question_title || '', + question_title: this.props.question_title!==undefined?JSON.parse(this.props.question_title):"", question_type: this.props.question_type || 0, question_score: this.props.question_score || this.props.init_question_score, - question_titles:this.props.question_titles||'', + question_titles: this.props.question_titles!==undefined?JSON.parse(this.props.question_titles):"", + question_titlesysl:this.props.question_titlesysl||'', + question_titleysl:this.props.question_title || '', item_banksedit:[], } } @@ -121,12 +123,21 @@ class SingleEditor extends Component{ } onSave = () => { var editordata=[]; - const {question_title, question_score, question_type,question_titles, question_choices, standard_answers } = this.state; + const {question_title, question_titleysl,question_score, question_type,question_titles,question_titlesysl, question_choices, standard_answers } = this.state; const { question_id_to_insert_after, question_id } = this.props // TODO check const answerArray = standard_answers.map((item, index) => { return item == true ? index+1 : -1 }).filter(item => item != -1); - if(!question_title) { - this.refs['titleEditor'].showError() + + // const _text = quill.getText(); + // const reg = /^[\s\S]*.*[^\s][\s\S]*$/; + // if (!reg.test(_text)) { + // // 处理编辑器内容为空 + // } else { + // // 提交到后台的内容需要处理一下; + // value = JSON.stringify(value) + // } + if(!question_titleysl) { + // this.refs['titleEditor'].showError() this.props.showNotification('请您输入题干'); return editordata; } @@ -139,14 +150,13 @@ class SingleEditor extends Component{ for(let i = 0; i < question_choices.length; i++) { if (!question_choices[i]) { - this.refs[`optionEditor${i}`].showError() + // this.refs[`optionEditor${i}`].showError() this.props.showNotification(`请先输入 ${tagArray[i]} 选项的内容`); return editordata; } } - if(!question_titles) { - this.refs['titleEditor2'].showError() + if(!question_titlesysl) { this.props.showNotification('请您输入题目解析'); return editordata; } @@ -158,7 +168,7 @@ class SingleEditor extends Component{ "question_choices":["a答案","b答案","c答案","d答案"], "standard_answers":[1] }*/ - editordata=[question_title,answerArray,question_choices,question_titles]; + editordata=[question_titleysl,answerArray,question_choices,question_titlesysl]; // question_title, // question_type: answerArray.length > 1 ? 1 : 0, // question_score, @@ -184,8 +194,10 @@ class SingleEditor extends Component{ try { this.setState({ item_banksedit:this.props.item_banksedit, - question_title:this.props.item_banksedit.name, - question_titles:this.props.item_banksedit.analysis, + question_title: this.props.item_banksedit.name!==undefined?JSON.parse(this.props.item_banksedit.name):"", + question_titleysl:this.props.item_banksedit.name|| '', + question_titles: this.props.item_banksedit.analysis!==undefined?JSON.parse(this.props.item_banksedit.analysis):"", + question_titlesysl:this.props.item_banksedit.analysis||'', mychoicess:this.props.item_banksedit.choices, }) @@ -204,8 +216,10 @@ class SingleEditor extends Component{ if(prevProps.item_banksedit !== this.props.item_banksedit) { this.setState({ item_banksedit: this.props.item_banksedit, - question_title: this.props.item_banksedit.name, - question_titles: this.props.item_banksedit.analysis, + question_title: this.props.item_banksedit.name!==undefined?JSON.parse(this.props.item_banksedit.name):"", + question_titleysl:this.props.item_banksedit.name|| '', + question_titles: this.props.item_banksedit.analysis!==undefined?JSON.parse(this.props.item_banksedit.analysis):"", + question_titlesysl:this.props.item_banksedit.analysis||'', mychoicess: this.props.item_banksedit.choices, }) @@ -229,14 +243,26 @@ class SingleEditor extends Component{ // standard_answers[index] = !standard_answers[index]; this.setState({ standard_answers }) } - onOptionContentChange = (value, index) => { + onOptionContentChange = (value,quill,index) => { if (index >= this.state.question_choices.length) { // TODO 新建,然后删除CD选项,再输入题干,会调用到这里,且index是3 return; } + var texts; + const _text = quill.getText(); + const reg = /^[\s\S]*.*[^\s][\s\S]*$/; + if (!reg.test(_text)) { + // 处理编辑器内容为空 + texts=""; + } else { + // 提交到后台的内容需要处理一下; + value = JSON.stringify(value) + texts=value; + } let question_choices = this.state.question_choices.slice(0); - question_choices[index] = value; - this.setState({ question_choices }) + question_choices[index] = texts; + console.log(question_choices); + this.setState({ question_choices }); } on_question_score_change = (e) => { this.setState({ question_score: e }) @@ -254,11 +280,46 @@ class SingleEditor extends Component{ } - onContentChange=(e)=>{ - console.log(e); + onContentChange=(value,quill)=>{ + const _text = quill.getText(); + const reg = /^[\s\S]*.*[^\s][\s\S]*$/; + if (!reg.test(_text)) { + // 处理编辑器内容为空 + this.setState({ + question_titleysl:"" + }) + } else { + // 提交到后台的内容需要处理一下; + value = JSON.stringify(value) + this.setState({ + question_titleysl:value + }) + } } + onContentChanges=(value,quill)=>{ + const _text = quill.getText(); + const reg = /^[\s\S]*.*[^\s][\s\S]*$/; + if (!reg.test(_text)) { + // 处理编辑器内容为空 + this.setState({ + question_titlesysl:"" + }) + } else { + // 提交到后台的内容需要处理一下; + value = JSON.stringify(value) + this.setState({ + question_titlesysl:value + }) + } + } + handleShowImage = (url) => { + console.log("点击了图片放大"); + console.log(url); + alert(url); + } + render() { - let { question_title, question_score, question_type, question_choices, standard_answers,question_titles} = this.state; + let { question_title, question_score, question_type, question_choices, standard_answers,question_titles,question_titlesysl} = this.state; let { question_id, index, exerciseIsPublish, // question_title, // question_type, @@ -279,7 +340,6 @@ class SingleEditor extends Component{ // ////console.log("xuanzheshijuan"); // ////console.log(answerTagArray); // ////console.log(!exerciseIsPublish); - return(
    - this.setState({ question_titles: val})} - ref="titleEditor2" - - > +
    +
    diff --git a/public/react/src/modules/question/questioncss/questioncom.css b/public/react/src/modules/question/questioncss/questioncom.css index 5d37aeccd..1bdf3853c 100644 --- a/public/react/src/modules/question/questioncss/questioncom.css +++ b/public/react/src/modules/question/questioncss/questioncom.css @@ -332,6 +332,12 @@ line-height:19px; margin-top: 19px; } +.listjihetixingstitsp{ + color: #333333; + font-size: 14px; + line-height:19px; + margin-top: 10px; +} .listjihetixingstitssy{ color: #333333; font-size: 14px; @@ -939,3 +945,6 @@ .searchwidth{ width: 347px !important; } +.lh26{ + line-height: 26px !important; +} From f289e9c270bb1603a6b86aea13d9b4592aeae4c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Wed, 8 Jan 2020 14:32:15 +0800 Subject: [PATCH 021/156] =?UTF-8?q?=E8=BE=93=E5=85=A5=E8=B6=85=E8=BF=87100?= =?UTF-8?q?=E5=AD=97=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../question/component/ChoquesEditor.js | 36 ++++++++++++++---- .../question/component/JudquestionEditor.js | 24 ++++++++++-- .../question/component/SingleEditor.js | 38 ++++++++++++++----- .../modules/testpaper/Paperlibraryeditid.js | 15 ++++++-- public/react/src/modules/tpm/NewHeader.js | 13 +++++-- 5 files changed, 98 insertions(+), 28 deletions(-) diff --git a/public/react/src/modules/question/component/ChoquesEditor.js b/public/react/src/modules/question/component/ChoquesEditor.js index e31e4b41a..afb7f4b3a 100644 --- a/public/react/src/modules/question/component/ChoquesEditor.js +++ b/public/react/src/modules/question/component/ChoquesEditor.js @@ -234,9 +234,15 @@ class ChoquesEditor extends Component{ // 处理编辑器内容为空 texts=""; } else { - // 提交到后台的内容需要处理一下; - value = JSON.stringify(value) - texts=value; + if(_text.length>=101){ + var result = _text.substring(0,100); + texts={"ops":[{"insert":result}]}; + texts=JSON.stringify(texts); + }else { + // 提交到后台的内容需要处理一下; + value = JSON.stringify(value); + texts=value; + } } let question_choices = this.state.question_choices.slice(0); question_choices[index] = texts; @@ -270,9 +276,17 @@ class ChoquesEditor extends Component{ }) } else { // 提交到后台的内容需要处理一下; - value = JSON.stringify(value) + var texts=""; + if(_text.length>=101){ + var result = _text.substring(0,100); + texts={"ops":[{"insert":result}]}; + texts=JSON.stringify(texts); + }else { + value = JSON.stringify(value) + texts=value; + } this.setState({ - question_titleysl:value + question_titleysl:texts }) } } @@ -286,9 +300,17 @@ class ChoquesEditor extends Component{ }) } else { // 提交到后台的内容需要处理一下; - value = JSON.stringify(value) + var texts=""; + if(_text.length>=101){ + var result = _text.substring(0,100); + texts={"ops":[{"insert":result}]}; + texts=JSON.stringify(texts); + }else { + value = JSON.stringify(value) + texts=value; + } this.setState({ - question_titlesysl:value + question_titleysl:texts }) } } diff --git a/public/react/src/modules/question/component/JudquestionEditor.js b/public/react/src/modules/question/component/JudquestionEditor.js index eb68308db..3adba9e5c 100644 --- a/public/react/src/modules/question/component/JudquestionEditor.js +++ b/public/react/src/modules/question/component/JudquestionEditor.js @@ -288,9 +288,17 @@ class JudquestionEditor extends Component{ }) } else { // 提交到后台的内容需要处理一下; - value = JSON.stringify(value) + var texts=""; + if(_text.length>=101){ + var result = _text.substring(0,100); + texts={"ops":[{"insert":result}]}; + texts=JSON.stringify(texts); + }else { + value = JSON.stringify(value) + texts=value; + } this.setState({ - question_titleysl:value + question_titleysl:texts }) } } @@ -304,9 +312,17 @@ class JudquestionEditor extends Component{ }) } else { // 提交到后台的内容需要处理一下; - value = JSON.stringify(value) + var texts=""; + if(_text.length>=101){ + var result = _text.substring(0,100); + texts={"ops":[{"insert":result}]}; + texts=JSON.stringify(texts); + }else { + value =JSON.stringify(value); + texts=value; + } this.setState({ - question_titlesysl:value + question_titleysl:texts }) } } diff --git a/public/react/src/modules/question/component/SingleEditor.js b/public/react/src/modules/question/component/SingleEditor.js index c0135ac1f..bf2c27b36 100644 --- a/public/react/src/modules/question/component/SingleEditor.js +++ b/public/react/src/modules/question/component/SingleEditor.js @@ -255,13 +255,18 @@ class SingleEditor extends Component{ // 处理编辑器内容为空 texts=""; } else { - // 提交到后台的内容需要处理一下; - value = JSON.stringify(value) - texts=value; + if(_text.length>=101){ + var result = _text.substring(0,100); + texts={"ops":[{"insert":result}]}; + texts=JSON.stringify(texts); + }else { + // 提交到后台的内容需要处理一下; + value = JSON.stringify(value) + texts=value; + } } let question_choices = this.state.question_choices.slice(0); question_choices[index] = texts; - console.log(question_choices); this.setState({ question_choices }); } on_question_score_change = (e) => { @@ -290,9 +295,17 @@ class SingleEditor extends Component{ }) } else { // 提交到后台的内容需要处理一下; - value = JSON.stringify(value) + var texts=""; + if(_text.length>=101){ + var result = _text.substring(0,100); + texts={"ops":[{"insert":result}]}; + texts=JSON.stringify(texts); + }else { + value = JSON.stringify(value) + texts=value; + } this.setState({ - question_titleysl:value + question_titleysl:texts }) } } @@ -305,10 +318,17 @@ class SingleEditor extends Component{ question_titlesysl:"" }) } else { - // 提交到后台的内容需要处理一下; - value = JSON.stringify(value) + var texts=""; + if(_text.length>=101){ + var result = _text.substring(0,100); + texts={"ops":[{"insert":result}]}; + texts=JSON.stringify(texts); + }else { + value = JSON.stringify(value) + texts=value; + } this.setState({ - question_titlesysl:value + question_titleysl:texts }) } } diff --git a/public/react/src/modules/testpaper/Paperlibraryeditid.js b/public/react/src/modules/testpaper/Paperlibraryeditid.js index 1b3ee95ef..efcb45496 100644 --- a/public/react/src/modules/testpaper/Paperlibraryeditid.js +++ b/public/react/src/modules/testpaper/Paperlibraryeditid.js @@ -258,17 +258,24 @@ class Paperlibraryeditid extends Component {
    - + +
    this.setnewmyshixunmodelbool(e)} all_score={paperlibrartdata && paperlibrartdata.exam && paperlibrartdata.exam.all_questions_count} all_questions_count={paperlibrartdata && paperlibrartdata.exam && paperlibrartdata.exam.all_score} difficulty={paperlibrartdata && paperlibrartdata.exam && paperlibrartdata.exam.difficulty} > - - - +
    { return (
    + {isRender===true?this.Modifyloginvalue()} @@ -1033,13 +1040,11 @@ submittojoinclass=(value)=>{ top: 63px !important; } - .ant-popover-inner-content { - padding:0px !important; - } + ` } -
  • +
  • Date: Wed, 8 Jan 2020 15:15:29 +0800 Subject: [PATCH 022/156] =?UTF-8?q?=E8=AF=95=E5=8D=B7=E9=A2=84=E8=A7=88=20?= =?UTF-8?q?=E8=AF=95=E5=8D=B7=E7=BC=96=E8=BE=91=20=20=E5=B1=95=E7=A4=BA?= =?UTF-8?q?=E6=96=B0=E7=9A=84=E7=BC=96=E8=BE=91=E5=99=A8=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/modules/question/Paperreview_item.js | 4 +- .../src/modules/question/Paperreview_items.js | 4 +- .../modules/question/Paperreview_single.js | 96 +++++++++++++++++-- .../question/questioncss/questioncom.css | 3 + 4 files changed, 94 insertions(+), 13 deletions(-) diff --git a/public/react/src/modules/question/Paperreview_item.js b/public/react/src/modules/question/Paperreview_item.js index 9112aa248..a9747e8c2 100644 --- a/public/react/src/modules/question/Paperreview_item.js +++ b/public/react/src/modules/question/Paperreview_item.js @@ -426,8 +426,8 @@ class Paperreview_item extends Component { }}>
    -

    题数:{this.props.all_score}

    -

    总分:{this.props.all_questions_count}

    +

    题数:{this.props.all_questions_count}

    +

    总分:{this.props.all_score}

    this.props.setnewmyshixunmodelbool(true)}> diff --git a/public/react/src/modules/question/Paperreview_items.js b/public/react/src/modules/question/Paperreview_items.js index 81ec320b5..8e86c514a 100644 --- a/public/react/src/modules/question/Paperreview_items.js +++ b/public/react/src/modules/question/Paperreview_items.js @@ -59,8 +59,8 @@ class Paperreview_items extends Component { let {paperreviewsingleindex,paperreviewsinglename,typenames,indexs,object,typenamesn}=this.props; // console.log(object); - console.log("Paperreview_items"); - console.log(object.item_id); + // console.log("Paperreview_items"); + // console.log(object.item_id); return (
    { diff --git a/public/react/src/modules/question/Paperreview_single.js b/public/react/src/modules/question/Paperreview_single.js index 5b64372a8..fdc9ff095 100644 --- a/public/react/src/modules/question/Paperreview_single.js +++ b/public/react/src/modules/question/Paperreview_single.js @@ -17,6 +17,7 @@ import Itembankstop from "./component/Itembankstop"; import NoneData from './component/NoneData'; import './questioncss/questioncom.css'; import '../tpm/newshixuns/css/Newshixuns.css'; +import QuillForEditor from "../../common/quillForEditor"; const tagArray = [ 'A.', 'B.', 'C.', 'D.', 'E.', 'F.', 'G.', 'H.', 'I.', @@ -69,13 +70,42 @@ class Paperreview_single extends Component { render() { let {questions, totalscore, total, items} = this.state; let {objectsingle, indexx, paperreviewsingleindex, indexxy,name} = this.props; + + + var itemssname=""; + try { + itemssname= JSON.parse(objectsingle.name); + }catch (e) { + } + if(itemssname===undefined){ + itemssname=objectsingle.name + } return (
    this.props.showparagraphs(indexxy,name)} style={{ minHeight: "114px", }}> - + {/*顶部*/}
    @@ -99,9 +129,35 @@ class Paperreview_single extends Component { ` } -
    -
    + { + objectsingle.item_type==="PROGRAM"? +
    +
    + ({objectsingle.score}分) +
    +
    + +
    +
    + : +
    +
    + ({objectsingle.score}分) +
    +
    + + +
    +
    + } +
    {/*内容*/}
    @@ -114,7 +170,7 @@ class Paperreview_single extends Component { objectsingle === undefined || objectsingle === null ? "" : objectsingle.choices.map((object, index) => { return (

    - + {object.choice_text}

    @@ -126,8 +182,17 @@ class Paperreview_single extends Component { objectsingle.item_type === "PROGRAM" ?

    -

    + { + objectsingle&&objectsingle.program_attr&&objectsingle.program_attr.description? +

    + +

    + : + ""}

    : @@ -137,8 +202,21 @@ class Paperreview_single extends Component { return (

    {tagArray[index]} -

    +

    + {object ? + object.choice_text === undefined || object.choice_text=== null || object.choice_text === "" ? + "" + : + object.choice_text.length>0? + + :"" + : + "" + } +

    ) }) diff --git a/public/react/src/modules/question/questioncss/questioncom.css b/public/react/src/modules/question/questioncss/questioncom.css index 1bdf3853c..ec2df7ca9 100644 --- a/public/react/src/modules/question/questioncss/questioncom.css +++ b/public/react/src/modules/question/questioncss/questioncom.css @@ -948,3 +948,6 @@ .lh26{ line-height: 26px !important; } +.tites{ + color: #888888 !important; +} From fc3fd27d49fc7ca2a832c82c31af352f1689a7fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Wed, 8 Jan 2020 15:43:44 +0800 Subject: [PATCH 023/156] =?UTF-8?q?=E8=B0=83=E6=95=B4=E8=AF=95=E5=8D=B7?= =?UTF-8?q?=E9=A2=98=E5=BA=93=E9=80=89=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/modules/question/NewMyShixunModel.js | 34 +++--- .../question/questioncss/questioncom.css | 5 + .../component/Paperlibraryseeid_items.js | 104 ++++++++++++++---- .../testpaper/testioncss/testioncss.css | 3 + 4 files changed, 110 insertions(+), 36 deletions(-) diff --git a/public/react/src/modules/question/NewMyShixunModel.js b/public/react/src/modules/question/NewMyShixunModel.js index 9db5d242f..364dd39f5 100644 --- a/public/react/src/modules/question/NewMyShixunModel.js +++ b/public/react/src/modules/question/NewMyShixunModel.js @@ -91,7 +91,7 @@ class NewMyShixunModel extends Component { page: this.state.page, per_page:10, oj_status:null, - item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdata(data); @@ -117,7 +117,7 @@ class NewMyShixunModel extends Component { page: 1, per_page:10, oj_status:null, - item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdata(data); } @@ -141,7 +141,7 @@ class NewMyShixunModel extends Component { page: 1, per_page:10, oj_status:null, - item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdata(data); } @@ -156,7 +156,7 @@ class NewMyShixunModel extends Component { public: defaultActiveKey, page:1, per_page:10, - item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdata(data); @@ -209,7 +209,7 @@ class NewMyShixunModel extends Component { page: 1, per_page:10, oj_status:null, - item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdata(data); @@ -342,7 +342,7 @@ class NewMyShixunModel extends Component { page: pageNumber, per_page:10, oj_status:this.state.oj_status, - item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdata(data); @@ -461,7 +461,7 @@ class NewMyShixunModel extends Component { page:1, per_page:10, oj_status:null, - item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdata(data); @@ -488,7 +488,7 @@ class NewMyShixunModel extends Component { per_page:10, keywords:null, oj_status:null, - item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdata(data); @@ -543,7 +543,7 @@ class NewMyShixunModel extends Component { page: this.state.page, per_page:10, oj_status:this.state.oj_status, - item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdata(data); @@ -567,7 +567,7 @@ class NewMyShixunModel extends Component { keywords: this.state.keywords, page: this.state.page, per_page:10, - item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdata(data); } @@ -593,7 +593,7 @@ class NewMyShixunModel extends Component { keywords: this.state.keywords, page: this.state.page, per_page:10, - item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdata(data); @@ -661,7 +661,7 @@ class NewMyShixunModel extends Component { keywords: this.state.keywords, page: this.state.page, per_page:10, - item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdatasy(data); this.getbasket_listdata(); @@ -683,7 +683,7 @@ class NewMyShixunModel extends Component { } axios.delete(url,{ data: { - item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }}) .then((result) => { if (result.data.status == 0) { @@ -698,7 +698,7 @@ class NewMyShixunModel extends Component { keywords: this.state.keywords, page: this.state.page, per_page:10, - item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdatasy(data); this.getbasket_listdata(); @@ -739,7 +739,7 @@ class NewMyShixunModel extends Component { } const data={ item_ids:item_idsdata, - item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), } this.getitem_baskets(data); this.setState({ @@ -768,7 +768,7 @@ class NewMyShixunModel extends Component { keywords: this.state.keywords, page: this.state.page, per_page:10, - item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdata(data); this.getbasket_listdata(); @@ -806,7 +806,7 @@ class NewMyShixunModel extends Component { page: this.state.page, per_page:10, oj_status:oj_status, - item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), }; this.getdata(data); } diff --git a/public/react/src/modules/question/questioncss/questioncom.css b/public/react/src/modules/question/questioncss/questioncom.css index ec2df7ca9..153e94f20 100644 --- a/public/react/src/modules/question/questioncss/questioncom.css +++ b/public/react/src/modules/question/questioncss/questioncom.css @@ -951,3 +951,8 @@ .tites{ color: #888888 !important; } +.ant-popover-inner-content{ + padding: 0px !important; +} + + diff --git a/public/react/src/modules/testpaper/component/Paperlibraryseeid_items.js b/public/react/src/modules/testpaper/component/Paperlibraryseeid_items.js index 1ab987ba0..0a6a718c3 100644 --- a/public/react/src/modules/testpaper/component/Paperlibraryseeid_items.js +++ b/public/react/src/modules/testpaper/component/Paperlibraryseeid_items.js @@ -15,6 +15,7 @@ import { } from "antd"; import '../testioncss/testioncss.css'; import '../../tpm/newshixuns/css/Newshixuns.css'; +import QuillForEditor from "../../../common/quillForEditor"; const tagArray = [ 'A.', 'B.', 'C.', 'D.', 'E.', 'F.', 'G.', 'H.', 'I.', @@ -67,15 +68,42 @@ class Paperlibraryseeid_items extends Component { render() { let {questions, totalscore, total, items} = this.state; let {objectsingle, indexx, paperreviewsingleindex, indexxy,name} = this.props; - // console.log("objectsingle"); - // console.log(objectsingle); + + + var itemssname=""; + try { + itemssname= JSON.parse(objectsingle.name); + }catch (e) { + } + if(itemssname===undefined){ + itemssname=objectsingle.name + } return (
    - + {/*顶部*/}
    @@ -100,29 +128,46 @@ class Paperlibraryseeid_items extends Component { } { - this.props.typenames==="PROGRAM"? -
    -
    + objectsingle.item_type==="PROGRAM"? +
    +
    + ({objectsingle.score}分) +
    +
    + +
    +
    : -
    +
    +
    + ({objectsingle.score}分) +
    +
    + + +
    - } +
    {/*内容*/}
    - { objectsingle.item_type === "JUDGMENT" ?

    { objectsingle === undefined || objectsingle === null ? "" : objectsingle.choices.map((object, index) => { return ( -

    - +

    + {object.choice_text}

    @@ -134,8 +179,17 @@ class Paperlibraryseeid_items extends Component { objectsingle.item_type === "PROGRAM" ?

    -

    + { + objectsingle&&objectsingle.program_attr&&objectsingle.program_attr.description? +

    + +

    + : + ""}

    : @@ -143,10 +197,23 @@ class Paperlibraryseeid_items extends Component { { objectsingle === undefined || objectsingle === null ? "" : objectsingle.choices.map((object, index) => { return ( -

    +

    {tagArray[index]} -

    +

    + {object ? + object.choice_text === undefined || object.choice_text=== null || object.choice_text === "" ? + "" + : + object.choice_text.length>0? + + :"" + : + "" + } +

    ) }) @@ -154,7 +221,6 @@ class Paperlibraryseeid_items extends Component {

    } -
    diff --git a/public/react/src/modules/testpaper/testioncss/testioncss.css b/public/react/src/modules/testpaper/testioncss/testioncss.css index a1de362d1..d5d27dbe1 100644 --- a/public/react/src/modules/testpaper/testioncss/testioncss.css +++ b/public/react/src/modules/testpaper/testioncss/testioncss.css @@ -892,3 +892,6 @@ width: 39px; height: 44px; } +.tites{ + color: #888888 !important; +} From 0573dcfc8913625871fef948a2ba25cda3de989a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Wed, 8 Jan 2020 15:50:50 +0800 Subject: [PATCH 024/156] =?UTF-8?q?=E8=B0=83=E6=95=B4=E8=AF=95=E5=8D=B7?= =?UTF-8?q?=E9=A2=98=E5=BA=93=E9=80=89=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/react/src/AppConfig.js | 4 +- .../src/modules/question/NewMyShixunModel.js | 73 ++++++++++++------- 2 files changed, 50 insertions(+), 27 deletions(-) diff --git a/public/react/src/AppConfig.js b/public/react/src/AppConfig.js index 177328dfa..a18e395dd 100644 --- a/public/react/src/AppConfig.js +++ b/public/react/src/AppConfig.js @@ -82,8 +82,8 @@ export function initAxiosInterceptors(props) { // proxy = "https://testeduplus2.educoder.net" //proxy="http://47.96.87.25:48080" proxy="https://pre-newweb.educoder.net" - proxy="https://test-newweb.educoder.net" - // proxy="https://test-jupyterweb.educoder.net" + // proxy="https://test-newweb.educoder.net" + proxy="https://test-jupyterweb.educoder.net" //proxy="http://192.168.2.63:3001" // 在这里使用requestMap控制,避免用户通过双击等操作发出重复的请求; diff --git a/public/react/src/modules/question/NewMyShixunModel.js b/public/react/src/modules/question/NewMyShixunModel.js index 364dd39f5..bfb8f5690 100644 --- a/public/react/src/modules/question/NewMyShixunModel.js +++ b/public/react/src/modules/question/NewMyShixunModel.js @@ -678,34 +678,57 @@ class NewMyShixunModel extends Component { let url=""; if(this.props.exam_id===undefined){ url=`/item_baskets/${id}.json`; + axios.delete(url) + .then((result) => { + if (result.data.status == 0) { + // this.props.showNotification(`撤销成功`); + var data = { + discipline_id:this.state.discipline_id, + sub_discipline_id:this.state.sub_discipline_id, + tag_discipline_id:this.state.tag_discipline_id, + public: this.state.defaultActiveKey, + difficulty: this.state.difficulty, + item_type: this.state.item_type, + keywords: this.state.keywords, + page: this.state.page, + per_page:10, + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + }; + this.getdatasy(data); + this.getbasket_listdata(); + } + }).catch((error) => { + //console.log(error); + }) }else{ - url=`/examination_banks/${id}/revoke_item.json`; + url=`/examination_banks/${this.props.exam_id}/revoke_item.json`; + axios.delete(url,{ data: { + item_id:id===undefined?"":parseInt(id), + }}) + .then((result) => { + if (result.data.status == 0) { + // this.props.showNotification(`撤销成功`); + var data = { + discipline_id:this.state.discipline_id, + sub_discipline_id:this.state.sub_discipline_id, + tag_discipline_id:this.state.tag_discipline_id, + public: this.state.defaultActiveKey, + difficulty: this.state.difficulty, + item_type: this.state.item_type, + keywords: this.state.keywords, + page: this.state.page, + per_page:10, + exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), + }; + this.getdatasy(data); + this.getbasket_listdata(); + } + }).catch((error) => { + //console.log(error); + }) } - axios.delete(url,{ data: { - exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), - }}) - .then((result) => { - if (result.data.status == 0) { - // this.props.showNotification(`撤销成功`); - var data = { - discipline_id:this.state.discipline_id, - sub_discipline_id:this.state.sub_discipline_id, - tag_discipline_id:this.state.tag_discipline_id, - public: this.state.defaultActiveKey, - difficulty: this.state.difficulty, - item_type: this.state.item_type, - keywords: this.state.keywords, - page: this.state.page, - per_page:10, - exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), - }; - this.getdatasy(data); - this.getbasket_listdata(); - } - }).catch((error) => { - //console.log(error); - }) + } //全选试题库 selectallquestionsonthispage=()=>{ From 397265417ec7950e3eb29be6c32f7283291180b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Wed, 8 Jan 2020 16:15:09 +0800 Subject: [PATCH 025/156] =?UTF-8?q?=E8=B0=83=E6=95=B4=E8=AF=95=E5=8D=B7?= =?UTF-8?q?=E9=A2=98=E5=BA=93=E9=80=89=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/modules/question/NewMyShixunModel.js | 4 ++-- public/react/src/modules/question/Question.js | 4 ++-- .../question/component/ChoquesEditor.js | 2 +- .../question/component/JudquestionEditor.js | 2 +- .../src/modules/question/component/Listjihe.js | 18 +++++++++++------- 5 files changed, 17 insertions(+), 13 deletions(-) diff --git a/public/react/src/modules/question/NewMyShixunModel.js b/public/react/src/modules/question/NewMyShixunModel.js index bfb8f5690..b300156b7 100644 --- a/public/react/src/modules/question/NewMyShixunModel.js +++ b/public/react/src/modules/question/NewMyShixunModel.js @@ -34,7 +34,7 @@ class NewMyShixunModel extends Component { placement: 'right', modalsType: false, modalsTypes:false, - titilesm: "设为公开后,所有成员均可使用试题", + titilesm: "在平台审核后,所有成员均可使用试题", titiless: "是否设置为公开?", titilesms:"单选题", titbool: false, @@ -386,7 +386,7 @@ class NewMyShixunModel extends Component { this.setState({ modalsType: true, - titilesm: "设为公开后,所有成员均可使用试题", + titilesm: "在平台审核后,所有成员均可使用试题", titiless: "是否设置为公开?", titbool: true, timuid: id diff --git a/public/react/src/modules/question/Question.js b/public/react/src/modules/question/Question.js index 0d51f4972..3264c52fa 100644 --- a/public/react/src/modules/question/Question.js +++ b/public/react/src/modules/question/Question.js @@ -33,7 +33,7 @@ class Question extends Component { placement: 'right', modalsType: false, modalsTypes:false, - titilesm: "设为公开后,所有成员均可使用试题", + titilesm: "在平台审核后,所有成员均可使用试题", titiless: "是否设置为公开?", titilesms:"单选题", titbool: false, @@ -399,7 +399,7 @@ class Question extends Component { this.setState({ modalsType: true, - titilesm: "设为公开后,所有成员均可使用试题", + titilesm: "在平台审核后,所有成员均可使用试题", titiless: "是否设置为公开?", titbool: true, timuid: id diff --git a/public/react/src/modules/question/component/ChoquesEditor.js b/public/react/src/modules/question/component/ChoquesEditor.js index afb7f4b3a..c3412467d 100644 --- a/public/react/src/modules/question/component/ChoquesEditor.js +++ b/public/react/src/modules/question/component/ChoquesEditor.js @@ -310,7 +310,7 @@ class ChoquesEditor extends Component{ texts=value; } this.setState({ - question_titleysl:texts + question_titlesysl:texts }) } } diff --git a/public/react/src/modules/question/component/JudquestionEditor.js b/public/react/src/modules/question/component/JudquestionEditor.js index 3adba9e5c..08aa54955 100644 --- a/public/react/src/modules/question/component/JudquestionEditor.js +++ b/public/react/src/modules/question/component/JudquestionEditor.js @@ -322,7 +322,7 @@ class JudquestionEditor extends Component{ texts=value; } this.setState({ - question_titleysl:texts + question_titlesysl:texts }) } } diff --git a/public/react/src/modules/question/component/Listjihe.js b/public/react/src/modules/question/component/Listjihe.js index e793859cd..ecf75c1ff 100644 --- a/public/react/src/modules/question/component/Listjihe.js +++ b/public/react/src/modules/question/component/Listjihe.js @@ -7,7 +7,8 @@ import { Spin, Table, Pagination, - Radio + Radio, + Tooltip } from "antd"; import './../questioncss/questioncom.css'; import QuillForEditor from "../../../common/quillForEditor"; @@ -153,9 +154,9 @@ class Listjihe extends Component {
    { items.item_type==="PROGRAM"? - +
    - +
    :
    { items===undefined||items===null||items===""?"": @@ -283,10 +284,13 @@ class Listjihe extends Component { : items.item_type === "PROGRAM" ? items.program_attr.status === 0 ? -

    - - 选用 -

    + +

    + + 选用 +

    +
    + :

    this.Selectingpracticaltraining(items.id)}> From 9ff41434fb5640d07c79f2d24a1ef0280d252087 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Wed, 8 Jan 2020 16:23:09 +0800 Subject: [PATCH 026/156] =?UTF-8?q?=E9=A2=98=E5=B9=B2=20=E9=A2=98=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=20=E5=AD=97=E6=95=B0=E9=99=90=E5=88=B61000=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../react/src/modules/question/component/ChoquesEditor.js | 8 ++++---- .../src/modules/question/component/JudquestionEditor.js | 8 ++++---- .../react/src/modules/question/component/SingleEditor.js | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/public/react/src/modules/question/component/ChoquesEditor.js b/public/react/src/modules/question/component/ChoquesEditor.js index c3412467d..8113322fb 100644 --- a/public/react/src/modules/question/component/ChoquesEditor.js +++ b/public/react/src/modules/question/component/ChoquesEditor.js @@ -277,8 +277,8 @@ class ChoquesEditor extends Component{ } else { // 提交到后台的内容需要处理一下; var texts=""; - if(_text.length>=101){ - var result = _text.substring(0,100); + if(_text.length>=1001){ + var result = _text.substring(0,1000); texts={"ops":[{"insert":result}]}; texts=JSON.stringify(texts); }else { @@ -301,8 +301,8 @@ class ChoquesEditor extends Component{ } else { // 提交到后台的内容需要处理一下; var texts=""; - if(_text.length>=101){ - var result = _text.substring(0,100); + if(_text.length>=1001){ + var result = _text.substring(0,1000); texts={"ops":[{"insert":result}]}; texts=JSON.stringify(texts); }else { diff --git a/public/react/src/modules/question/component/JudquestionEditor.js b/public/react/src/modules/question/component/JudquestionEditor.js index 08aa54955..65a80b8ab 100644 --- a/public/react/src/modules/question/component/JudquestionEditor.js +++ b/public/react/src/modules/question/component/JudquestionEditor.js @@ -289,8 +289,8 @@ class JudquestionEditor extends Component{ } else { // 提交到后台的内容需要处理一下; var texts=""; - if(_text.length>=101){ - var result = _text.substring(0,100); + if(_text.length>=1001){ + var result = _text.substring(0,1000); texts={"ops":[{"insert":result}]}; texts=JSON.stringify(texts); }else { @@ -313,8 +313,8 @@ class JudquestionEditor extends Component{ } else { // 提交到后台的内容需要处理一下; var texts=""; - if(_text.length>=101){ - var result = _text.substring(0,100); + if(_text.length>=1001){ + var result = _text.substring(0,1000); texts={"ops":[{"insert":result}]}; texts=JSON.stringify(texts); }else { diff --git a/public/react/src/modules/question/component/SingleEditor.js b/public/react/src/modules/question/component/SingleEditor.js index bf2c27b36..d7a326714 100644 --- a/public/react/src/modules/question/component/SingleEditor.js +++ b/public/react/src/modules/question/component/SingleEditor.js @@ -296,8 +296,8 @@ class SingleEditor extends Component{ } else { // 提交到后台的内容需要处理一下; var texts=""; - if(_text.length>=101){ - var result = _text.substring(0,100); + if(_text.length>=1001){ + var result = _text.substring(0,1000); texts={"ops":[{"insert":result}]}; texts=JSON.stringify(texts); }else { @@ -319,8 +319,8 @@ class SingleEditor extends Component{ }) } else { var texts=""; - if(_text.length>=101){ - var result = _text.substring(0,100); + if(_text.length>=1001){ + var result = _text.substring(0,1000); texts={"ops":[{"insert":result}]}; texts=JSON.stringify(texts); }else { From 84afe73ec8934272bb75e5d4cd790b3863cda42e Mon Sep 17 00:00:00 2001 From: tangjiang <465264938@qq.com> Date: Wed, 8 Jan 2020 16:28:08 +0800 Subject: [PATCH 027/156] add quill editor --- .../courses/exercise/new/SingleEditor.js | 74 +++++++++++++++++-- 1 file changed, 68 insertions(+), 6 deletions(-) diff --git a/public/react/src/modules/courses/exercise/new/SingleEditor.js b/public/react/src/modules/courses/exercise/new/SingleEditor.js index 0b1b7599a..8585e0a82 100644 --- a/public/react/src/modules/courses/exercise/new/SingleEditor.js +++ b/public/react/src/modules/courses/exercise/new/SingleEditor.js @@ -8,8 +8,9 @@ import { import TPMMDEditor from '../../../tpm/challengesnew/TPMMDEditor'; import axios from 'axios' import update from 'immutability-helper' - import {getUrl, ActionBtn, DMDEditor, ConditionToolTip} from 'educoder'; +import QuillForEditor from "../../../../common/quillForEditor"; + const { TextArea } = Input; const confirm = Modal.confirm; const $ = window.$ @@ -47,6 +48,9 @@ class SingleEditor extends Component{ question_title: this.props.question_title || '', question_type: this.props.question_type || 0, question_score: this.props.question_score || this.props.init_question_score, + choice_editor: 'md', + quill_question_title: '', + quill_default_title: '' } } addOption = () => { @@ -205,8 +209,33 @@ class SingleEditor extends Component{ toShowMode = () => { } + + // 切换编辑器 + handleChangeEditor = (e) => { + const {quill_question_title} = this.state; + const value = e.target.value + if (value === 'quill') { + const _val = quill_question_title ? JSON.parse(quill_question_title) : ''; + this.setState({ + quill_default_title: _val + }) + } + this.setState({ + choice_editor: value + }); + } + + // quill编辑器内容变化时调用此接口 + handleCtxChange = (ctx) => { + console.log('编辑器内容', ctx); + // 保存编辑器内容 + this.setState({ + quill_question_title: JSON.stringify(ctx) + }); + } + render() { - let { question_title, question_score, question_type, question_choices, standard_answers } = this.state; + let { question_title, question_score, question_type, question_choices, standard_answers, choice_editor, quill_default_title } = this.state; let { question_id, index, exerciseIsPublish, // question_title, // question_type, @@ -245,18 +274,51 @@ class SingleEditor extends Component{ max-width: 1056px; word-break:break-all; } + .editor_area{ + display: inline-block; + float: right; + // line-height: 30px; + // height: 30px; + } + .editor_txt{ + margin-right: 10px; + font-size: 12px; + color: #999; + } + .radio_style{ + display: inline-block; + vertical: center; + } `}

    {/* {!question_id ? '新建' : '编辑'} */} 选择题 (客观题,由系统自动评分,请设置标准答案) + {/* */} + {/*

    + 切换编辑器: + + MD + Quill + +
    */}

    - this.setState({ question_title: val})} - ref="titleEditor" + {choice_editor === 'md' + ? this.setState({ question_title: val})} + ref="titleEditor" + > - > + : + } {question_choices.map( (item, index) => { const bg = standard_answers[index] ? 'check-option-bg' : '' From 598c2385e8153b0f9263b3d2097abb735cd5d459 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Wed, 8 Jan 2020 16:40:06 +0800 Subject: [PATCH 028/156] =?UTF-8?q?=E5=AD=97=E6=95=B0=E9=99=90=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/react/src/modules/question/component/ChoquesEditor.js | 4 ++-- public/react/src/modules/question/component/SingleEditor.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/public/react/src/modules/question/component/ChoquesEditor.js b/public/react/src/modules/question/component/ChoquesEditor.js index 8113322fb..1dc35ef4c 100644 --- a/public/react/src/modules/question/component/ChoquesEditor.js +++ b/public/react/src/modules/question/component/ChoquesEditor.js @@ -234,8 +234,8 @@ class ChoquesEditor extends Component{ // 处理编辑器内容为空 texts=""; } else { - if(_text.length>=101){ - var result = _text.substring(0,100); + if(_text.length>=301){ + var result = _text.substring(0,300); texts={"ops":[{"insert":result}]}; texts=JSON.stringify(texts); }else { diff --git a/public/react/src/modules/question/component/SingleEditor.js b/public/react/src/modules/question/component/SingleEditor.js index d7a326714..0b0a8b5f7 100644 --- a/public/react/src/modules/question/component/SingleEditor.js +++ b/public/react/src/modules/question/component/SingleEditor.js @@ -255,8 +255,8 @@ class SingleEditor extends Component{ // 处理编辑器内容为空 texts=""; } else { - if(_text.length>=101){ - var result = _text.substring(0,100); + if(_text.length>=301){ + var result = _text.substring(0,300); texts={"ops":[{"insert":result}]}; texts=JSON.stringify(texts); }else { From 9f6e038a3a14865256d0b558cbf61acd03e8731b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Wed, 8 Jan 2020 17:02:52 +0800 Subject: [PATCH 029/156] =?UTF-8?q?=E9=A2=98=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../react/src/modules/question/component/Itembankstop.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/public/react/src/modules/question/component/Itembankstop.js b/public/react/src/modules/question/component/Itembankstop.js index 5192eca4e..581baf844 100644 --- a/public/react/src/modules/question/component/Itembankstop.js +++ b/public/react/src/modules/question/component/Itembankstop.js @@ -413,6 +413,10 @@ class Itembankstop extends Component { } NewknTypedeldel=(bool)=>{ + if(this.state.rbkc===undefined || this.state.rbkc===null || this.state.rbkc===""){ + this.props.showNotification(`请选择课程方向`); + return; + } this.setState({ NewknTypedel:bool }) @@ -431,10 +435,6 @@ class Itembankstop extends Component { return } - if(this.state.rbkc===undefined || this.state.rbkc===null || this.state.rbkc===""){ - this.props.showNotification(`请选择课程方向`); - return; - } var data={ name:value, sub_discipline_id:this.state.rbkc[1] From d206e1c37ee0cbd39db6d0dc2f289e66db5fb8df Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Wed, 8 Jan 2020 18:56:00 +0800 Subject: [PATCH 030/156] =?UTF-8?q?=E6=99=BA=E8=83=BD=E7=BB=84=E5=8D=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ination_intelligent_settings_controller.rb | 85 +++++++++++++++++-- app/controllers/item_banks_controller.rb | 9 +- app/controllers/item_baskets_controller.rb | 35 +++++--- .../save_exam_setting_form.rb | 11 +++ app/forms/item_banks/save_item_form.rb | 4 +- app/models/examination_intelligent_setting.rb | 3 + app/models/examination_type_setting.rb | 1 + app/models/item_basket.rb | 11 +-- app/models/user.rb | 2 + app/queries/optional_item_query.rb | 37 ++++---- .../save_setting_service.rb | 63 ++++++++++++++ .../item_baskets/save_item_basket_service.rb | 24 ++++-- config/routes.rb | 5 ++ ...930_add_user_id_to_intelligent_settings.rb | 5 ++ ..._intelligent_setting_id_to_item_baskets.rb | 5 ++ 15 files changed, 247 insertions(+), 53 deletions(-) create mode 100644 app/forms/examination_intelligent_settings/save_exam_setting_form.rb create mode 100644 app/services/examination_intelligent_settings/save_setting_service.rb create mode 100644 db/migrate/20200108030930_add_user_id_to_intelligent_settings.rb create mode 100644 db/migrate/20200108061139_add_intelligent_setting_id_to_item_baskets.rb diff --git a/app/controllers/examination_intelligent_settings_controller.rb b/app/controllers/examination_intelligent_settings_controller.rb index 8a69a5c70..13d412da8 100644 --- a/app/controllers/examination_intelligent_settings_controller.rb +++ b/app/controllers/examination_intelligent_settings_controller.rb @@ -1,14 +1,89 @@ class ExaminationIntelligentSettingsController < ApplicationController + before_action :require_login + before_action :find_exam, only: [:exchange_one_item, :exchange_items] def optinal_items - items = OptionalItemQuery.call(params) - @single_question_count = items[:single_question_count] - @multiple_question_count = items[:multiple_question_count] - @judgement_question_count = items[:judgement_question_count] - @program_question_count = items[:program_question_count] + sub_discipline_id = params[:sub_discipline_id] + tag_discipline_id = params[:tag_discipline_id] + difficulty = params[:difficulty] + source = params[:source] + + items = OptionalItemQuery.call(sub_discipline_id, tag_discipline_id, difficulty, source) + @single_question_count = items.select{ |item| item.item_type == "SINGLE" }.size + @multiple_question_count = items.select{ |item| item.item_type == "MULTIPLE" }.size + @judgement_question_count = items.select{ |item| item.item_type == "JUDGMENT" }.size + @program_question_count = items.select{ |item| item.item_type == "PROGRAM" }.size end def create + ActiveRecord::Base.transaction do + exam = ExaminationIntelligentSetting.new(user: current_user) + # 保存试卷基础信息 + exam = ExaminationIntelligentSettings::SaveSettingService.call(exam, form_params) + render_ok({exam_setting_id: exam.id}) + end + rescue ApplicationService::Error => ex + render_error(ex.message) + end + + def exchange_one_item + item = @exam.item_baskets.find_by!(id: params[:item_id]) + exam_type_setting = @exam.examination_type_settings.find_by!(item_type: item.item_type) + + # 获取可选的题 + items = OptionalItemQuery.call(@exam.sub_discipline_id, @exam.tag_discipline_containers.pluck(:tag_discipline_id), @exam.difficulty, @exam.public) + type_items = items.select{ |t_item| t_item.item_type == item.item_type } + # 如果可选的题数小于等于设置的题数则提示无可换的题 + tip_exception("无可换的题") if type_items.size <= exam_type_setting.count + # 可选题中去掉已组卷的同题型试题 + optional_item_ids = type_items.pluck(:id) - @exam.item_baskets.where(item_type: item.item_type).pluck(:item_bank_id) + new_item = ItemBank.find optional_item_ids.sample(1).first + ActiveRecord::Base.transaction do + @exam.item_baskets << ItemBasket.new(item_bank_id: new_item.id, position: item.position, score: item.score, item_type: new_item.item_type) + item.destroy! + end + render_ok + end + + def exchange_items + exam_type_setting = @exam.examination_type_settings.find_by!(item_type: params[:item_type]) + choosed_items = @exam.item_baskets.where(item_type: params[:item_type]) + + # 获取可选的题 + items = OptionalItemQuery.call(@exam.sub_discipline_id, @exam.tag_discipline_containers.pluck(:tag_discipline_id), @exam.difficulty, @exam.public) + type_items = items.select{ |t_item| t_item.item_type == params[:item_type] } + # 如果可选的题数小于等于设置的题数则提示无可换的题 + tip_exception("无可换的题") if type_items.size <= exam_type_setting.count + # 可选题中去掉已组卷的同题型试题 + choosed_item_ids = choosed_items.pluck(:item_bank_id) + optional_item_ids = type_items.pluck(:id) - choosed_item_ids + + # 如果可选题数小于设置的题数n,则在原来的选题中随机选n个,确保换题时能选到新的题 + if optional_item_ids.size < exam_type_setting.count + absence_count = exam_type_setting.count - optional_item_ids.size + optional_item_ids = optional_item_ids + choosed_item_ids.sample(absence_count) + end + + ActiveRecord::Base.transaction do + # 取试题分数 + score = choosed_items.first&.score || (params[:item_type] == "PROGRAM" ? 10 : 5) + choosed_items.destroy_all + optional_item_ids.sample(exam_type_setting.count).each_with_index do |item_id, index| + new_item = ItemBank.find item_id + @exam.item_baskets << ItemBasket.new(item_bank_id: new_item.id, position: index+1, score: score, item_type: new_item.item_type) + end + end + render_ok + end + + private + + def find_exam + @exam = ExaminationIntelligentSetting.find_by!(id: params[:id]) + tip_exception(403,"无权限编辑") unless current_user.admin_or_business? || @exam.user_id == current_user.id + end + def form_params + params.permit(:discipline_id, :sub_discipline_id, :difficulty, :source, tag_discipline_id: [], question_settings: %i[item_type count]) end end \ No newline at end of file diff --git a/app/controllers/item_banks_controller.rb b/app/controllers/item_banks_controller.rb index 24d9c44a9..10dd10e07 100644 --- a/app/controllers/item_banks_controller.rb +++ b/app/controllers/item_banks_controller.rb @@ -9,7 +9,14 @@ class ItemBanksController < ApplicationController @items_count = items.size @items = paginate items.includes(:item_analysis, :user, :container) exam = ExaminationBank.find_by(id: params[:exam_id]) if params[:exam_id].present? - @item_basket_ids = exam ? exam.examination_items.pluck(:item_bank_id) : current_user.item_baskets.pluck(:item_bank_id) + exam_setting = ExaminationIntelligentSetting.find_by(id: params[:exam_setting_id]) if params[:exam_setting_id].present? + @item_basket_ids = if exam + exam.examination_items.pluck(:item_bank_id) + elsif exam_setting + exam_setting.item_baskets.pluck(:item_bank_id) + else + current_user.item_baskets.pluck(:item_bank_id) + end end def create diff --git a/app/controllers/item_baskets_controller.rb b/app/controllers/item_baskets_controller.rb index 21203346b..dc5367378 100644 --- a/app/controllers/item_baskets_controller.rb +++ b/app/controllers/item_baskets_controller.rb @@ -4,7 +4,7 @@ class ItemBasketsController < ApplicationController helper_method :current_basket def index - @item_baskets = current_user.item_baskets + @item_baskets = basket_items @single_questions = @item_baskets.where(item_type: "SINGLE") @multiple_questions = @item_baskets.where(item_type: "MULTIPLE") @judgement_questions = @item_baskets.where(item_type: "JUDGMENT") @@ -22,41 +22,41 @@ class ItemBasketsController < ApplicationController end def create - ItemBaskets::SaveItemBasketService.call(current_user, create_params) + ItemBaskets::SaveItemBasketService.call(current_user, create_params, exam_setting) render_ok rescue ApplicationService::Error => ex render_error(ex.message) end def destroy - item = current_user.item_baskets.find_by!(item_bank_id: params[:id]) + item = basket_items.find_by!(item_bank_id: params[:id]) ActiveRecord::Base.transaction do - current_user.item_baskets.where(item_type: item.item_type).where("position > #{item.position}").update_all("position = position -1") + basket_items.where(item_type: item.item_type).where("position > #{item.position}").update_all("position = position -1") item.destroy! end render_ok end def delete_item_type - baskets = ItemBasket.where(item_type: params[:item_type]) + baskets = basket_items.where(item_type: params[:item_type]) baskets.destroy_all render_ok end def set_score current_basket.update_attributes!(score: params[:score]) - @questions_score = current_user.item_baskets.where(item_type: current_basket.item_type).pluck(:score).sum - @all_score = current_user.item_baskets.pluck(:score).sum + @questions_score = basket_items.where(item_type: current_basket.item_type).pluck(:score).sum + @all_score = basket_items.pluck(:score).sum end def batch_set_score - current_user.item_baskets.where(item_type: params[:item_type]).update_all(score: params[:score]) - @questions_score = current_user.item_baskets.where(item_type: params[:item_type]).pluck(:score).sum - @all_score = current_user.item_baskets.pluck(:score).sum + basket_items.where(item_type: params[:item_type]).update_all(score: params[:score]) + @questions_score = basket_items.where(item_type: params[:item_type]).pluck(:score).sum + @all_score = basket_items.pluck(:score).sum end def adjust_position - same_items = current_user.item_baskets.where(item_type: current_basket.item_type) + same_items = basket_items.where(item_type: current_basket.item_type) max_position = same_items.size tip_exception("position超出范围") unless params[:position].present? && params[:position].to_i <= max_position && params[:position].to_i >= 1 ActiveRecord::Base.transaction do @@ -79,8 +79,19 @@ class ItemBasketsController < ApplicationController params.permit(item_ids: []) end + def exam_setting + @_exam_setting = ExaminationIntelligentSetting.find_by(id: params[:exam_setting_id]) + end + + def basket_items + @_items = params[:exam_setting_id] ? exam_setting.item_baskets : current_user.item_baskets + end + def current_basket - @_current_basket = current_user.item_baskets.find_by!(id: params[:id]) + @_current_basket = ItemBasket.find_by!(id: params[:id]) + tip_exception(403, "无权限编辑") unless current_user.admin_or_business? || @_current_basket.user_id.to_i == current_user.id || + @_current_basket.examination_intelligent_setting&.user_id.to_i == current_user.id + @_current_basket end def validate_score diff --git a/app/forms/examination_intelligent_settings/save_exam_setting_form.rb b/app/forms/examination_intelligent_settings/save_exam_setting_form.rb new file mode 100644 index 000000000..bbfb9eee8 --- /dev/null +++ b/app/forms/examination_intelligent_settings/save_exam_setting_form.rb @@ -0,0 +1,11 @@ +class ExaminationIntelligentSettings::SaveExamSettingForm + include ActiveModel::Model + + attr_accessor :discipline_id, :sub_discipline_id, :source, :difficulty, :tag_discipline_id, :question_settings + + validates :discipline_id, presence: true + validates :sub_discipline_id, presence: true + validates :source, presence: true + validates :difficulty, presence: true, inclusion: {in: 1..3}, numericality: { only_integer: true } + validates :question_settings, presence: true +end \ No newline at end of file diff --git a/app/forms/item_banks/save_item_form.rb b/app/forms/item_banks/save_item_form.rb index 7e788067e..d6d3a3e28 100644 --- a/app/forms/item_banks/save_item_form.rb +++ b/app/forms/item_banks/save_item_form.rb @@ -15,9 +15,9 @@ class ItemBanks::SaveItemForm return unless errors.blank? choices.each { |item| SubForm.new(item).validate! } if %W(SINGLE MULTIPLE JUDGMENT).include?(item_type) return unless errors.blank? - if [0, 2].include?(item_type) && choices.pluck(:is_answer).select{|item| item == 1}.length > 1 + if ["SINGLE", "JUDGMENT"].include?(item_type) && choices.pluck(:is_answer).select{|item| item == 1}.length > 1 raise("正确答案只能有一个") - elsif item_type == 1 && choices.pluck(:is_answer).select{|item| item == 1}.length <= 1 + elsif item_type == "MULTIPLE" && choices.pluck(:is_answer).select{|item| item == 1}.length <= 1 raise("多选题至少有两个正确答案") end end diff --git a/app/models/examination_intelligent_setting.rb b/app/models/examination_intelligent_setting.rb index 16dd88300..38c7fbe4b 100644 --- a/app/models/examination_intelligent_setting.rb +++ b/app/models/examination_intelligent_setting.rb @@ -1,4 +1,7 @@ class ExaminationIntelligentSetting < ApplicationRecord belongs_to :sub_discipline + belongs_to :user has_many :examination_type_settings, dependent: :destroy + has_many :tag_discipline_containers, as: :container, dependent: :destroy + has_many :item_baskets, dependent: :destroy end diff --git a/app/models/examination_type_setting.rb b/app/models/examination_type_setting.rb index c985e578e..30f3e80b4 100644 --- a/app/models/examination_type_setting.rb +++ b/app/models/examination_type_setting.rb @@ -1,3 +1,4 @@ class ExaminationTypeSetting < ApplicationRecord + enum item_type: { SINGLE: 0, MULTIPLE: 1, JUDGMENT: 2, COMPLETION: 3, SUBJECTIVE: 4, PRACTICAL: 5, PROGRAM: 6 } belongs_to :examination_intelligent_setting end diff --git a/app/models/item_basket.rb b/app/models/item_basket.rb index a3ff865ba..eb849d403 100644 --- a/app/models/item_basket.rb +++ b/app/models/item_basket.rb @@ -2,13 +2,6 @@ class ItemBasket < ApplicationRecord enum item_type: { SINGLE: 0, MULTIPLE: 1, JUDGMENT: 2, COMPLETION: 3, SUBJECTIVE: 4, PRACTICAL: 5, PROGRAM: 6 } belongs_to :item_bank - belongs_to :user - - def all_score - User.current.item_baskets.map(&:score).sum - end - - def question_count - User.current.item_baskets.size - end + belongs_to :user, optional: true + belongs_to :examination_intelligent_setting, optional: true end diff --git a/app/models/user.rb b/app/models/user.rb index 54aa8d85e..34be9615e 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -156,6 +156,8 @@ class User < ApplicationRecord # 题库 has_many :item_banks, dependent: :destroy has_many :item_baskets, -> { order("item_baskets.position ASC") }, dependent: :destroy + has_many :examination_banks, dependent: :destroy + has_many :examination_intelligent_settings, dependent: :destroy # Groups and active users scope :active, lambda { where(status: STATUS_ACTIVE) } diff --git a/app/queries/optional_item_query.rb b/app/queries/optional_item_query.rb index 456a74c6a..54cd0eed0 100644 --- a/app/queries/optional_item_query.rb +++ b/app/queries/optional_item_query.rb @@ -1,32 +1,35 @@ class OptionalItemQuery < ApplicationQuery - attr_reader :params + attr_reader :sub_discipline_id, :tag_discipline_id, :difficulty, :source - def initialize(params) - @params = params + def initialize(sub_discipline_id, tag_discipline_id, difficulty, source) + @sub_discipline_id = sub_discipline_id + @tag_discipline_id = tag_discipline_id + @difficulty = difficulty + @source = source end def call items = ItemBank.all - if params[:tag_discipline_id].present? && params[:sub_discipline_id].present? - items = items.joins(:tag_discipline_containers).where(tag_discipline_containers: {tag_discipline_id: params[:tag_discipline_id]}) - hacks = Hack.joins(:tag_discipline_containers).where(tag_discipline_containers: {tag_discipline_id: params[:tag_discipline_id]}) - elsif params[:sub_discipline_id].present? - items = items.where(sub_discipline_id: params[:sub_discipline_id]) - hacks = Hack.where(sub_discipline_id: params[:sub_discipline_id]) + if tag_discipline_id.present? && sub_discipline_id.present? + items = items.joins(:tag_discipline_containers).where(tag_discipline_containers: {tag_discipline_id: tag_discipline_id}) + hacks = Hack.joins(:tag_discipline_containers).where(tag_discipline_containers: {tag_discipline_id: tag_discipline_id}) + elsif sub_discipline_id.present? + items = items.where(sub_discipline_id: sub_discipline_id) + hacks = Hack.where(sub_discipline_id: sub_discipline_id) + end + + if hacks.present? + items = ItemBank.where(container_id: hacks.pluck(:id), container_type: "Hack").or(ItemBank.where(id: items.pluck(:id))) end # 来源 - source = params[:source].present? ? params[:source].to_i : 1 - public = source == 3 ? [0, 1] : source + public = source.present? ? source.to_i : 1 + public = public == 2 ? [0, 1] : public items = items.where(public: public) # 难度 - difficulty = params[:difficulty] ? params[:difficulty].to_i : 1 + difficulty = difficulty ? difficulty.to_i : 1 items = items.where(difficulty: difficulty) - single_question_count = items.select{ |item| item.item_type == "SINGLE" }.size - multiple_question_count = items.select{ |item| item.item_type == "MULTIPLE" }.size - judgement_question_count = items.select{ |item| item.item_type == "JUDGMENT" }.size - program_question_count = hacks.present? ? hacks.pluck(:item_bank_id).reject(&:blank?).size : items.select{ |item| item.item_type == "PROGRAM" }.size - {single_question_count: single_question_count, multiple_question_count: multiple_question_count, judgement_question_count: judgement_question_count, program_question_count: program_question_count} + items end end \ No newline at end of file diff --git a/app/services/examination_intelligent_settings/save_setting_service.rb b/app/services/examination_intelligent_settings/save_setting_service.rb new file mode 100644 index 000000000..af22b3234 --- /dev/null +++ b/app/services/examination_intelligent_settings/save_setting_service.rb @@ -0,0 +1,63 @@ +class ExaminationIntelligentSettings::SaveSettingService < ApplicationService + attr_reader :exam, :params + + def initialize(exam, params) + @exam = exam + @params = params + end + + def call + ExaminationIntelligentSettings::SaveExamSettingForm.new(params).validate! + items = OptionalItemQuery.call(params[:sub_discipline_id], params[:tag_discipline_id], params[:difficulty], params[:source]) + params[:question_settings].each do |setting| + raise "超出可选题数范围" if items.select{ |item| item.item_type == setting[:item_type] }.size.to_i < setting[:count].to_i + end + + exam.difficulty = params[:difficulty] + exam.sub_discipline_id = params[:sub_discipline_id] + exam.public = params[:source].present? ? params[:source].to_i : 1 + exam.save! + + # 知识点的创建 + params[:tag_discipline_id].each do |tag_id| + exam.tag_discipline_containers << TagDisciplineContainer.new(tag_discipline_id: tag_id) + end + + # 智能选题的设置 + params[:question_settings].each do |setting| + if setting[:count].to_i > 0 + exam.examination_type_settings << ExaminationTypeSetting.new(item_type: setting[:item_type], count: setting[:count].to_i) + end + end + + # 选题 + choose_question items + + exam + end + + private + + def choose_question items + exam.examination_type_settings.each do |setting| + questions = items.select{ |item| item.item_type == setting.item_type } + questions.pluck(:id).sample(setting.count).each_with_index do |item_id, index| + item = ItemBank.find item_id + exam.item_baskets << ItemBasket.new(item_bank_id: item.id, position: index+1, score: item_score(item.item_type), item_type: item.item_type) + end + end + end + + def item_score item_type + score = + case item_type + when "SINGLE", "MULTIPLE", "JUDGMENT" + 5 + when "PROGRAM" + 10 + else + 5 + end + score + end +end \ No newline at end of file diff --git a/app/services/item_baskets/save_item_basket_service.rb b/app/services/item_baskets/save_item_basket_service.rb index cf6d3738b..debc7e2ed 100644 --- a/app/services/item_baskets/save_item_basket_service.rb +++ b/app/services/item_baskets/save_item_basket_service.rb @@ -1,9 +1,10 @@ class ItemBaskets::SaveItemBasketService < ApplicationService - attr_reader :user, :params + attr_reader :user, :params, :exam_setting - def initialize(user, params) + def initialize(user, params, exam_setting) @user = user @params = params + @exam_setting = exam_setting end def call @@ -13,9 +14,14 @@ class ItemBaskets::SaveItemBasketService < ApplicationService items = ItemBank.where(public: 1).or(ItemBank.where(user_id: user.id)) # 已选到过试题篮的不重复选用 - item_ids = params[:item_ids] - user.item_baskets.pluck(:item_bank_id) + item_ids = params[:item_ids] - basket_items.pluck(:item_bank_id) items.where(id: item_ids).each do |item| - new_item = ItemBasket.new(user_id: user.id, item_bank_id: item.id, item_type: item.item_type) + new_item = ItemBasket.new(item_bank_id: item.id, item_type: item.item_type) + if exam_setting.present? + new_item.examination_intelligent_setting_id = exam_setting.id + else + new_item.user_id = user.id + end new_item.score = item_score item.item_type new_item.position = item_position item.item_type new_item.save! @@ -25,8 +31,8 @@ class ItemBaskets::SaveItemBasketService < ApplicationService private def item_score item_type - if user.item_baskets.where(item_type: item_type).last.present? - score = user.item_baskets.where(item_type: item_type).last.score + if basket_items.where(item_type: item_type).last.present? + score = basket_items.where(item_type: item_type).last.score else score = case item_type @@ -42,6 +48,10 @@ class ItemBaskets::SaveItemBasketService < ApplicationService end def item_position item_type - user.item_baskets.where(item_type: item_type).last&.position.to_i + 1 + basket_items.where(item_type: item_type).last&.position.to_i + 1 + end + + def basket_items + exam_setting.present? ? exam_setting.item_baskets : user.item_baskets end end \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 198dbc39f..225909f8e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -100,6 +100,11 @@ Rails.application.routes.draw do collection do get :optinal_items end + + member do + post :exchange_one_item + post :exchange_items + end end resources :hacks, path: :problems, param: :identifier do diff --git a/db/migrate/20200108030930_add_user_id_to_intelligent_settings.rb b/db/migrate/20200108030930_add_user_id_to_intelligent_settings.rb new file mode 100644 index 000000000..83d3b96b4 --- /dev/null +++ b/db/migrate/20200108030930_add_user_id_to_intelligent_settings.rb @@ -0,0 +1,5 @@ +class AddUserIdToIntelligentSettings < ActiveRecord::Migration[5.2] + def change + add_column :examination_intelligent_settings, :user_id, :integer, index: true + end +end diff --git a/db/migrate/20200108061139_add_intelligent_setting_id_to_item_baskets.rb b/db/migrate/20200108061139_add_intelligent_setting_id_to_item_baskets.rb new file mode 100644 index 000000000..9de17ee48 --- /dev/null +++ b/db/migrate/20200108061139_add_intelligent_setting_id_to_item_baskets.rb @@ -0,0 +1,5 @@ +class AddIntelligentSettingIdToItemBaskets < ActiveRecord::Migration[5.2] + def change + add_column :item_baskets, :examination_intelligent_setting_id, :integer, index: true + end +end From e80f11ccf0bae136a2fc40e0483ce1c416d72cd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Wed, 8 Jan 2020 20:15:33 +0800 Subject: [PATCH 031/156] =?UTF-8?q?=E8=B0=83=E6=95=B4=E9=A2=98=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/react/src/modules/question/component/SingleEditor.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/react/src/modules/question/component/SingleEditor.js b/public/react/src/modules/question/component/SingleEditor.js index 0b0a8b5f7..fa20afb83 100644 --- a/public/react/src/modules/question/component/SingleEditor.js +++ b/public/react/src/modules/question/component/SingleEditor.js @@ -410,7 +410,7 @@ class SingleEditor extends Component{ {/* */} this.onOptionClick(index)} style={{flex: '0 0 38px'}}> - +
    {tagArray[index]}
    From e98c3350ad9ad7dcebf8b1413b62b157dea61cab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Thu, 9 Jan 2020 09:30:47 +0800 Subject: [PATCH 032/156] =?UTF-8?q?=E9=A2=98=E5=BA=93=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../question/component/ChoquesEditor.js | 16 ++- .../modules/question/component/Contentpart.js | 44 ++++++- .../question/component/Headplugselections.js | 2 +- .../question/component/Itembankstop.js | 119 +++++++++++++++++- .../question/component/Newknledpots.js | 25 +++- .../question/component/SingleEditor.js | 17 +-- .../question/questioncss/questioncom.css | 9 +- 7 files changed, 204 insertions(+), 28 deletions(-) diff --git a/public/react/src/modules/question/component/ChoquesEditor.js b/public/react/src/modules/question/component/ChoquesEditor.js index 1dc35ef4c..e3bb1b268 100644 --- a/public/react/src/modules/question/component/ChoquesEditor.js +++ b/public/react/src/modules/question/component/ChoquesEditor.js @@ -134,23 +134,21 @@ class ChoquesEditor extends Component{ this.props.showNotification('请您输入题干'); return editordata; } + + for(let i = 0; i < question_choices.length; i++) { + if (!question_choices[i]) { + this.props.showNotification(`请先输入 ${tagArray[i]} 选项的内容`); + return editordata; + } + } if(!answerArray || answerArray.length == 0) { this.props.showNotification('请先点击选择本选择题的正确选项'); return editordata; } - if(!answerArray || answerArray.length < 2) { this.props.showNotification('多选题最小正确选项为2个'); return editordata; } - - for(let i = 0; i < question_choices.length; i++) { - if (!question_choices[i]) { - this.props.showNotification(`请先输入 ${tagArray[i]} 选项的内容`); - return editordata; - } - } - if(!question_titlesysl) { this.props.showNotification('请您输入题目解析'); return editordata; diff --git a/public/react/src/modules/question/component/Contentpart.js b/public/react/src/modules/question/component/Contentpart.js index d92a1e8e7..da85ce0f7 100644 --- a/public/react/src/modules/question/component/Contentpart.js +++ b/public/react/src/modules/question/component/Contentpart.js @@ -37,6 +37,48 @@ class Contentpart extends Component { this.props.chakanjiexibool(index); } + xinzenw=(e)=>{ + var urls="?"; + if(this.props.discipline_id){ + if(urls==="?"){ + urls=urls+`discipline_id=${this.props.discipline_id}` + }else { + urls=urls+`&discipline_id=${this.props.discipline_id}` + } + } + if(this.props.sub_discipline_id){ + if(urls==="?"){ + urls=urls+`sub_discipline_id=${this.props.sub_discipline_id}` + }else { + urls=urls+`&sub_discipline_id=${this.props.sub_discipline_id}` + } + } + if(this.props.tag_discipline_id){ + if(urls==="?"){ + urls=urls+`sub_discipline_id=${this.props.tag_discipline_id}` + }else { + urls=urls+`&sub_discipline_id=${this.props.tag_discipline_id}` + } + } + if(this.props.difficulty){ + if(urls==="?"){ + urls=urls+`difficulty=${this.props.difficulty}&` + }else { + urls=urls+`&difficulty=${this.props.difficulty}` + } + } + if(this.props.item_type){ + if(urls==="?"){ + urls=urls+`item_type=${this.props.item_type}` + }else { + urls=urls+`&item_type=${this.props.item_type}` + } + + } + + + this.props.history.push("/question/newitem"+urls); + } render() { let {page}=this.state; let {defaultActiveKey,item_type,booljupyterurls}=this.props; @@ -139,7 +181,7 @@ class Contentpart extends Component {
    { defaultActiveKey===0||defaultActiveKey==="0"? - + this.xinzenw(e)}>

    新增

    diff --git a/public/react/src/modules/question/component/Headplugselections.js b/public/react/src/modules/question/component/Headplugselections.js index 3cff40cc2..206b556e9 100644 --- a/public/react/src/modules/question/component/Headplugselections.js +++ b/public/react/src/modules/question/component/Headplugselections.js @@ -153,7 +153,7 @@ class Headplugselections extends Component { { item&&item.map((list,k)=>{ return( - +
    diff --git a/public/react/src/modules/question/component/Itembankstop.js b/public/react/src/modules/question/component/Itembankstop.js index 581baf844..576dbb42d 100644 --- a/public/react/src/modules/question/component/Itembankstop.js +++ b/public/react/src/modules/question/component/Itembankstop.js @@ -19,6 +19,8 @@ import './../questioncss/questioncom.css'; import Newknledpots from './Newknledpots' const InputGroup = Input.Group; const {Option} = Select; +const queryString = require('query-string'); + const options = [ { value: '方向', @@ -59,6 +61,8 @@ class Itembankstop extends Component { //初始化 componentDidMount() { + + try { this.props.getcontentMdRef(this); } catch (e) { @@ -68,7 +72,53 @@ class Itembankstop extends Component { options: this.props.disciplmy, }) + console.log("数据"); + console.log(this.props); + const parsed = queryString.parse(this.props.location.search); + console.log(parsed); + try { + if(JSON.stringify(parsed)==={}||JSON.stringify(parsed)==="{}"){ + + }else { + if(parsed.discipline_id){ + if(parsed.sub_discipline_id){ + this.setState({ + rbkc:[parseInt(parsed.discipline_id),parseInt(parsed.sub_discipline_id)] + }) + this.props.form.setFieldsValue({ + rbkc: [parseInt(parsed.discipline_id),parseInt(parsed.sub_discipline_id)], + }); + this.getdatasmyss(parseInt(parsed.discipline_id),parseInt(parsed.sub_discipline_id)); + + } + + } + if(parsed.item_type){ + this.setState({ + rbtx:parsed.item_type, + }) + this.props.form.setFieldsValue({ + rbtx:parsed.item_type, + }); + this.props.setitem_type(parsed.item_type); + } + + if(parsed.difficulty){ + this.setState({ + rbnd:parsed.difficulty, + }) + this.props.form.setFieldsValue({ + rbnd:parsed.difficulty, + }); + } + + + } + + }catch (e) { + + } } componentDidUpdate(prevProps) { @@ -79,6 +129,7 @@ class Itembankstop extends Component { }) } if(prevProps.disciplinesdata!== this.props.disciplinesdata){ + console.log("新增开始加载了") try { if(this.props.item_banksedit.discipline &&this.props.item_banksedit.sub_discipline){ const didata = this.props.disciplinesdata; @@ -110,6 +161,27 @@ class Itembankstop extends Component { knowledgepoints2: _result, }) } + + + try { + const parsed = queryString.parse(this.props.location.search); + if(JSON.stringify(parsed)==={}||JSON.stringify(parsed)==="{}"){ + + }else { + if(parsed.discipline_id){ + if(parsed.sub_discipline_id){ + this.setState({ + rbkc:[parseInt(parsed.discipline_id),parseInt(parsed.sub_discipline_id)] + }) + this.props.form.setFieldsValue({ + rbkc: [parseInt(parsed.discipline_id),parseInt(parsed.sub_discipline_id)], + }); + this.getdatasmyss(parseInt(parsed.discipline_id),parseInt(parsed.sub_discipline_id)); + } + } + } + }catch (e) { + } }catch (e) { } } @@ -125,6 +197,7 @@ class Itembankstop extends Component { this.handletag_disciplinesChange(this.props.item_banksedit.tag_disciplines); } try { + //初始化课程 this.handdisciplinesChange(this.props.item_banksedit.discipline,this.props.item_banksedit.sub_discipline); }catch (e) { @@ -175,7 +248,42 @@ class Itembankstop extends Component { } } } + getdatasmyss=(id,ids)=>{ + if(this.props.disciplinesdata){ + try { + if(id &&ids){ + var didata = this.props.disciplinesdata; + var knowledgepointsdata = []; + for (var i = 0; i < didata.length; i++) { + //方向 + if (id === didata[i].id) { + const fxdidata = didata[i].sub_disciplines; + for (var j = 0; j < fxdidata.length; j++) { + //课程 + if (ids === fxdidata[j].id) { + const zsddata = fxdidata[j].tag_disciplines; + for (var k = 0; k < zsddata.length; k++) { + //知识点 + knowledgepointsdata.push(zsddata[k]); + } + } + } + } + } + + + this.setState({ + knowledgepoints:knowledgepointsdata, + knowledgepoints2: knowledgepointsdata, + }) + }else{ + } + }catch (e) { + + } + } + } handdisciplinesChange =(name,title)=>{ this.setState({ rbkc:[name.id,title.id] @@ -476,6 +584,11 @@ class Itembankstop extends Component { let {page, options,NewknTypedel,knowledgepoints,knowledgepoints2,Knowpoints} = this.state; const {getFieldDecorator} = this.props.form; + console.log("this.state.rbkc"); + console.log(this.state.rbkc); + console.log(options); + + return (
    @@ -555,15 +668,15 @@ class Itembankstop extends Component { this.NewknTypedeldel(true)}/> -
    {this.state.Knowpoints === undefined ? "" : this.state.Knowpoints.map((object, index) => { return ( -

    {object.name}

    diff --git a/public/react/src/modules/question/component/Newknledpots.js b/public/react/src/modules/question/component/Newknledpots.js index a097b7d79..06d5b8ea0 100644 --- a/public/react/src/modules/question/component/Newknledpots.js +++ b/public/react/src/modules/question/component/Newknledpots.js @@ -14,10 +14,27 @@ class PaperDeletModel extends Component { } handleChange=(e)=>{ - this.setState({ - newkntypeinput: e.target.value - }) + // this.setState({ + // newkntypeinput: e.target.value + // }) + // console.log(e.target.value); + // console.log(e.target.value.length); + this.setState({ + newkntypeinput: e.target.value + }) + // + // debugger + // console.log(e); + // + // if(e.target.value.length>0){ + // if(e.target.value.length>=16){ + // var result = e.target.value.substring(0,15); + // this.setState({ + // newkntypeinput: result + // }) + // } + // } } render() { @@ -35,7 +52,7 @@ class PaperDeletModel extends Component { >
    - +
    this.props.NewknTypedeldel(false)}>取消 diff --git a/public/react/src/modules/question/component/SingleEditor.js b/public/react/src/modules/question/component/SingleEditor.js index fa20afb83..36ab30ab8 100644 --- a/public/react/src/modules/question/component/SingleEditor.js +++ b/public/react/src/modules/question/component/SingleEditor.js @@ -141,13 +141,6 @@ class SingleEditor extends Component{ this.props.showNotification('请您输入题干'); return editordata; } - - if(!answerArray || answerArray.length == 0) { - this.props.showNotification('请先点击选择本选择题的正确选项'); - return editordata; - } - - for(let i = 0; i < question_choices.length; i++) { if (!question_choices[i]) { // this.refs[`optionEditor${i}`].showError() @@ -156,6 +149,14 @@ class SingleEditor extends Component{ } } + if(!answerArray || answerArray.length == 0) { + this.props.showNotification('请先点击选择本选择题的正确选项'); + return editordata; + } + + + + if(!question_titlesysl) { this.props.showNotification('请您输入题目解析'); return editordata; @@ -328,7 +329,7 @@ class SingleEditor extends Component{ texts=value; } this.setState({ - question_titleysl:texts + question_titlesysl:texts }) } } diff --git a/public/react/src/modules/question/questioncss/questioncom.css b/public/react/src/modules/question/questioncss/questioncom.css index 153e94f20..0326f25fd 100644 --- a/public/react/src/modules/question/questioncss/questioncom.css +++ b/public/react/src/modules/question/questioncss/questioncom.css @@ -524,7 +524,7 @@ margin-top: 19px; } .mytags{ - width:106px; + min-width:106px; height:32px; border-radius:2px; border:1px solid #DDDDDD; @@ -955,4 +955,9 @@ padding: 0px !important; } - +.huanhan{ + flex-wrap: wrap; +} +.mb20{ + margin-bottom: 20px; +} From 5bc401236cd2727047bd5b48dec1000e343b905f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Thu, 9 Jan 2020 09:50:30 +0800 Subject: [PATCH 033/156] =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E5=9B=BE=E7=89=87?= =?UTF-8?q?=E7=9A=84=20=E4=B8=8A=E4=BC=A0=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/react/src/modules/question/component/ChoquesEditor.js | 4 ++++ .../react/src/modules/question/component/JudquestionEditor.js | 2 ++ public/react/src/modules/question/component/Listjihe.js | 1 + public/react/src/modules/question/component/SingleEditor.js | 4 ++++ 4 files changed, 11 insertions(+) diff --git a/public/react/src/modules/question/component/ChoquesEditor.js b/public/react/src/modules/question/component/ChoquesEditor.js index e3bb1b268..383ad1a86 100644 --- a/public/react/src/modules/question/component/ChoquesEditor.js +++ b/public/react/src/modules/question/component/ChoquesEditor.js @@ -365,6 +365,7 @@ class ChoquesEditor extends Component{

    :
    0? diff --git a/public/react/src/modules/question/component/SingleEditor.js b/public/react/src/modules/question/component/SingleEditor.js index 36ab30ab8..cdb2ef9b6 100644 --- a/public/react/src/modules/question/component/SingleEditor.js +++ b/public/react/src/modules/question/component/SingleEditor.js @@ -389,6 +389,7 @@ class SingleEditor extends Component{

    :
    Date: Thu, 9 Jan 2020 10:08:32 +0800 Subject: [PATCH 034/156] =?UTF-8?q?=E9=A2=98=E7=9B=AE=E8=A7=A3=E6=9E=90?= =?UTF-8?q?=E9=9D=9E=E5=BF=85=E5=A1=AB=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../question/component/ChoquesEditor.js | 8 ++-- .../question/component/Itembankstop.js | 42 +++++++++++++------ .../question/component/JudquestionEditor.js | 10 ++--- .../question/component/SingleEditor.js | 8 ++-- 4 files changed, 43 insertions(+), 25 deletions(-) diff --git a/public/react/src/modules/question/component/ChoquesEditor.js b/public/react/src/modules/question/component/ChoquesEditor.js index 383ad1a86..e1b1183f0 100644 --- a/public/react/src/modules/question/component/ChoquesEditor.js +++ b/public/react/src/modules/question/component/ChoquesEditor.js @@ -149,10 +149,10 @@ class ChoquesEditor extends Component{ this.props.showNotification('多选题最小正确选项为2个'); return editordata; } - if(!question_titlesysl) { - this.props.showNotification('请您输入题目解析'); - return editordata; - } + // if(!question_titlesysl) { + // this.props.showNotification('请您输入题目解析'); + // return editordata; + // } /** { "question_title":"同学朋友间常用的沟通工具是什么?", diff --git a/public/react/src/modules/question/component/Itembankstop.js b/public/react/src/modules/question/component/Itembankstop.js index 576dbb42d..c0cf0055b 100644 --- a/public/react/src/modules/question/component/Itembankstop.js +++ b/public/react/src/modules/question/component/Itembankstop.js @@ -556,19 +556,37 @@ class Itembankstop extends Component { id: result.data.tag_discipline_id, name:value, } - this.state.knowledgepoints.push(leydata); - const _result =[]; - this.state.knowledgepoints.filter(item => { - if (this.state.Knowpoints.findIndex(t => t.id === item.id) === -1) { - _result.push(item); - } - }); - this.setState({ - Knowpoints: this.state.Knowpoints, - knowledgepoints: this.state.knowledgepoints, - knowledgepoints2: _result, - }) + if(this.state.Knowpoints.length>=5){ + this.state.knowledgepoints.push(leydata); + const _result =[]; + this.state.knowledgepoints.filter(item => { + if (this.state.Knowpoints.findIndex(t => t.id === item.id) === -1) { + _result.push(item); + } + }); + + this.setState({ + Knowpoints: this.state.Knowpoints, + knowledgepoints: this.state.knowledgepoints, + knowledgepoints2: _result, + }) + }else{ + this.state.Knowpoints.push(leydata); + this.state.knowledgepoints.push(leydata); + const _result =[]; + this.state.knowledgepoints.filter(item => { + if (this.state.Knowpoints.findIndex(t => t.id === item.id) === -1) { + _result.push(item); + } + }); + this.setState({ + Knowpoints: this.state.Knowpoints, + knowledgepoints: this.state.knowledgepoints, + knowledgepoints2: _result, + }) + } + } }).catch((error) => { //console.log(error); diff --git a/public/react/src/modules/question/component/JudquestionEditor.js b/public/react/src/modules/question/component/JudquestionEditor.js index 951b37894..56c1f5017 100644 --- a/public/react/src/modules/question/component/JudquestionEditor.js +++ b/public/react/src/modules/question/component/JudquestionEditor.js @@ -119,11 +119,11 @@ class JudquestionEditor extends Component{ - - if(!question_titlesysl) { - this.props.showNotification('请您输入题目解析'); - return editordata; - } + // + // if(!question_titlesysl) { + // this.props.showNotification('请您输入题目解析'); + // return editordata; + // } /** { "question_title":"同学朋友间常用的沟通工具是什么?", diff --git a/public/react/src/modules/question/component/SingleEditor.js b/public/react/src/modules/question/component/SingleEditor.js index cdb2ef9b6..f050488bf 100644 --- a/public/react/src/modules/question/component/SingleEditor.js +++ b/public/react/src/modules/question/component/SingleEditor.js @@ -157,10 +157,10 @@ class SingleEditor extends Component{ - if(!question_titlesysl) { - this.props.showNotification('请您输入题目解析'); - return editordata; - } + // if(!question_titlesysl) { + // this.props.showNotification('请您输入题目解析'); + // return editordata; + // } /** { "question_title":"同学朋友间常用的沟通工具是什么?", From 8ad855a80d08b16c05a53f16e88994dd4922b9be Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Thu, 9 Jan 2020 10:16:54 +0800 Subject: [PATCH 035/156] =?UTF-8?q?=E4=BF=9D=E5=AD=98=E6=99=BA=E8=83=BD?= =?UTF-8?q?=E7=BB=84=E5=8D=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ination_intelligent_settings_controller.rb | 15 +++++++- .../save_exam_form.rb | 12 ++++++ .../save_examination_service.rb | 38 +++++++++++++++++++ config/routes.rb | 1 + .../20200109021528_add_intelligent_to_exam.rb | 5 +++ 5 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 app/forms/examination_intelligent_settings/save_exam_form.rb create mode 100644 app/services/examination_intelligent_settings/save_examination_service.rb create mode 100644 db/migrate/20200109021528_add_intelligent_to_exam.rb diff --git a/app/controllers/examination_intelligent_settings_controller.rb b/app/controllers/examination_intelligent_settings_controller.rb index 13d412da8..f4dcc1535 100644 --- a/app/controllers/examination_intelligent_settings_controller.rb +++ b/app/controllers/examination_intelligent_settings_controller.rb @@ -1,6 +1,6 @@ class ExaminationIntelligentSettingsController < ApplicationController before_action :require_login - before_action :find_exam, only: [:exchange_one_item, :exchange_items] + before_action :find_exam, only: [:exchange_one_item, :exchange_items, :save_exam] def optinal_items sub_discipline_id = params[:sub_discipline_id] @@ -26,6 +26,15 @@ class ExaminationIntelligentSettingsController < ApplicationController render_error(ex.message) end + def save_exam + new_exam = ExaminationBank.new(user: current_user) + # 保存试卷基础信息 + ExaminationIntelligentSettings::SaveExaminationService.call(new_exam, save_params, @exam) + render_ok + rescue ApplicationService::Error => ex + render_error(ex.message) + end + def exchange_one_item item = @exam.item_baskets.find_by!(id: params[:item_id]) exam_type_setting = @exam.examination_type_settings.find_by!(item_type: item.item_type) @@ -86,4 +95,8 @@ class ExaminationIntelligentSettingsController < ApplicationController def form_params params.permit(:discipline_id, :sub_discipline_id, :difficulty, :source, tag_discipline_id: [], question_settings: %i[item_type count]) end + + def save_params + params.permit(:name, :duration) + end end \ No newline at end of file diff --git a/app/forms/examination_intelligent_settings/save_exam_form.rb b/app/forms/examination_intelligent_settings/save_exam_form.rb new file mode 100644 index 000000000..ec4f17ad7 --- /dev/null +++ b/app/forms/examination_intelligent_settings/save_exam_form.rb @@ -0,0 +1,12 @@ +class ExaminationIntelligentSettings::SaveExamForm + include ActiveModel::Model + + attr_accessor :name, :duration + + validates :name, presence: true, length: { maximum: 60 } + validate :validate_duration + + def validate_duration + raise '时长应为大于0的整数' if duration.present? && duration.to_i < 1 + end +end \ No newline at end of file diff --git a/app/services/examination_intelligent_settings/save_examination_service.rb b/app/services/examination_intelligent_settings/save_examination_service.rb new file mode 100644 index 000000000..d6f5e7406 --- /dev/null +++ b/app/services/examination_intelligent_settings/save_examination_service.rb @@ -0,0 +1,38 @@ +class ExaminationIntelligentSettings::SaveExaminationService < ApplicationService + attr_reader :exam, :params, :exam_setting + + def initialize(exam, params, exam_setting) + @exam = exam + @params = params + @exam_setting = exam_setting + end + + def call + ExaminationIntelligentSettings::SaveExamForm.new(params).validate! + + ActiveRecord::Base.transaction do + exam.name = params[:name].to_s.strip + exam.difficulty = exam_setting.difficulty + exam.duration = params[:duration].present? ? params[:duration].to_i : nil + exam.sub_discipline_id = exam_setting.sub_discipline_id + exam.intelligent = 1 + exam.save! + + # 知识点的创建 + exam_setting.tag_discipline_containers.each do |tag| + exam.tag_discipline_containers << TagDisciplineContainer.new(tag_discipline_id: tag.tag_discipline_id) + end + + # 试题的复制 + exam_setting.item_baskets.includes(:item_bank).each do |basket| + item = basket.item_bank + if item.present? + new_item = ExaminationItem.new + new_item.new_item(item, exam, basket.score, basket.position) + end + end + + exam_setting.destroy! + end + end +end \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 225909f8e..a63776d44 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -102,6 +102,7 @@ Rails.application.routes.draw do end member do + post :save_exam post :exchange_one_item post :exchange_items end diff --git a/db/migrate/20200109021528_add_intelligent_to_exam.rb b/db/migrate/20200109021528_add_intelligent_to_exam.rb new file mode 100644 index 000000000..fa4b16dd1 --- /dev/null +++ b/db/migrate/20200109021528_add_intelligent_to_exam.rb @@ -0,0 +1,5 @@ +class AddIntelligentToExam < ActiveRecord::Migration[5.2] + def change + add_column :examination_banks, :intelligent, :boolean, default: false + end +end From 32e6ff7f23e9e979ec54aba873e2e0572d0b8f2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Thu, 9 Jan 2020 10:56:46 +0800 Subject: [PATCH 036/156] =?UTF-8?q?=E9=A2=98=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../question/component/ChoquesEditor.js | 4 + .../question/component/Itembankstop.js | 32 +- .../question/component/JudquestionEditor.js | 2 + .../question/component/Newknledpots.js | 12 +- .../question/component/SingleEditor.js | 4 + .../comthetestpaper/Comthetestpapers.js | 656 ------------------ .../comthetestpaper/Comthetestpaperst.js | 66 +- .../question/questioncss/questioncom.css | 5 + 8 files changed, 107 insertions(+), 674 deletions(-) delete mode 100644 public/react/src/modules/question/comthetestpaper/Comthetestpapers.js diff --git a/public/react/src/modules/question/component/ChoquesEditor.js b/public/react/src/modules/question/component/ChoquesEditor.js index e1b1183f0..8f07937ae 100644 --- a/public/react/src/modules/question/component/ChoquesEditor.js +++ b/public/react/src/modules/question/component/ChoquesEditor.js @@ -365,6 +365,7 @@ class ChoquesEditor extends Component{

    :
    { + this.setState({ + boolred:bool + }) + + } + //初始化 componentDidMount() { @@ -532,14 +541,31 @@ class Itembankstop extends Component { } NewknTypedeltyoedel=(value)=>{ + var knowledgepointmys= this.state.knowledgepoints; + var konwbool=null; + for(let myda of knowledgepointmys) { + if(myda.name===value){ + konwbool="yes" + break; + } + } + if(konwbool!=null){ + this.props.showNotification(`重复的知识点`); + this.setboolred(true); + return + } + + if(value===null||value===""){ this.props.showNotification(`请输入知识点`); + this.setboolred(true); return } if(value.length===0){ this.props.showNotification(`请输入知识点`); + this.setboolred(true); return } @@ -643,6 +669,8 @@ class Itembankstop extends Component { { NewknTypedel? this.setboolred(bool)} NewknTypedeldel={(bool)=>this.NewknTypedeldel(bool)} NewknTypedeltyoedel={(value)=>this.NewknTypedeltyoedel(value)} > diff --git a/public/react/src/modules/question/component/JudquestionEditor.js b/public/react/src/modules/question/component/JudquestionEditor.js index 56c1f5017..a48bef60a 100644 --- a/public/react/src/modules/question/component/JudquestionEditor.js +++ b/public/react/src/modules/question/component/JudquestionEditor.js @@ -377,6 +377,7 @@ class JudquestionEditor extends Component{

    { + console.log("失去焦点了"); + } + + inputOnFocus=(e)=>{ + console.log("获取焦点"); + } render() { @@ -51,8 +59,8 @@ class PaperDeletModel extends Component { width="442px" >
    -
    - +
    +
    this.props.NewknTypedeldel(false)}>取消 diff --git a/public/react/src/modules/question/component/SingleEditor.js b/public/react/src/modules/question/component/SingleEditor.js index f050488bf..591646aad 100644 --- a/public/react/src/modules/question/component/SingleEditor.js +++ b/public/react/src/modules/question/component/SingleEditor.js @@ -389,6 +389,7 @@ class SingleEditor extends Component{

    :
    { - this.setState({ - rbkc:[name.id,title.id] - }) - this.props.form.setFieldsValue({ - rbkc: [name.id,title.id], - }); - - if(this.props.item_banksedit.tag_disciplines.length===0){ - const didata = this.props.disciplinesdata; - const knowledgepointsdata = []; - - for (var i = 0; i < didata.length; i++) { - //方向 - if (name.id === didata[i].id) { - const fxdidata = didata[i].sub_disciplines; - for (var j = 0; j < fxdidata.length; j++) { - //课程 - if (title.id === fxdidata[j].id) { - const zsddata = fxdidata[j].tag_disciplines; - for (var k = 0; k < zsddata.length; k++) { - //知识点 - knowledgepointsdata.push(zsddata[k]); - - - } - - } - - } - } - - - } - - this.setState({ - Knowpoints: [], - knowledgepoints: knowledgepointsdata, - }) - - } - - - - - - - - - - - } - handletag_disciplinesChange = (data) => { - try { - var sju=data[data.length-1].name; - this.setState({ - rbzsd:sju, - Knowpoints:data, - }) - this.props.form.setFieldsValue({ - rbzsd: sju, - }); - }catch (e) { - - } - } - onChange = (e) => { - - } - Getdatas = () => { - return this.handleSubmits(); - } - handleSubmits = () => { - var data = []; - this.props.form.validateFields((err, values) => { - data = []; - if (!err) { - data.push({ - rbnd: parseInt(values.rbnd) - }) - data.push({ - rbtx: values.rbtx - }) - data.push({ - rbzsd: this.state.Knowpoints - }) - data.push({ - rbkc: values.rbkc - }) - data.push({ - classroom:values.classroom - }) - data.push({ - kssc:values.kssc - }) - - } - }); - - return data; - - } - handleSubmit = (e) => { - e.preventDefault(); - this.props.form.validateFields((err, values) => { - if (!err) { - ////console.log("获取的form 数据"); - ////console.log(values); - - } - - - }); - } - - handleFormLayoutChange = (value) => { - //难度塞选 - ////console.log("难度塞选"); - ////console.log(value); - this.props.form.setFieldsValue({ - rbnd: value + "", - }); - this.setState({ - rbnd: value + "", - }) - - } - handleFormkechen = (value) => { - //课程 - ////console.log("课程"); - ////console.log(value); - var valuename = undefined; - this.props.form.setFieldsValue({ - rbzsd: value, - }); - - var arr = this.state.knowledgepoints; - for (let data of arr) { - if (data.id === value) { - this.state.Knowpoints.push(data); - valuename = data.name; - } - } - - var tmp = JSON.parse(JSON.stringify(this.state.knowledgepoints)); - for (var i = 0; i < tmp.length; i++) { - if (tmp[i].id === value) { - this.state.knowledgepoints.splice(i, 1); - } - } - - this.setState({ - rbzsd: valuename, - Knowpoints: this.state.Knowpoints, - knowledgepoints: this.state.knowledgepoints, - }) - - } - - handleFormzhishidian = (value) => { - console.log("handleFormzhishidian 课程"); - console.log(value); - - //课程 - this.props.form.setFieldsValue({ - rbkc: value, - }); - this.setState({ - rbkc:value, - }) - // console.log("handleFormzhishidian"); - // console.log(this.props.disciplinesdata); - - const didata = this.props.disciplinesdata; - const knowledgepointsdata = []; - - for (var i = 0; i < didata.length; i++) { - //方向 - if (value[0] === didata[i].id) { - const fxdidata = didata[i].sub_disciplines; - for (var j = 0; j < fxdidata.length; j++) { - //课程 - if (value[1] === fxdidata[j].id) { - const zsddata = fxdidata[j].tag_disciplines; - for (var k = 0; k < zsddata.length; k++) { - //知识点 - knowledgepointsdata.push(zsddata[k]); - - - } - - } - - } - } - - - } - - this.setState({ - Knowpoints: [], - knowledgepoints: knowledgepointsdata, - }) - - this.props.form.setFieldsValue({ - rbzsd: undefined, - }); - this.setState({ - rbzsd: undefined, - }) - } - - handleFormtixing = (value) => { - //题型 - //console.log("题型"); - //console.log(value); - this.setState({ - rbtx: value + "", - }) - this.props.form.setFieldsValue({ - rbtx: value + "", - }); - this.props.setitem_type(value); - } - preventDefault = (e) => { - e.preventDefault(); - ////console.log('Clicked! But prevent default.'); - } - deletesobject = (item, index) => { - var arr = this.state.Knowpoints; - for (let data of arr) { - if (data.id === item.id) { - this.state.knowledgepoints.push(data); - } - } - - - var tmp = JSON.parse(JSON.stringify(this.state.Knowpoints)); - for (var i = 0; i < tmp.length; i++) { - if (i >= index) { - var pos = this.state.Knowpoints.indexOf(tmp[i]); - this.state.Knowpoints.splice(pos, 1); - } - } - - this.props.form.setFieldsValue({ - rbzsd: this.state.Knowpoints, - }); - - - this.setState({ - Knowpoints: this.state.Knowpoints, - }) - - if (this.state.Knowpoints.length === 0) { - this.setState({ - rbzsd: undefined, - }) - } else if (this.state.Knowpoints.length > 0) { - try { - const myknowda = this.state.Knowpoints; - this.setState({ - rbzsd: myknowda[this.state.Knowpoints.length - 1].name, - }) - } catch (e) { - - } - - } - - } - handleSearch=(value)=>{ - - - if(value!=""){ - this.props.form.setFieldsValue({ - classroom:value, - // course:value - }); - // this.Searchvalue(value) - } - - }; - - handleChange=(e)=>{ - console.log(e); - this.props.form.setFieldsValue({ - // course:value, - classroom:e.target.value, - }) - if(e.target.value){ - if(e.target.value.length>60){ - this.setState({ - bordebool:true, - }) - }else if(e.target.value.length===0){ - this.setState({ - bordebool:true, - }) - }else{ - this.setState({ - bordebool:false, - }) - } - }else{ - this.setState({ - bordebool:true - }) - - } - - }; - - render() { - let {page,options} = this.state; - const {getFieldDecorator} = this.props.form; - const optionss = this.state.searchlist && this.state.searchlist.map(d => ); - var addonAfterthree=this.props.form&&this.props.form.getFieldValue('classroom'); - var addonAfteronelens3=0; - if(addonAfterthree){ - addonAfteronelens3=String(addonAfterthree).length; - } - - return ( - -
    - -
    -
    -
    - - {getFieldDecorator("rbkc", - { - rules: [{required: true, message: '请选择课程'}], - } - )( -
    - - - -
    - )} -
    -
    - -
    - - {getFieldDecorator("rbzsd" - )( -
    - - - -
    - - {this.state.Knowpoints === undefined ? "" : this.state.Knowpoints.map((object, index) => { - return ( -
    -

    {object.name}

    - this.deletesobject(object, index)}> -
    - ) - })} - -
    -
    - )} -
    -
    - -
    - -
    - - {getFieldDecorator('classroom', { - rules: [{required: true, message: "不能为空"}], - })( - - - - - )} -
    -
    -
    - -
    - -
    - - - {getFieldDecorator('kssc')()} - 分钟 - -
    - {/*
    */} - {/**/} - {/* {getFieldDecorator("rbtx",*/} - {/* {*/} - {/* rules: [{required: true, message: '请选择题型'}],*/} - {/* }*/} - {/* )(*/} - {/* */} - {/* */} - {/* */} - {/* )}*/} - {/**/} - {/*
    */} - - -
    - - {getFieldDecorator('rbnd', - { - rules: [{required: true, message: '请选择难度'}], - } - )( - - 简单 - 适中 - 困难 - , - )} - -
    - -
    -
    -
    - ) - - } - - -} - -const Comthetestpaperss = Form.create({name: 'Itembankstops'})(Comthetestpapers); -export default Comthetestpaperss; diff --git a/public/react/src/modules/question/comthetestpaper/Comthetestpaperst.js b/public/react/src/modules/question/comthetestpaper/Comthetestpaperst.js index 88d5b9725..e6aa5f987 100644 --- a/public/react/src/modules/question/comthetestpaper/Comthetestpaperst.js +++ b/public/react/src/modules/question/comthetestpaper/Comthetestpaperst.js @@ -41,7 +41,7 @@ const options = [ ], }, ]; - +//Itembankstop 题库的 class Comthetestpaperst extends Component { constructor(props) { super(props); @@ -54,10 +54,16 @@ class Comthetestpaperst extends Component { knowledgepoints: [], knowledgepoints2:[], options: [], - NewknTypedel:false + NewknTypedel:false, + boolred:false, } } + setboolred=(bool)=>{ + this.setState({ + boolred:bool + }) + } //初始化 componentDidMount() { try { @@ -495,19 +501,32 @@ class Comthetestpaperst extends Component { } NewknTypedeltyoedel=(value)=>{ + var knowledgepointmys= this.state.knowledgepoints; + for(let myda of knowledgepointmys) { + if(myda.name===value){ + this.props.showNotification(`重复的知识点`); + this.setboolred(true); + break; + } + } if(value===null||value===""){ this.props.showNotification(`请输入知识点`); + this.setboolred(true); + return } if(value.length===0){ this.props.showNotification(`请输入知识点`); + this.setboolred(true); + return } if(this.state.rbkc===undefined || this.state.rbkc===null || this.state.rbkc===""){ this.props.showNotification(`请选择课程方向`); + this.setboolred(true); return; } var data={ @@ -523,19 +542,36 @@ class Comthetestpaperst extends Component { id: result.data.tag_discipline_id, name:value, } - this.state.knowledgepoints.push(leydata); - const _result =[]; - this.state.knowledgepoints.filter(item => { - if (this.state.Knowpoints.findIndex(t => t.id === item.id) === -1) { - _result.push(item); - } - }); - this.setState({ - Knowpoints: this.state.Knowpoints, - knowledgepoints: this.state.knowledgepoints, - knowledgepoints2: _result, - }) + if(this.state.Knowpoints.length>=5){ + this.state.knowledgepoints.push(leydata); + const _result =[]; + this.state.knowledgepoints.filter(item => { + if (this.state.Knowpoints.findIndex(t => t.id === item.id) === -1) { + _result.push(item); + } + }); + + this.setState({ + Knowpoints: this.state.Knowpoints, + knowledgepoints: this.state.knowledgepoints, + knowledgepoints2: _result, + }) + }else{ + this.state.Knowpoints.push(leydata); + this.state.knowledgepoints.push(leydata); + const _result =[]; + this.state.knowledgepoints.filter(item => { + if (this.state.Knowpoints.findIndex(t => t.id === item.id) === -1) { + _result.push(item); + } + }); + this.setState({ + Knowpoints: this.state.Knowpoints, + knowledgepoints: this.state.knowledgepoints, + knowledgepoints2: _result, + }) + } } }).catch((error) => { //console.log(error); @@ -609,6 +645,8 @@ class Comthetestpaperst extends Component { { NewknTypedel? this.setboolred(bool)} NewknTypedeldel={(bool)=>this.NewknTypedeldel(bool)} NewknTypedeltyoedel={(value)=>this.NewknTypedeltyoedel(value)} > diff --git a/public/react/src/modules/question/questioncss/questioncom.css b/public/react/src/modules/question/questioncss/questioncom.css index 0326f25fd..d792453d3 100644 --- a/public/react/src/modules/question/questioncss/questioncom.css +++ b/public/react/src/modules/question/questioncss/questioncom.css @@ -961,3 +961,8 @@ .mb20{ margin-bottom: 20px; } + +.inpustred .ant-input{ + border: 1px solid #f30707; + border-radius: 5px; +} From 25cfbf41f6d80adbdd498d3fc601f610e5ebe661 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Thu, 9 Jan 2020 11:02:40 +0800 Subject: [PATCH 037/156] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/react/src/modules/question/component/SingleEditor.js | 1 - 1 file changed, 1 deletion(-) diff --git a/public/react/src/modules/question/component/SingleEditor.js b/public/react/src/modules/question/component/SingleEditor.js index 591646aad..fc8549a7b 100644 --- a/public/react/src/modules/question/component/SingleEditor.js +++ b/public/react/src/modules/question/component/SingleEditor.js @@ -396,7 +396,6 @@ class SingleEditor extends Component{ options={['code-block', 'image', 'formula']} value={question_title} onContentChange={this.onContentChange} - />
    From 802876d0c7c0306cd348ae2235aa4a07e7777e8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Thu, 9 Jan 2020 11:13:02 +0800 Subject: [PATCH 038/156] =?UTF-8?q?=E8=B0=83=E6=95=B4=E9=A2=98=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/react/src/modules/question/component/ChoquesEditor.js | 4 ++-- .../react/src/modules/question/component/JudquestionEditor.js | 4 ++-- public/react/src/modules/question/component/SingleEditor.js | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/public/react/src/modules/question/component/ChoquesEditor.js b/public/react/src/modules/question/component/ChoquesEditor.js index 8f07937ae..93283c307 100644 --- a/public/react/src/modules/question/component/ChoquesEditor.js +++ b/public/react/src/modules/question/component/ChoquesEditor.js @@ -378,7 +378,7 @@ class ChoquesEditor extends Component{
    {/* {!question_id ? '新建' : '编辑'} */} * - 答案选项:点击答案可设置正确答案 + 答案选项:点击选项可设置正确答案
    {question_choices.map( (item, index) => { @@ -443,7 +443,7 @@ class ChoquesEditor extends Component{

    {/* {!question_id ? '新建' : '编辑'} */} - * + 题目解析:

    diff --git a/public/react/src/modules/question/component/JudquestionEditor.js b/public/react/src/modules/question/component/JudquestionEditor.js index a48bef60a..b1dc1fb45 100644 --- a/public/react/src/modules/question/component/JudquestionEditor.js +++ b/public/react/src/modules/question/component/JudquestionEditor.js @@ -390,7 +390,7 @@ class JudquestionEditor extends Component{
    {/* {!question_id ? '新建' : '编辑'} */} * - 答案选项:点击答案可设置正确答案 + 答案选项:点击选项可设置正确答案
    - this.showDrawer()} - Headertop={Headertop} + { + isysladmins===true? + this.showDrawer()} + Headertop={Headertop} + + /> + : + is_teacher===true&&professional_certification===true? + this.showDrawer()} + Headertop={Headertop} + + /> + : + + "" + } - /> {/*顶部*/} diff --git a/public/react/src/modules/question/component/Contentpart.js b/public/react/src/modules/question/component/Contentpart.js index da85ce0f7..a41050486 100644 --- a/public/react/src/modules/question/component/Contentpart.js +++ b/public/react/src/modules/question/component/Contentpart.js @@ -82,6 +82,11 @@ class Contentpart extends Component { render() { let {page}=this.state; let {defaultActiveKey,item_type,booljupyterurls}=this.props; + const isysladmins=this.props&&this.props.current_user&&this.props.current_user.admin?this.props.current_user.admin:false; + const is_teacher=this.props&&this.props.current_user&&this.props.current_user.is_teacher?this.props.current_user.is_teacher:false; + const professional_certification=this.props&&this.props.current_user&&this.props.current_user.professional_certification?this.props.current_user.professional_certification:false; + + const content = (
    this.props.callback(e)}> - - + { + isysladmins===true? + + + :is_teacher===true&&professional_certification===true? + + + :"" + } +
    { defaultActiveKey===0||defaultActiveKey==="0"? - this.xinzenw(e)}> -
    -

    新增

    -
    -
    + isysladmins===true? + this.xinzenw(e)}> +
    +

    新增

    +
    +
    + : + is_teacher===true&&professional_certification===true? + this.xinzenw(e)}> +
    +

    新增

    +
    +
    + :"" :"" } @@ -208,7 +230,7 @@ class Contentpart extends Component { { defaultActiveKey===0||defaultActiveKey==="0"? Date: Thu, 9 Jan 2020 14:39:12 +0800 Subject: [PATCH 044/156] =?UTF-8?q?=E9=A2=98=E5=BA=93=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/react/src/modules/question/Question.js | 16 ++++- .../modules/question/component/Contentpart.js | 34 ++++------ .../src/modules/testpaper/Testpaperlibrary.js | 19 +++++- .../testpaper/component/Contentpart.js | 66 +++++++++++-------- 4 files changed, 87 insertions(+), 48 deletions(-) diff --git a/public/react/src/modules/question/Question.js b/public/react/src/modules/question/Question.js index 144bac6eb..0ce04d3ba 100644 --- a/public/react/src/modules/question/Question.js +++ b/public/react/src/modules/question/Question.js @@ -163,16 +163,30 @@ class Question extends Component { //初始化 componentDidMount() { + const isysladmins=this.props&&this.props.current_user&&this.props.current_user.admin?this.props.current_user.admin:false; + const is_teacher=this.props&&this.props.current_user&&this.props.current_user.is_teacher?this.props.current_user.is_teacher:false; + const professional_certification=this.props&&this.props.current_user&&this.props.current_user.professional_certification?this.props.current_user.professional_certification:false; let {defaultActiveKey} = this.state; + var defaultActiveKeys=defaultActiveKey; + if(isysladmins===true||(is_teacher===true&&professional_certification===true)){ + defaultActiveKeys="1" + } + + + + var data = { discipline_id:this.state.discipline_id, sub_discipline_id:this.state.sub_discipline_id, tag_discipline_id:this.state.tag_discipline_id, - public: defaultActiveKey, + public: defaultActiveKeys, page:1, per_page:10, }; this.getdata(data); + this.setState({ + defaultActiveKey:defaultActiveKeys + }) let url = `/users/get_navigation_info.json`; axios.get(url, {}).then((response) => { diff --git a/public/react/src/modules/question/component/Contentpart.js b/public/react/src/modules/question/component/Contentpart.js index a41050486..44871ec76 100644 --- a/public/react/src/modules/question/component/Contentpart.js +++ b/public/react/src/modules/question/component/Contentpart.js @@ -120,8 +120,6 @@ class Contentpart extends Component { ); const buttonWidth = 70; - //console.log("Contentpart"); - //console.log(this.props); return (
    @@ -146,20 +144,23 @@ class Contentpart extends Component { ` } - this.props.callback(e)}> - - - { - isysladmins===true? - + + + { + isysladmins===true||(is_teacher===true&&professional_certification===true)? + this.props.callback(e)}> + - :is_teacher===true&&professional_certification===true? - :"" - } + + : + this.props.callback(e)}> + + + + } -
    { defaultActiveKey===0||defaultActiveKey==="0"? - isysladmins===true? - this.xinzenw(e)}> -
    -

    新增

    -
    -
    - : - is_teacher===true&&professional_certification===true? + isysladmins===true||(is_teacher===true&&professional_certification===true)? this.xinzenw(e)}>

    新增

    diff --git a/public/react/src/modules/testpaper/Testpaperlibrary.js b/public/react/src/modules/testpaper/Testpaperlibrary.js index fdd290ed8..c2b536d26 100644 --- a/public/react/src/modules/testpaper/Testpaperlibrary.js +++ b/public/react/src/modules/testpaper/Testpaperlibrary.js @@ -51,6 +51,17 @@ class Testpaperlibrary extends Component { //初始化 componentDidMount() { + const isysladmins=this.props&&this.props.current_user&&this.props.current_user.admin?this.props.current_user.admin:false; + const is_teacher=this.props&&this.props.current_user&&this.props.current_user.is_teacher?this.props.current_user.is_teacher:false; + const professional_certification=this.props&&this.props.current_user&&this.props.current_user.professional_certification?this.props.current_user.professional_certification:false; + let {defaultActiveKey} = this.state; + var defaultActiveKeys=defaultActiveKey; + if(isysladmins===true||(is_teacher===true&&professional_certification===true)){ + defaultActiveKeys="1" + } + this.setState({ + defaultActiveKey:defaultActiveKeys + }) let url = `/users/get_navigation_info.json`; axios.get(url, {}).then((response) => { // ////console.log("开始请求/get_navigation_info.json"); @@ -80,7 +91,7 @@ class Testpaperlibrary extends Component { discipline_id:this.state.discipline_id, sub_discipline_id:this.state.sub_discipline_id, tag_discipline_id:this.state.tag_discipline_id, - public: this.state.defaultActiveKey, + public: defaultActiveKeys, difficulty: this.state.difficulty, keywords: this.state.keywords, page: 1, @@ -417,6 +428,12 @@ class Testpaperlibrary extends Component { render() { let{Headertop,items_count,page,per_page,modalsTypes,modalsType}=this.state; + + const isysladmins=this.props&&this.props.current_user&&this.props.current_user.admin?this.props.current_user.admin:false; + const is_teacher=this.props&&this.props.current_user&&this.props.current_user.is_teacher?this.props.current_user.is_teacher:false; + const professional_certification=this.props&&this.props.current_user&&this.props.current_user.professional_certification?this.props.current_user.professional_certification:false; + + return (
    { diff --git a/public/react/src/modules/testpaper/component/Contentpart.js b/public/react/src/modules/testpaper/component/Contentpart.js index 1a7c90740..d5b568d52 100644 --- a/public/react/src/modules/testpaper/component/Contentpart.js +++ b/public/react/src/modules/testpaper/component/Contentpart.js @@ -41,6 +41,12 @@ class Contentpart extends Component { render() { let {page}=this.state; let {defaultActiveKey}=this.props; + + + const isysladmins=this.props&&this.props.current_user&&this.props.current_user.admin?this.props.current_user.admin:false; + const is_teacher=this.props&&this.props.current_user&&this.props.current_user.is_teacher?this.props.current_user.is_teacher:false; + const professional_certification=this.props&&this.props.current_user&&this.props.current_user.professional_certification?this.props.current_user.professional_certification:false; + const contents = (
    - this.props.callback(e)}> - - - - - + { + isysladmins===true||(is_teacher===true&&professional_certification===true)? + this.props.callback(e)}> + + + + + + : + this.props.callback(e)}> + + + + }
    -
    +
    - - From 6263d1e48cc22b3fd18236ffb7ebfe28d20e8a66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Thu, 9 Jan 2020 15:20:54 +0800 Subject: [PATCH 045/156] =?UTF-8?q?=E9=A2=98=E5=BA=93=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/react/src/modules/question/Question.js | 2 ++ public/react/src/modules/testpaper/Testpaperlibrary.js | 3 +++ 2 files changed, 5 insertions(+) diff --git a/public/react/src/modules/question/Question.js b/public/react/src/modules/question/Question.js index 0ce04d3ba..92e97161d 100644 --- a/public/react/src/modules/question/Question.js +++ b/public/react/src/modules/question/Question.js @@ -169,6 +169,8 @@ class Question extends Component { let {defaultActiveKey} = this.state; var defaultActiveKeys=defaultActiveKey; if(isysladmins===true||(is_teacher===true&&professional_certification===true)){ + defaultActiveKeys="0" + }else{ defaultActiveKeys="1" } diff --git a/public/react/src/modules/testpaper/Testpaperlibrary.js b/public/react/src/modules/testpaper/Testpaperlibrary.js index c2b536d26..0e8c362df 100644 --- a/public/react/src/modules/testpaper/Testpaperlibrary.js +++ b/public/react/src/modules/testpaper/Testpaperlibrary.js @@ -57,8 +57,11 @@ class Testpaperlibrary extends Component { let {defaultActiveKey} = this.state; var defaultActiveKeys=defaultActiveKey; if(isysladmins===true||(is_teacher===true&&professional_certification===true)){ + defaultActiveKeys="0" + }else{ defaultActiveKeys="1" } + this.setState({ defaultActiveKey:defaultActiveKeys }) From 6b734110fb815c8ed308296623544a703cea5f58 Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Thu, 9 Jan 2020 15:55:38 +0800 Subject: [PATCH 046/156] =?UTF-8?q?=E7=BC=96=E8=BE=91=E7=AD=94=E6=A1=88?= =?UTF-8?q?=E8=A7=A6=E5=8F=91=E8=AF=95=E9=A2=98=E7=9A=84=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/item_analysis.rb | 2 +- app/models/item_choice.rb | 2 +- app/models/tag_discipline_container.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/models/item_analysis.rb b/app/models/item_analysis.rb index 8f6e71302..dc1453982 100644 --- a/app/models/item_analysis.rb +++ b/app/models/item_analysis.rb @@ -1,3 +1,3 @@ class ItemAnalysis < ApplicationRecord - belongs_to :item_bank + belongs_to :item_bank, touch: true end diff --git a/app/models/item_choice.rb b/app/models/item_choice.rb index ccc35698e..2b2b08c9d 100644 --- a/app/models/item_choice.rb +++ b/app/models/item_choice.rb @@ -1,3 +1,3 @@ class ItemChoice < ApplicationRecord - belongs_to :item_bank + belongs_to :item_bank, touch: true end diff --git a/app/models/tag_discipline_container.rb b/app/models/tag_discipline_container.rb index 585182bbf..44b28af1a 100644 --- a/app/models/tag_discipline_container.rb +++ b/app/models/tag_discipline_container.rb @@ -1,5 +1,5 @@ class TagDisciplineContainer < ApplicationRecord belongs_to :tag_discipline - belongs_to :container, polymorphic: true, optional: true + belongs_to :container, polymorphic: true, optional: true, touch: true end From c32bce5c3573cbeb6f42c6f8c3d875f86ae6bdd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Thu, 9 Jan 2020 16:21:36 +0800 Subject: [PATCH 047/156] =?UTF-8?q?=E9=A2=98=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/react/src/modules/question/Question.js | 32 ----------------- .../modules/question/component/Contentpart.js | 34 ++++++++++++++----- .../src/modules/testpaper/Testpaperlibrary.js | 27 --------------- .../testpaper/component/Contentpart.js | 30 ++++++++++++---- 4 files changed, 50 insertions(+), 73 deletions(-) diff --git a/public/react/src/modules/question/Question.js b/public/react/src/modules/question/Question.js index 92e97161d..3b2c3a9bd 100644 --- a/public/react/src/modules/question/Question.js +++ b/public/react/src/modules/question/Question.js @@ -72,7 +72,6 @@ class Question extends Component { } chakanjiexibool=(index)=>{ - debugger if(this.state.chakanjiexiboolindex===index){ this.setState({ chakanjiexiboolindex:"无", @@ -163,37 +162,8 @@ class Question extends Component { //初始化 componentDidMount() { - const isysladmins=this.props&&this.props.current_user&&this.props.current_user.admin?this.props.current_user.admin:false; - const is_teacher=this.props&&this.props.current_user&&this.props.current_user.is_teacher?this.props.current_user.is_teacher:false; - const professional_certification=this.props&&this.props.current_user&&this.props.current_user.professional_certification?this.props.current_user.professional_certification:false; - let {defaultActiveKey} = this.state; - var defaultActiveKeys=defaultActiveKey; - if(isysladmins===true||(is_teacher===true&&professional_certification===true)){ - defaultActiveKeys="0" - }else{ - defaultActiveKeys="1" - } - - - - - var data = { - discipline_id:this.state.discipline_id, - sub_discipline_id:this.state.sub_discipline_id, - tag_discipline_id:this.state.tag_discipline_id, - public: defaultActiveKeys, - page:1, - per_page:10, - }; - this.getdata(data); - this.setState({ - defaultActiveKey:defaultActiveKeys - }) - let url = `/users/get_navigation_info.json`; axios.get(url, {}).then((response) => { - // ////console.log("开始请求/get_navigation_info.json"); - // ////console.log(response); if (response != undefined) { if (response.status === 200) { this.setState({ @@ -203,9 +173,7 @@ class Question extends Component { } } }); - this.getbasket_listdata(); - //获取题库筛选资料 let urls = `/disciplines.json`; axios.get(urls, {params: { diff --git a/public/react/src/modules/question/component/Contentpart.js b/public/react/src/modules/question/component/Contentpart.js index 44871ec76..5a50104a8 100644 --- a/public/react/src/modules/question/component/Contentpart.js +++ b/public/react/src/modules/question/component/Contentpart.js @@ -36,7 +36,22 @@ class Contentpart extends Component { chakanjiexibool=(index)=>{ this.props.chakanjiexibool(index); } - + componentDidUpdate(prevProps) { + if(prevProps.current_user !== this.props.current_user) { + debugger + const isysladmins=this.props&&this.props.current_user&&this.props.current_user.admin?this.props.current_user.admin:false; + const is_teacher=this.props&&this.props.current_user&&this.props.current_user.is_teacher?this.props.current_user.is_teacher:false; + const professional_certification=this.props&&this.props.current_user&&this.props.current_user.professional_certification?this.props.current_user.professional_certification:false; + let {defaultActiveKey} = this.props; + var defaultActiveKeys=defaultActiveKey; + if(isysladmins===true||(is_teacher===true&&professional_certification===true)){ + defaultActiveKeys="0" + }else{ + defaultActiveKeys="1" + } + this.props.callback(defaultActiveKeys); + } + } xinzenw=(e)=>{ var urls="?"; if(this.props.discipline_id){ @@ -119,7 +134,10 @@ class Contentpart extends Component {
    ); - const buttonWidth = 70; + + console.log("Contentpart.js"); + console.log(this.props.defaultActiveKey); + return (
    @@ -148,12 +166,12 @@ class Contentpart extends Component { { isysladmins===true||(is_teacher===true&&professional_certification===true)? - this.props.callback(e)}> - - - - - + this.props.callback(e)}> + + + + + : this.props.callback(e)}> diff --git a/public/react/src/modules/testpaper/Testpaperlibrary.js b/public/react/src/modules/testpaper/Testpaperlibrary.js index 0e8c362df..77192b1b2 100644 --- a/public/react/src/modules/testpaper/Testpaperlibrary.js +++ b/public/react/src/modules/testpaper/Testpaperlibrary.js @@ -51,20 +51,6 @@ class Testpaperlibrary extends Component { //初始化 componentDidMount() { - const isysladmins=this.props&&this.props.current_user&&this.props.current_user.admin?this.props.current_user.admin:false; - const is_teacher=this.props&&this.props.current_user&&this.props.current_user.is_teacher?this.props.current_user.is_teacher:false; - const professional_certification=this.props&&this.props.current_user&&this.props.current_user.professional_certification?this.props.current_user.professional_certification:false; - let {defaultActiveKey} = this.state; - var defaultActiveKeys=defaultActiveKey; - if(isysladmins===true||(is_teacher===true&&professional_certification===true)){ - defaultActiveKeys="0" - }else{ - defaultActiveKeys="1" - } - - this.setState({ - defaultActiveKey:defaultActiveKeys - }) let url = `/users/get_navigation_info.json`; axios.get(url, {}).then((response) => { // ////console.log("开始请求/get_navigation_info.json"); @@ -78,7 +64,6 @@ class Testpaperlibrary extends Component { } } }); - //获取题库筛选资料 let urls = `/disciplines.json`; axios.get(urls, {params: { @@ -90,18 +75,6 @@ class Testpaperlibrary extends Component { }) } }); - var data={ - discipline_id:this.state.discipline_id, - sub_discipline_id:this.state.sub_discipline_id, - tag_discipline_id:this.state.tag_discipline_id, - public: defaultActiveKeys, - difficulty: this.state.difficulty, - keywords: this.state.keywords, - page: 1, - per_page:10, - } - this.getdata(data); - } paginationonChange=(pages)=>{ diff --git a/public/react/src/modules/testpaper/component/Contentpart.js b/public/react/src/modules/testpaper/component/Contentpart.js index d5b568d52..97db4844b 100644 --- a/public/react/src/modules/testpaper/component/Contentpart.js +++ b/public/react/src/modules/testpaper/component/Contentpart.js @@ -38,6 +38,22 @@ class Contentpart extends Component { } + componentDidUpdate(prevProps) { + if(prevProps.current_user !== this.props.current_user) { + const isysladmins=this.props&&this.props.current_user&&this.props.current_user.admin?this.props.current_user.admin:false; + const is_teacher=this.props&&this.props.current_user&&this.props.current_user.is_teacher?this.props.current_user.is_teacher:false; + const professional_certification=this.props&&this.props.current_user&&this.props.current_user.professional_certification?this.props.current_user.professional_certification:false; + let {defaultActiveKey} = this.props; + var defaultActiveKeys=defaultActiveKey; + if(isysladmins===true||(is_teacher===true&&professional_certification===true)){ + defaultActiveKeys="0" + }else{ + defaultActiveKeys="1" + } + this.props.callback(defaultActiveKeys); + } + } + render() { let {page}=this.state; let {defaultActiveKey}=this.props; @@ -62,6 +78,8 @@ class Contentpart extends Component {

    ); + + return (
    @@ -90,12 +108,12 @@ class Contentpart extends Component { { isysladmins===true||(is_teacher===true&&professional_certification===true)? - this.props.callback(e)}> - - - - - + this.props.callback(e)}> + + + + + : this.props.callback(e)}> From ba4a081f8c487ebb81d181188876396fa6314d9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Thu, 9 Jan 2020 16:38:53 +0800 Subject: [PATCH 048/156] =?UTF-8?q?=E9=A2=98=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/modules/question/NewMyShixunModel.js | 14 +- public/react/src/modules/question/Question.js | 2 +- .../src/modules/testpaper/Intecomponents.js | 334 ++++++++++++++++++ .../src/modules/testpaper/Testpaperlibrary.js | 2 +- 4 files changed, 338 insertions(+), 14 deletions(-) create mode 100644 public/react/src/modules/testpaper/Intecomponents.js diff --git a/public/react/src/modules/question/NewMyShixunModel.js b/public/react/src/modules/question/NewMyShixunModel.js index b300156b7..badbffa08 100644 --- a/public/react/src/modules/question/NewMyShixunModel.js +++ b/public/react/src/modules/question/NewMyShixunModel.js @@ -27,7 +27,7 @@ class NewMyShixunModel extends Component { super(props); this.state = { count: 50, - defaultActiveKey:"0", + defaultActiveKey:"1", Headertop: "", Footerdown: "", visible: false, @@ -148,17 +148,7 @@ class NewMyShixunModel extends Component { //初始化 componentDidMount() { - let {defaultActiveKey} = this.state; - var data = { - discipline_id:this.state.discipline_id, - sub_discipline_id:this.state.sub_discipline_id, - tag_discipline_id:this.state.tag_discipline_id, - public: defaultActiveKey, - page:1, - per_page:10, - exam_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id), - }; - this.getdata(data); + let url = `/users/get_navigation_info.json`; axios.get(url, {}).then((response) => { diff --git a/public/react/src/modules/question/Question.js b/public/react/src/modules/question/Question.js index 3b2c3a9bd..c6278db17 100644 --- a/public/react/src/modules/question/Question.js +++ b/public/react/src/modules/question/Question.js @@ -26,7 +26,7 @@ class Question extends Component { super(props); this.state = { count: 50, - defaultActiveKey:"0", + defaultActiveKey:"1", Headertop: "", Footerdown: "", visible: false, diff --git a/public/react/src/modules/testpaper/Intecomponents.js b/public/react/src/modules/testpaper/Intecomponents.js new file mode 100644 index 000000000..0d452a890 --- /dev/null +++ b/public/react/src/modules/testpaper/Intecomponents.js @@ -0,0 +1,334 @@ +import React, {Component} from "react"; +import {Link, NavLink} from 'react-router-dom'; +import {WordsBtn, ActionBtn, SnackbarHOC, getImageUrl} from 'educoder'; +import axios from 'axios'; +import { + notification, + Spin, + Table, + Pagination, + Drawer, + Input, + Button, + Breadcrumb +} from "antd"; +import {TPMIndexHOC} from "../tpm/TPMIndexHOC"; +import NoneData from './component/NoneData'; +import './testioncss/testioncss.css'; +import '../tpm/newshixuns/css/Newshixuns.css'; +import Bottomsubmit from "../../modules/modals/Bottomsubmit"; +import Seeoagertits from "./component/Seeoagertits"; +import Paperlibraryseeid_item from './component/Paperlibraryseeid_item'; +import Comthetestpaperst from '../question/comthetestpaper/Comthetestpaperst'; +import Paperlibraryseeid_itemss from './component/Paperlibraryseeid_itemss'; +import JudquestionEditor from "../question/component/JudquestionEditor"; +import NewMyShixunModel from "../question/NewMyShixunModel"; + + +//试卷编辑 +class Intecomponents extends Component { + constructor(props) { + super(props); + this.Judquestio = React.createRef(); + this.state = { + paperlibrartdata: [], + disciplinesdata: [], + knowledgepoints: [], + disciplmy: [], + item_banksedit: [], + newmyshixunmodelbool:false, + } + + + } + + getJudquestio = (Ref) => { + console.log("子组件对象"); + console.log(Ref); + this.Judquestio = Ref; + } + + //初始化 + componentDidMount() { + this.getdata(); + let urls = `/disciplines.json`; + axios.get(urls, { + params: { + source: "question" + } + }).then((response) => { + if (response) { + this.setState({ + disciplinesdata: response.data.disciplines, + }) + if (response.data) { + if (response.data.disciplines) { + + const didata = response.data.disciplines; + + for (var i = 0; i < didata.length; i++) { + const childern = []; + //方向 + const fxdidata = didata[i].sub_disciplines; + + + for (var j = 0; j < fxdidata.length; j++) { + //课程 + const zsddata = fxdidata[j].tag_disciplines; + childern.push( + { + value: fxdidata[j].id, + label: fxdidata[j].name, + } + ) + for (var k = 0; k < zsddata.length; k++) { + //知识点 + this.state.knowledgepoints.push(zsddata[k]); + + + } + } + + const datakec = { + value: didata[i].id, + label: didata[i].name, + children: childern, + } + this.state.disciplmy.push(datakec); + } + + this.setState({ + knowledgepoints: this.state.knowledgepoints, + disciplmy: this.state.disciplmy, + }) + + + } + + } + + } + }); + + } + componentDidUpdate(prevProps) { + if(prevProps.current_user !== this.props.current_user) { + debugger + const isysladmins=this.props&&this.props.current_user&&this.props.current_user.admin?this.props.current_user.admin:false; + const is_teacher=this.props&&this.props.current_user&&this.props.current_user.is_teacher?this.props.current_user.is_teacher:false; + const professional_certification=this.props&&this.props.current_user&&this.props.current_user.professional_certification?this.props.current_user.professional_certification:false; + let {defaultActiveKey} = this.props; + var defaultActiveKeys=defaultActiveKey; + if(isysladmins===true||(is_teacher===true&&professional_certification===true)){ + defaultActiveKeys="0" + }else{ + defaultActiveKeys="1" + } + this.props.callback(defaultActiveKeys); + } + } + + getdata = () => { + let urls = `/examination_banks/${this.props.match.params.id}.json`; + axios.get(urls).then((response) => { + if (response) { + this.setState({ + paperlibrartdata: response.data, + item_banksedit: response.data.exam, + }) + } + }); + + } + + + //跳转道描点的地方 + scrollToAnchor = (anchorName) => { + try { + if (anchorName) { + // 找到锚点 + let anchorElement = document.getElementById(anchorName); + // 如果对应id的锚点存在,就跳转到锚点 + if (anchorElement) { + anchorElement.scrollIntoView(); + } + } + } catch (e) { + + } + + } + preservation = () => { + //保存试卷 + if (this.Judquestio.Getdatas().length === 0) { + this.scrollToAnchor("Itembankstopid"); + return; + } + var myrbkc=[]; + var Getdatasdatas=this.Judquestio.Getdatas()[2].rbzsd; + for(let myda of Getdatasdatas) { + myrbkc.push(myda.id); + } + const url = `/examination_banks/${this.props.match.params.id}.json`; + var data={ + difficulty:this.Judquestio.Getdatas()[0].rbnd, + name:this.Judquestio.Getdatas()[4].classroom, + duration:this.Judquestio.Getdatas()[5].kssc, + discipline_id: this.Judquestio.Getdatas()[3].rbkc[0], + sub_discipline_id: this.Judquestio.Getdatas()[3].rbkc[1], + tag_discipline_id: myrbkc, + } + axios.put(url, data) + .then((result) => { + if (result.data.status === 0) { + // this.props.showNotification(`试卷更新成功`); + this.props.history.push('/paperlibrary'); + } + }).catch((error) => { + console.log(error); + }) + + } + + + setitem_type = (item_type) => { + + + } + + setCohetepaperbool = (bool) => { + + } + getcontentMdRef = (Ref) => { + this.contentMdRef = Ref; + } + + setnewmyshixunmodelbool=(bool)=>{ + if(bool===true){ + let scrollToTop = window.setInterval(function() { + let pos = window.pageYOffset; + if ( pos > 0 ) { + window.scrollTo( 0, pos - 20 ); // how far to scroll on each step + } else { + window.clearInterval( scrollToTop ); + } + }, 2); + } + this.setState({ + newmyshixunmodelbool:bool + }) + this.getdata(); + } + + render() { + let {paperlibrartdata,newmyshixunmodelbool} = this.state; + const params = this.props && this.props.match && this.props.match.params; + // console.log("newmyshixunmodelbool"); + // console.log(newmyshixunmodelbool); + return ( +
    +
    + { + newmyshixunmodelbool===true? + + :"" + } + + { + newmyshixunmodelbool===true? +
    + this.setnewmyshixunmodelbool(e)}> +
    + : + "" + } + + +
    +
    + + 试卷库 + 公告试卷库 + 试卷编辑 + +
    + this.getJudquestio(ref)} + > + + +
    + +
    + this.setnewmyshixunmodelbool(e)} + all_score={paperlibrartdata && paperlibrartdata.exam && paperlibrartdata.exam.all_questions_count} + all_questions_count={paperlibrartdata && paperlibrartdata.exam && paperlibrartdata.exam.all_score} + difficulty={paperlibrartdata && paperlibrartdata.exam && paperlibrartdata.exam.difficulty} + > + +
    + this.getdata()} + single_questions={paperlibrartdata && paperlibrartdata.single_questions && paperlibrartdata.single_questions.questions.length > 0 ? paperlibrartdata.single_questions : null} + multiple_questions={paperlibrartdata && paperlibrartdata.multiple_questions + && paperlibrartdata.multiple_questions.questions.length > 0 ? paperlibrartdata.multiple_questions : null + } + judgement_questions={paperlibrartdata && paperlibrartdata.judgement_questions + && paperlibrartdata.judgement_questions.questions.length > 0 ? paperlibrartdata.judgement_questions : null + } + program_questions={paperlibrartdata && paperlibrartdata.program_questions + && paperlibrartdata.program_questions.questions.length > 0 ? paperlibrartdata.program_questions : null + } + > + + +
    + + +
    + + +
    + { + newmyshixunmodelbool === true ? "" : + this.setCohetepaperbool(bool)} + onSubmits={() => this.preservation()} url={'/paperlibrary'}> + } +
    + ) + + } + + +} + +export default SnackbarHOC()(TPMIndexHOC(Intecomponents)); + + diff --git a/public/react/src/modules/testpaper/Testpaperlibrary.js b/public/react/src/modules/testpaper/Testpaperlibrary.js index 77192b1b2..fb77352ef 100644 --- a/public/react/src/modules/testpaper/Testpaperlibrary.js +++ b/public/react/src/modules/testpaper/Testpaperlibrary.js @@ -36,7 +36,7 @@ class Testpaperlibrary extends Component { booljupyterurls:false, Contentdata:[], items_count:0, - defaultActiveKey:"0", + defaultActiveKey:"1", modalsTypes:false, modalsType:false, timuid:0, From dca89e0c0c0c681dd43cdd64a396e6f13dc094d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Thu, 9 Jan 2020 16:51:19 +0800 Subject: [PATCH 049/156] =?UTF-8?q?=E9=A2=98=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/modules/question/NewMyShixunModel.js | 31 +++++++++++++++++-- .../react/src/modules/question/Paperreview.js | 2 +- .../src/modules/testpaper/Intecomponents.js | 2 +- .../modules/testpaper/Paperlibraryeditid.js | 2 +- 4 files changed, 32 insertions(+), 5 deletions(-) diff --git a/public/react/src/modules/question/NewMyShixunModel.js b/public/react/src/modules/question/NewMyShixunModel.js index badbffa08..e271857ba 100644 --- a/public/react/src/modules/question/NewMyShixunModel.js +++ b/public/react/src/modules/question/NewMyShixunModel.js @@ -148,8 +148,17 @@ class NewMyShixunModel extends Component { //初始化 componentDidMount() { - - + const isysladmins=this.props&&this.props.current_user&&this.props.current_user.admin?this.props.current_user.admin:false; + const is_teacher=this.props&&this.props.current_user&&this.props.current_user.is_teacher?this.props.current_user.is_teacher:false; + const professional_certification=this.props&&this.props.current_user&&this.props.current_user.professional_certification?this.props.current_user.professional_certification:false; + let {defaultActiveKey} = this.props; + var defaultActiveKeys=defaultActiveKey; + if(isysladmins===true||(is_teacher===true&&professional_certification===true)){ + defaultActiveKeys="0" + }else{ + defaultActiveKeys="1" + } + this.callback(defaultActiveKeys); let url = `/users/get_navigation_info.json`; axios.get(url, {}).then((response) => { // ////console.log("开始请求/get_navigation_info.json"); @@ -180,6 +189,24 @@ class NewMyShixunModel extends Component { } }); } + + componentDidUpdate(prevProps) { + if(prevProps.current_user !== this.props.current_user) { + debugger + const isysladmins=this.props&&this.props.current_user&&this.props.current_user.admin?this.props.current_user.admin:false; + const is_teacher=this.props&&this.props.current_user&&this.props.current_user.is_teacher?this.props.current_user.is_teacher:false; + const professional_certification=this.props&&this.props.current_user&&this.props.current_user.professional_certification?this.props.current_user.professional_certification:false; + let {defaultActiveKey} = this.props; + var defaultActiveKeys=defaultActiveKey; + if(isysladmins===true||(is_teacher===true&&professional_certification===true)){ + defaultActiveKeys="0" + }else{ + defaultActiveKeys="1" + } + this.callback(defaultActiveKeys); + } + } + //公共和我的 callback = (key) => { this.setState({ diff --git a/public/react/src/modules/question/Paperreview.js b/public/react/src/modules/question/Paperreview.js index b65127c8d..680916d77 100644 --- a/public/react/src/modules/question/Paperreview.js +++ b/public/react/src/modules/question/Paperreview.js @@ -285,7 +285,7 @@ class Paperreview extends Component { { newmyshixunmodelbool===true?
    - this.setnewmyshixunmodelbool(e)}> + this.setnewmyshixunmodelbool(e)}>
    : "" diff --git a/public/react/src/modules/testpaper/Intecomponents.js b/public/react/src/modules/testpaper/Intecomponents.js index 0d452a890..fc0dadd4a 100644 --- a/public/react/src/modules/testpaper/Intecomponents.js +++ b/public/react/src/modules/testpaper/Intecomponents.js @@ -242,7 +242,7 @@ class Intecomponents extends Component { { newmyshixunmodelbool===true?
    - this.setnewmyshixunmodelbool(e)}> + this.setnewmyshixunmodelbool(e)}>
    : "" diff --git a/public/react/src/modules/testpaper/Paperlibraryeditid.js b/public/react/src/modules/testpaper/Paperlibraryeditid.js index efcb45496..449de0219 100644 --- a/public/react/src/modules/testpaper/Paperlibraryeditid.js +++ b/public/react/src/modules/testpaper/Paperlibraryeditid.js @@ -227,7 +227,7 @@ class Paperlibraryeditid extends Component { { newmyshixunmodelbool===true?
    - this.setnewmyshixunmodelbool(e)}> + this.setnewmyshixunmodelbool(e)}>
    : "" From e7c1dd122d73f5892f57241bfe95621113ea0386 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Thu, 9 Jan 2020 20:53:28 +0800 Subject: [PATCH 050/156] =?UTF-8?q?=E9=A2=98=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/react/src/App.js | 12 +- .../question/component/Itembankstop.js | 6 +- .../comthetestpaper/Comthetestpaperst.js | 10 +- .../comthetestpaper/Intelligentcomponents.js | 790 ++++++++++++++++++ .../comthetestpaper/lntlligentpone.js | 103 +++ .../question/questioncss/questioncom.css | 53 +- .../src/modules/testpaper/Intecomponents.js | 198 ++--- .../testpaper/testioncss/testioncss.css | 32 + 8 files changed, 1069 insertions(+), 135 deletions(-) create mode 100644 public/react/src/modules/question/comthetestpaper/Intelligentcomponents.js create mode 100644 public/react/src/modules/question/comthetestpaper/lntlligentpone.js diff --git a/public/react/src/App.js b/public/react/src/App.js index ee986824a..008cb12fe 100644 --- a/public/react/src/App.js +++ b/public/react/src/App.js @@ -334,7 +334,11 @@ const Paperreview= Loadable({ loading: Loading }) - +//智能组卷 +const Integeneration= Loadable({ + loader: () => import('./modules/testpaper/Intecomponents'), + loading: Loading +}) // 学院统计 const College = Loadable({ @@ -795,6 +799,12 @@ class App extends Component { render={ (props) => () }/> + + () + }/> + () diff --git a/public/react/src/modules/question/component/Itembankstop.js b/public/react/src/modules/question/component/Itembankstop.js index 070628d76..4e77bb524 100644 --- a/public/react/src/modules/question/component/Itembankstop.js +++ b/public/react/src/modules/question/component/Itembankstop.js @@ -628,9 +628,9 @@ class Itembankstop extends Component { let {page, options,NewknTypedel,knowledgepoints,knowledgepoints2,Knowpoints} = this.state; const {getFieldDecorator} = this.props.form; - console.log("this.state.rbkc"); - console.log(this.state.rbkc); - console.log(options); + // console.log("this.state.rbkc"); + // console.log(this.state.rbkc); + // console.log(options); return ( diff --git a/public/react/src/modules/question/comthetestpaper/Comthetestpaperst.js b/public/react/src/modules/question/comthetestpaper/Comthetestpaperst.js index 51574b36c..5116dcd61 100644 --- a/public/react/src/modules/question/comthetestpaper/Comthetestpaperst.js +++ b/public/react/src/modules/question/comthetestpaper/Comthetestpaperst.js @@ -494,6 +494,10 @@ class Comthetestpaperst extends Component { } NewknTypedeldel=(bool)=>{ + if(this.state.rbkc===undefined || this.state.rbkc===null || this.state.rbkc===""){ + this.props.showNotification(`请选择课程方向`); + return; + } this.setState({ NewknTypedel:bool }) @@ -524,11 +528,7 @@ class Comthetestpaperst extends Component { return } - if(this.state.rbkc===undefined || this.state.rbkc===null || this.state.rbkc===""){ - this.props.showNotification(`请选择课程方向`); - this.setboolred(true); - return; - } + var data={ name:value, sub_discipline_id:this.state.rbkc[1] diff --git a/public/react/src/modules/question/comthetestpaper/Intelligentcomponents.js b/public/react/src/modules/question/comthetestpaper/Intelligentcomponents.js new file mode 100644 index 000000000..c6ef50d90 --- /dev/null +++ b/public/react/src/modules/question/comthetestpaper/Intelligentcomponents.js @@ -0,0 +1,790 @@ +import React, {Component} from "react"; +import {Link, NavLink} from 'react-router-dom'; +import {WordsBtn, ActionBtn, SnackbarHOC, getImageUrl} from 'educoder'; +import axios from 'axios'; +import { + notification, + Spin, + Table, + Pagination, + Radio, + Checkbox, + Form, + Input, + Select, + Cascader, + Col, Row, InputNumber, DatePicker, AutoComplete, Button, Tag,Icon +} from "antd"; +import './../questioncss/questioncom.css'; +import Newknledpots from '../component/Newknledpots'; +import Ldanxuan from './lntlligentpone'; +const InputGroup = Input.Group; +const {Option} = Select; +//Itembankstop Comthetestpaperst 题库的 +class Intelligentcomponents extends Component { + constructor(props) { + super(props); + this.contentMdRef = React.createRef() + this.state = { + page: 1, + Knowpoints: [], + rbtx: undefined, + rbkc: undefined, + knowledgepoints: [], + knowledgepoints2:[], + options: [], + NewknTypedel:false, + boolred:false, + rbly:"1" + } + } + setboolred=(bool)=>{ + this.setState({ + boolred:bool + }) + + } + //初始化 + componentDidMount() { + try { + this.props.getJudquestio(this); + } catch (e) { + + } + this.setState({ + options: this.props.disciplmy, + + }) + + } + + componentDidUpdate(prevProps) { + //编辑的时候 + if (prevProps.disciplmy !== this.props.disciplmy) { + this.setState({ + options: this.props.disciplmy + }) + } + + } + + + + handdisciplinesChange =(name,title)=>{ + this.setState({ + rbkc:[name.id,title.id] + }) + this.props.form.setFieldsValue({ + rbkc: [name.id,title.id], + }); + + + + } + handleSearch=(value)=>{ + + + if(value!=""){ + this.props.form.setFieldsValue({ + classroom:value, + // course:value + }); + // this.Searchvalue(value) + } + + }; + handleChange=(e)=>{ + console.log(e); + + if(e.target.value){ + if(e.target.value.length>60){ + this.setState({ + bordebool:true, + }) + }else if(e.target.value.length===0){ + this.setState({ + bordebool:true, + }) + }else{ + this.setState({ + bordebool:false, + }) + } + }else{ + this.setState({ + bordebool:true + }) + + } + + }; + + handletag_disciplinesChange = (data) => { + //是否选中的知识点 + try { + var sju=data[data.length-1].name; + this.setState({ + Knowpoints:data, + }) + this.props.form.setFieldsValue({ + rbzsd: sju, + }); + }catch (e) { + + } + + + } + onChange = (e) => { + + } + Getdatas = () => { + return this.handleSubmits(); + } + handleSubmits = () => { + var dxt=0; + var dxtx=0; + var pdt=0; + var bct=0; + try { + dxt=this.$dxt.mygetinputnumber(); + }catch (e) { + dxt=0; + } + + try { + dxtx=this.$ddxt.mygetinputnumber(); + }catch (e) { + dxtx=0; + } + + try { + pdt=this.$pdt.mygetinputnumber(); + }catch (e) { + pdt=0; + } + + try { + bct=this.$bct.mygetinputnumber(); + }catch (e) { + bct=0; + } + + + + + var data = []; + this.props.form.validateFields((err, values) => { + data = []; + if (!err) { + data.push({ + rbnd: parseInt(values.rbnd) + }) + data.push({ + rbzsd: this.state.Knowpoints + }) + data.push({ + rbkc: values.rbkc + }) + data.push({ + rbdxt: dxt + }) + data.push({ + rbdxtx: dxtx + }) + data.push({ + rbpdt: pdt + }) + data.push({ + rbbct: bct + }) + data.push({ + rbly: parseInt(values.rbly) + }) + } + }); + return data; + } + handleSubmit = (e) => { + e.preventDefault(); + this.props.form.validateFields((err, values) => { + if (!err) { + ////console.log("获取的form 数据"); + ////console.log(values); + + } + + + }); + } + handleFormLayoutChanges = (value) => { + //来源 + this.props.form.setFieldsValue({ + rbly: value + "", + }); + this.setState({ + rbly: value + "", + }) + + } + handleFormLayoutChange = (value) => { + //难度塞选 + ////console.log("难度塞选"); + ////console.log(value); + this.props.form.setFieldsValue({ + rbnd: value + "", + }); + this.setState({ + rbnd: value + "", + }) + + } + handleFormkechen = (value) => { + //课程 + ////console.log("课程"); + ////console.log(value); + if(this.state.Knowpoints.length>4){ + this.props.showNotification(`知识点最多选择5个`); + return + } + var valuename = undefined; + this.props.form.setFieldsValue({ + rbzsd: value, + }); + + var arr = this.state.knowledgepoints; + for (let data of arr) { + if (data.id === value) { + this.state.Knowpoints.push(data); + valuename = data.name; + } + } + + const _result =[]; + this.state.knowledgepoints.filter(item => { + if (this.state.Knowpoints.findIndex(t => t.id === item.id) === -1) { + console.log("guonue"); + console.log(item); + _result.push(item); + } + }); + + + this.setState({ + rbzsd: valuename, + Knowpoints: this.state.Knowpoints, + knowledgepoints2: _result, + }) + + } + + handleFormzhishidian = (value) => { + console.log("handleFormzhishidian 课程"); + console.log(value); + + //课程 + this.props.form.setFieldsValue({ + rbkc: value, + }); + this.setState({ + rbkc:value, + }) + // console.log("handleFormzhishidian"); + // console.log(this.props.disciplinesdata); + + const didata = this.props.disciplinesdata; + const knowledgepointsdata = []; + + for (var i = 0; i < didata.length; i++) { + //方向 + if (value[0] === didata[i].id) { + const fxdidata = didata[i].sub_disciplines; + for (var j = 0; j < fxdidata.length; j++) { + //课程 + if (value[1] === fxdidata[j].id) { + const zsddata = fxdidata[j].tag_disciplines; + for (var k = 0; k < zsddata.length; k++) { + //知识点 + knowledgepointsdata.push(zsddata[k]); + + + } + + } + + } + } + + + } + + this.setState({ + Knowpoints: [], + knowledgepoints: knowledgepointsdata, + knowledgepoints2:knowledgepointsdata, + }) + + this.props.form.setFieldsValue({ + rbzsd: undefined, + }); + this.setState({ + rbzsd: undefined, + }) + } + + handleFormtixing = (value) => { + //题型 + //console.log("题型"); + //console.log(value); + this.setState({ + rbtx: value + "", + }) + this.props.form.setFieldsValue({ + rbtx: value + "", + }); + this.props.setitem_type(value); + } + preventDefault = (e) => { + e.preventDefault(); + ////console.log('Clicked! But prevent default.'); + } + deletesobject = (item, index) => { + debugger + var tmp = this.state.Knowpoints; + for (var i = 0; i < tmp.length; i++) { + if (i ===index) { + tmp.splice(i,1); + } + } + + this.props.form.setFieldsValue({ + rbzsd: this.state.Knowpoints, + }); + + const _result =[]; + this.state.knowledgepoints.filter(item => { + if (this.state.Knowpoints.findIndex(t => t.id === item.id) === -1) { + _result.push(item); + } + }); + this.setState({ + Knowpoints: this.state.Knowpoints, + knowledgepoints2:_result, + }) + if (this.state.Knowpoints.length === 0) { + this.setState({ + rbzsd: undefined, + }) + } else if (this.state.Knowpoints.length > 0) { + try { + const myknowda = this.state.Knowpoints; + this.setState({ + rbzsd: myknowda[this.state.Knowpoints.length - 1].name, + }) + } catch (e) { + + } + + } + + } + + NewknTypedeldel=(bool)=>{ + if(this.state.rbkc===undefined || this.state.rbkc===null || this.state.rbkc===""){ + this.props.showNotification(`请选择课程方向`); + return; + } + this.setState({ + NewknTypedel:bool + }) + + } + + NewknTypedeltyoedel=(value)=>{ + var knowledgepointmys= this.state.knowledgepoints; + for(let myda of knowledgepointmys) { + if(myda.name===value){ + this.props.showNotification(`重复的知识点`); + this.setboolred(true); + + break; + } + } + if(value===null||value===""){ + this.props.showNotification(`请输入知识点`); + this.setboolred(true); + + return + } + + if(value.length===0){ + this.props.showNotification(`请输入知识点`); + this.setboolred(true); + + return + } + + + var data={ + name:value, + sub_discipline_id:this.state.rbkc[1] + } + const url="/tag_disciplines.json"; + axios.post(url,data) + .then((result) => { + if (result.data.status === 0) { + // this.props.showNotification(`新增知识点成功!`); + var leydata={ + id: result.data.tag_discipline_id, + name:value, + } + + if(this.state.Knowpoints.length>=5){ + this.state.knowledgepoints.push(leydata); + const _result =[]; + this.state.knowledgepoints.filter(item => { + if (this.state.Knowpoints.findIndex(t => t.id === item.id) === -1) { + _result.push(item); + } + }); + + this.setState({ + Knowpoints: this.state.Knowpoints, + knowledgepoints: this.state.knowledgepoints, + knowledgepoints2: _result, + }) + }else{ + this.state.Knowpoints.push(leydata); + this.state.knowledgepoints.push(leydata); + const _result =[]; + this.state.knowledgepoints.filter(item => { + if (this.state.Knowpoints.findIndex(t => t.id === item.id) === -1) { + _result.push(item); + } + }); + this.setState({ + Knowpoints: this.state.Knowpoints, + knowledgepoints: this.state.knowledgepoints, + knowledgepoints2: _result, + }) + } + } + }).catch((error) => { + //console.log(error); + }) + + this.setState({ + NewknTypedel:false + }) + } + + + + render() { + let {page, options,NewknTypedel,knowledgepoints,knowledgepoints2,Knowpoints} = this.state; + const {getFieldDecorator} = this.props.form; + const optionss = this.state.searchlist && this.state.searchlist.map(d => ); + + + return ( + +
    + +
    + { + NewknTypedel? + this.setboolred(bool)} + NewknTypedeldel={(bool)=>this.NewknTypedeldel(bool)} + NewknTypedeltyoedel={(value)=>this.NewknTypedeltyoedel(value)} + > + :"" + } + +
    +
    +
    + + {getFieldDecorator("rbkc" + , + {initialValue: this.state.rbkc, + rules: [{required: true, message: '请选择课程'}], + } + )( + + )} + +
    +
    +
    + + {getFieldDecorator("rbzsd" + )( +
    + + + + + + + this.NewknTypedeldel(true)}/> + + + +
    + )} +
    +
    + { + this.state.Knowpoints===undefined||this.state.Knowpoints===null?"": + this.state.Knowpoints.length>0? +
    + {this.state.Knowpoints === undefined ? "" : this.state.Knowpoints.map((object, index) => { + return ( +
    +

    {object.name}

    + + this.deletesobject(object, index)} src={getImageUrl("images/educoder/bzucha.png")}/> + +
    + ) + })} +
    + : + "" + } + + +
    + + {getFieldDecorator('rbly' + , + {initialValue: this.state.rbly, + } + )( + + 公共 + 我的 + , + )} + +
    + +

    条件设置

    +
    + + + +
    + + {getFieldDecorator('rbnd' + , + {initialValue: this.state.rbnd, + rules: [{required: true, message: '请选择难度'}], + } + )( + + 简单 + 适中 + 困难 + , + )} + +
    + + +
    +

    题型及数量

    +
    + this.props.getdatas()} ref={dom => { + this.$dxt = dom; + }}> + this.props.getdatas()} ref={dom => { + this.$ddxt = dom; + }}> + this.props.getdatas()} ref={dom => { + this.$pdt = dom; + }}> + this.props.getdatas()} ref={dom => { + this.$bct = dom; + }}> + + + +
    +
    + ) + + } + + +} + +const Intelligentcomponentss = Form.create({name: 'Intelligentcomponents'})(Intelligentcomponents); +export default Intelligentcomponentss; diff --git a/public/react/src/modules/question/comthetestpaper/lntlligentpone.js b/public/react/src/modules/question/comthetestpaper/lntlligentpone.js new file mode 100644 index 000000000..b7cbab974 --- /dev/null +++ b/public/react/src/modules/question/comthetestpaper/lntlligentpone.js @@ -0,0 +1,103 @@ +import React, {Component} from "react"; +import {Link, NavLink} from 'react-router-dom'; +import {WordsBtn, ActionBtn, getImageUrl, markdownToHTML} from 'educoder'; +import axios from 'axios'; +import { + notification, + Spin, + Table, + Pagination, + Drawer, + Input, + Button, + Breadcrumb, + Icon, + InputNumber +} from "antd"; +import '../questioncss/questioncom.css'; + +//判断题 +class lntlligentpone extends Component { + constructor(props) { + super(props); + + this.state = { + count: 0, + countbool: false, + } + + } + + //初始化 + componentDidMount() { + + + } + + increase = () => { + this.props.getdatas(); + const count = this.state.count + 1; + this.setState({count: count, countbool: false}); + }; + + decline = () => { + this.props.getdatas(); + let count = this.state.count - 1; + if (count < 0) { + count = 0; + } + this.setState({count: count, countbool: false}); + }; + inputsnumber = (value) => { + this.props.getdatas(); + this.setState({count: value, countbool: false}); + + } + + //返回数据 + mygetinputnumber=()=>{ + return this.state.count; + } + isNumber=(val)=>{ + var regPos = /^\d+(\.\d+)?$/; //非负浮点数 + var regNeg = /^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$/; //负浮点数 + if(regPos.test(val) && regNeg.test(val)){ + return true; + }else{ + return false; + } + } + + render() { + let {questions, totalscore, total, items} = this.state; + return ( +
    +

    {this.props.dxtx}

    +
    + +
    + +
    + +

    共{this.props.dxgt}道

    +
    +
    + ) + + } + + +} + +export default lntlligentpone + + diff --git a/public/react/src/modules/question/questioncss/questioncom.css b/public/react/src/modules/question/questioncss/questioncom.css index 84a663217..47e3eb9b6 100644 --- a/public/react/src/modules/question/questioncss/questioncom.css +++ b/public/react/src/modules/question/questioncss/questioncom.css @@ -524,7 +524,14 @@ margin-top: 19px; } .mytags{ - min-width:106px; + min-width:106px !important; + height:32px; + border-radius:2px; + border:1px solid #DDDDDD; + margin-right: 20px; +} +.mytagss{ + min-width:106px !important; height:32px; border-radius:2px; border:1px solid #DDDDDD; @@ -970,3 +977,47 @@ .mt15{ margin-top: 15px; } +.conditionsetting{ + width:64px; + height:21px; + font-size:16px; + color:#333333; + line-height:21px; +} +.hengxians{ + width:1021px; + height:1px; + background: #EEEEEE; +} +.mt13{ + margin-top: 13px; +} +.inpustredss .ant-input-number{ + border: 1px solid #f30707; + border-radius: 5px; +} + +.inpustredssdiv button { + border-radius: 50%; + width: 38px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +.inpustredssdiv .ant-input-number-input{ + text-align: center; +} +.lh32{ + line-height: 32px; +} +.ml23{ + margin-left: 23px; +} +.ml12{ + margin-left: 12px; +} +.mr12{ + margin-right: 12px; +} diff --git a/public/react/src/modules/testpaper/Intecomponents.js b/public/react/src/modules/testpaper/Intecomponents.js index fc0dadd4a..d16e6ae80 100644 --- a/public/react/src/modules/testpaper/Intecomponents.js +++ b/public/react/src/modules/testpaper/Intecomponents.js @@ -13,17 +13,10 @@ import { Breadcrumb } from "antd"; import {TPMIndexHOC} from "../tpm/TPMIndexHOC"; -import NoneData from './component/NoneData'; import './testioncss/testioncss.css'; import '../tpm/newshixuns/css/Newshixuns.css'; import Bottomsubmit from "../../modules/modals/Bottomsubmit"; -import Seeoagertits from "./component/Seeoagertits"; -import Paperlibraryseeid_item from './component/Paperlibraryseeid_item'; -import Comthetestpaperst from '../question/comthetestpaper/Comthetestpaperst'; -import Paperlibraryseeid_itemss from './component/Paperlibraryseeid_itemss'; -import JudquestionEditor from "../question/component/JudquestionEditor"; -import NewMyShixunModel from "../question/NewMyShixunModel"; - +import Intelligentcomponents from "../question/comthetestpaper/Intelligentcomponents"; //试卷编辑 class Intecomponents extends Component { @@ -50,7 +43,6 @@ class Intecomponents extends Component { //初始化 componentDidMount() { - this.getdata(); let urls = `/disciplines.json`; axios.get(urls, { params: { @@ -110,38 +102,43 @@ class Intecomponents extends Component { } }); + + + } - componentDidUpdate(prevProps) { - if(prevProps.current_user !== this.props.current_user) { - debugger - const isysladmins=this.props&&this.props.current_user&&this.props.current_user.admin?this.props.current_user.admin:false; - const is_teacher=this.props&&this.props.current_user&&this.props.current_user.is_teacher?this.props.current_user.is_teacher:false; - const professional_certification=this.props&&this.props.current_user&&this.props.current_user.professional_certification?this.props.current_user.professional_certification:false; - let {defaultActiveKey} = this.props; - var defaultActiveKeys=defaultActiveKey; - if(isysladmins===true||(is_teacher===true&&professional_certification===true)){ - defaultActiveKeys="0" - }else{ - defaultActiveKeys="1" - } - this.props.callback(defaultActiveKeys); + getdatas=()=>{ + var myrbkc=[]; + var Getdatasdatas=this.Judquestio.Getdatas()[1].rbzsd; + for(let myda of Getdatasdatas) { + myrbkc.push(myda.id); + } + const url="/examination_intelligent_settings/optinal_items.jso"; + var data={ + sub_discipline_id:this.Judquestio.Getdatas()[2].rbkc[1], + tag_discipline_id:myrbkc, + source:this.Judquestio.Getdatas()[7].rbly, + difficulty:this.Judquestio.Getdatas()[0].rbnd, } + + axios.get(url, {params: { + data + }}).then((response) => { + if (response) { + console.log(response); + } + }); + } - getdata = () => { - let urls = `/examination_banks/${this.props.match.params.id}.json`; - axios.get(urls).then((response) => { - if (response) { - this.setState({ - paperlibrartdata: response.data, - item_banksedit: response.data.exam, - }) - } - }); + + + + componentDidUpdate(prevProps) { } + //跳转道描点的地方 scrollToAnchor = (anchorName) => { try { @@ -159,30 +156,53 @@ class Intecomponents extends Component { } preservation = () => { - //保存试卷 if (this.Judquestio.Getdatas().length === 0) { this.scrollToAnchor("Itembankstopid"); return; } var myrbkc=[]; - var Getdatasdatas=this.Judquestio.Getdatas()[2].rbzsd; + var Getdatasdatas=this.Judquestio.Getdatas()[1].rbzsd; for(let myda of Getdatasdatas) { myrbkc.push(myda.id); } - const url = `/examination_banks/${this.props.match.params.id}.json`; - var data={ + // console.log(myrbkc); + // console.log("preservation"); + // console.log(this.Judquestio.Getdatas()); + + + var question_settings =[ + { + "item_type": "SINGLE", + "count": this.Judquestio.Getdatas()[3].rbdxt + }, + { + "item_type": "MULTIPLE", + "count": this.Judquestio.Getdatas()[4].rbdxtx + }, + { + "item_type": "JUDGMENT", + "count": this.Judquestio.Getdatas()[5].rbpdt + }, + { + "item_type": "PROGRAM", + "count": this.Judquestio.Getdatas()[6].rbbct + } + ] + + + const url="/examination_intelligent_settings.json" + var data = { + discipline_id: this.Judquestio.Getdatas()[2].rbkc[0], + sub_discipline_id:this.Judquestio.Getdatas()[2].rbkc[1], + tag_discipline_id:myrbkc, + source:this.Judquestio.Getdatas()[7].rbly, difficulty:this.Judquestio.Getdatas()[0].rbnd, - name:this.Judquestio.Getdatas()[4].classroom, - duration:this.Judquestio.Getdatas()[5].kssc, - discipline_id: this.Judquestio.Getdatas()[3].rbkc[0], - sub_discipline_id: this.Judquestio.Getdatas()[3].rbkc[1], - tag_discipline_id: myrbkc, + question_settings:question_settings, } - axios.put(url, data) + axios.post(url, data) .then((result) => { - if (result.data.status === 0) { - // this.props.showNotification(`试卷更新成功`); - this.props.history.push('/paperlibrary'); + if (result.data.status == 0) { + console.log("组卷成功"); } }).catch((error) => { console.log(error); @@ -203,51 +223,17 @@ class Intecomponents extends Component { this.contentMdRef = Ref; } - setnewmyshixunmodelbool=(bool)=>{ - if(bool===true){ - let scrollToTop = window.setInterval(function() { - let pos = window.pageYOffset; - if ( pos > 0 ) { - window.scrollTo( 0, pos - 20 ); // how far to scroll on each step - } else { - window.clearInterval( scrollToTop ); - } - }, 2); - } - this.setState({ - newmyshixunmodelbool:bool - }) - this.getdata(); + setnewmyshixunmodelbool=()=>{ + } render() { let {paperlibrartdata,newmyshixunmodelbool} = this.state; const params = this.props && this.props.match && this.props.match.params; - // console.log("newmyshixunmodelbool"); - // console.log(newmyshixunmodelbool); return (
    - { - newmyshixunmodelbool===true? - - :"" - } - - { - newmyshixunmodelbool===true? -
    - this.setnewmyshixunmodelbool(e)}> -
    - : - "" - } - -
    - this.setnewmyshixunmodelbool(e)} - all_score={paperlibrartdata && paperlibrartdata.exam && paperlibrartdata.exam.all_questions_count} - all_questions_count={paperlibrartdata && paperlibrartdata.exam && paperlibrartdata.exam.all_score} - difficulty={paperlibrartdata && paperlibrartdata.exam && paperlibrartdata.exam.difficulty} - > - -
    - this.getdata()} - single_questions={paperlibrartdata && paperlibrartdata.single_questions && paperlibrartdata.single_questions.questions.length > 0 ? paperlibrartdata.single_questions : null} - multiple_questions={paperlibrartdata && paperlibrartdata.multiple_questions - && paperlibrartdata.multiple_questions.questions.length > 0 ? paperlibrartdata.multiple_questions : null - } - judgement_questions={paperlibrartdata && paperlibrartdata.judgement_questions - && paperlibrartdata.judgement_questions.questions.length > 0 ? paperlibrartdata.judgement_questions : null - } - program_questions={paperlibrartdata && paperlibrartdata.program_questions - && paperlibrartdata.program_questions.questions.length > 0 ? paperlibrartdata.program_questions : null - } - > - - -
    diff --git a/public/react/src/modules/testpaper/testioncss/testioncss.css b/public/react/src/modules/testpaper/testioncss/testioncss.css index c22c93f8a..2025779ab 100644 --- a/public/react/src/modules/testpaper/testioncss/testioncss.css +++ b/public/react/src/modules/testpaper/testioncss/testioncss.css @@ -895,3 +895,35 @@ .tites{ color: #888888 !important; } +.conditionsetting{ + width:64px; + height:21px; + font-size:16px; + color:#333333; + line-height:21px; +} + +.conditionsettings{ + width:80px; + height:21px; + font-size:16px; + font-family:MicrosoftYaHei; + color:rgba(51,51,51,1); + line-height:21px; +} +.hengxians{ + width:1021px; + height:1px; + background: #EEEEEE; +} +.mt13{ + margin-top: 13px; +} +.dxuantitie{ + width:57px; + height:19px; + font-size:14px; + font-family:MicrosoftYaHei; + color:rgba(51,51,51,1); + line-height:19px; +} From dfc0053ca267b9c82fe2e4fc0c3e8639679e3582 Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Fri, 10 Jan 2020 11:34:10 +0800 Subject: [PATCH 051/156] =?UTF-8?q?=E9=A2=98=E5=BA=93=E7=9A=84=E5=AD=97?= =?UTF-8?q?=E7=AC=A6=E9=99=90=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/forms/item_banks/save_item_form.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/forms/item_banks/save_item_form.rb b/app/forms/item_banks/save_item_form.rb index d6d3a3e28..f4ad5291c 100644 --- a/app/forms/item_banks/save_item_form.rb +++ b/app/forms/item_banks/save_item_form.rb @@ -8,7 +8,7 @@ class ItemBanks::SaveItemForm validates :item_type, presence: true, inclusion: {in: %W(SINGLE MULTIPLE JUDGMENT COMPLETION SUBJECTIVE PRACTICAL PROGRAM)} validates :difficulty, presence: true, inclusion: {in: 1..3}, numericality: { only_integer: true } validates :name, presence: true, length: { maximum: 1000 } - validates :analysis, length: { maximum: 1000 } + validates :analysis, length: { maximum: 5000 } def validate! super @@ -27,7 +27,7 @@ class ItemBanks::SaveItemForm attr_accessor :choice_text, :is_answer - validates :choice_text, presence: true, length: { maximum: 300 } + validates :choice_text, presence: true, length: { maximum: 500 } validates :is_answer, presence: true, inclusion: {in: 0..1}, numericality: { only_integer: true } end end \ No newline at end of file From 91d0fc605453d7d46b3814917afce8d95a5507fe Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Fri, 10 Jan 2020 11:46:38 +0800 Subject: [PATCH 052/156] =?UTF-8?q?=E8=AF=B7=E6=B1=82=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/routes.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/routes.rb b/config/routes.rb index a63776d44..7d85d66db 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -98,7 +98,7 @@ Rails.application.routes.draw do resources :examination_intelligent_settings do collection do - get :optinal_items + post :optinal_items end member do From 710a04162e1727f7cb653a9346f82d37782d0b12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Fri, 10 Jan 2020 11:57:35 +0800 Subject: [PATCH 053/156] =?UTF-8?q?=E9=A2=98=E5=BA=93=E6=99=BA=E8=83=BD?= =?UTF-8?q?=E7=BB=84=E5=8D=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/react/src/App.js | 16 ++- .../react/src/modules/question/Paperreview.js | 105 ++++++++++------ public/react/src/modules/question/Question.js | 2 +- .../question/component/Itembankstop.js | 6 +- .../comthetestpaper/Comthetestpaperst.js | 6 +- .../comthetestpaper/Intelligentcomponents.js | 38 +++--- .../comthetestpaper/lntlligentpone.js | 112 ++++++++++++++---- .../question/questioncss/questioncom.css | 1 + .../src/modules/testpaper/Intecomponents.js | 69 ++++++++++- .../testpaper/component/Contentpart.js | 2 +- 10 files changed, 265 insertions(+), 92 deletions(-) diff --git a/public/react/src/App.js b/public/react/src/App.js index 008cb12fe..dabe4a50d 100644 --- a/public/react/src/App.js +++ b/public/react/src/App.js @@ -758,6 +758,7 @@ class App extends Component { } } /> + () @@ -768,7 +769,14 @@ class App extends Component { render={ (props) => () } /> - + () + }/> + () + }/> () @@ -778,6 +786,7 @@ class App extends Component { render={ (props) => () }/> + () @@ -805,11 +814,6 @@ class App extends Component { (props) => () }/> - () - }/> - () diff --git a/public/react/src/modules/question/Paperreview.js b/public/react/src/modules/question/Paperreview.js index 680916d77..c0660d544 100644 --- a/public/react/src/modules/question/Paperreview.js +++ b/public/react/src/modules/question/Paperreview.js @@ -51,6 +51,7 @@ class Paperreview extends Component { name:null, duration:null, newmyshixunmodelbool:false, + artificialtype:"artificial", } // single_questions:null, 单选题 @@ -64,10 +65,27 @@ class Paperreview extends Component { //初始化 componentDidMount() { + console.log("Paperreview.js"); + console.log(this.props.match.params.type); + this.setState({ + artificialtype:this.props.match.params.type + }) + if(this.props.match.params.type==="artificial"){ + //人工组卷 + + var data = {} + this.getdata(data); + }else{ + //智能组卷 + // + var data = { + exam_setting_id:this.props.match.params.id + } + this.getdata(data); + } + - var data = {} - this.getdata(data); let urls = `/disciplines.json`; axios.get(urls, { params: { @@ -193,43 +211,51 @@ class Paperreview extends Component { } preservation = () => { //保存试卷 - if(this.state.Cohetepaperbool===true){ - if (this.contentMdRef.Getdatas().length === 0) { - this.scrollToAnchor("Itembankstopid"); - return; - } - var myrbkc=[]; - var Getdatasdatas=this.contentMdRef.Getdatas()[2].rbzsd; - for(let myda of Getdatasdatas) { - myrbkc.push(myda.id); - } - const url = `/examination_banks.json`; - var data={ - difficulty:this.contentMdRef.Getdatas()[0].rbnd, - name:this.contentMdRef.Getdatas()[4].classroom, - duration:this.contentMdRef.Getdatas()[5].kssc, - discipline_id: this.contentMdRef.Getdatas()[3].rbkc[0], - sub_discipline_id: this.contentMdRef.Getdatas()[3].rbkc[1], - tag_discipline_id: myrbkc, + if(this.state.artificialtype==="artificial"){ + if(this.state.Cohetepaperbool===true){ + if (this.contentMdRef.Getdatas().length === 0) { + this.scrollToAnchor("Itembankstopid"); + return; + } + var myrbkc=[]; + var Getdatasdatas=this.contentMdRef.Getdatas()[2].rbzsd; + for(let myda of Getdatasdatas) { + myrbkc.push(myda.id); + } + const url = `/examination_banks.json`; + var data={ + difficulty:this.contentMdRef.Getdatas()[0].rbnd, + name:this.contentMdRef.Getdatas()[4].classroom, + duration:this.contentMdRef.Getdatas()[5].kssc, + discipline_id: this.contentMdRef.Getdatas()[3].rbkc[0], + sub_discipline_id: this.contentMdRef.Getdatas()[3].rbkc[1], + tag_discipline_id: myrbkc, + } + axios.post(url, data) + .then((result) => { + if (result.data.status === 0) { + // this.props.showNotification(`组卷成功`); + this.props.history.replace('/paperlibrary'); + } + }).catch((error) => { + console.log(error); + }) + + }else{ + this.setCohetepaperbool(true); + } - axios.post(url, data) - .then((result) => { - if (result.data.status === 0) { - // this.props.showNotification(`组卷成功`); - this.props.history.replace('/paperlibrary'); - } - }).catch((error) => { - console.log(error); - }) }else{ - this.setCohetepaperbool(true); + //智能组卷 + } + } @@ -265,7 +291,7 @@ class Paperreview extends Component { this.getdata(data); } render() { - let {page, limit, count, Headertop, visible, placement, modalsType, item_type,Cohetepaperbool,newmyshixunmodelbool} = this.state; + let {page, limit, count, Headertop, visible, placement, modalsType, item_type,artificialtype,Cohetepaperbool,newmyshixunmodelbool} = this.state; const params = this.props && this.props.match && this.props.match.params; // //console.log(params); return ( @@ -305,11 +331,18 @@ class Paperreview extends Component {
    { Cohetepaperbool===false? - - 试题库 - 人工组卷 - 试卷预览 - + artificialtype==="artificial"? + + 试题库 + 人工组卷 + 试卷预览 + + : + + 试卷库 + 智能组卷 + 试卷预览 + : 试题库 diff --git a/public/react/src/modules/question/Question.js b/public/react/src/modules/question/Question.js index c6278db17..47343e091 100644 --- a/public/react/src/modules/question/Question.js +++ b/public/react/src/modules/question/Question.js @@ -759,7 +759,7 @@ class Question extends Component { //跳转 gotopaperreview=()=>{ - this.props.history.replace("/paperreview"); + this.props.history.replace("/paperreview/artificial"); } diff --git a/public/react/src/modules/question/component/Itembankstop.js b/public/react/src/modules/question/component/Itembankstop.js index 4e77bb524..4b3cfa0f6 100644 --- a/public/react/src/modules/question/component/Itembankstop.js +++ b/public/react/src/modules/question/component/Itembankstop.js @@ -367,15 +367,15 @@ class Itembankstop extends Component { }); } - handleFormLayoutChange = (value) => { + handleFormLayoutChange = (e) => { //难度塞选 ////console.log("难度塞选"); ////console.log(value); this.props.form.setFieldsValue({ - rbnd: value + "", + rbnd: e.target.value + "", }); this.setState({ - rbnd: value + "", + rbnd: e.target.value + "", }) } diff --git a/public/react/src/modules/question/comthetestpaper/Comthetestpaperst.js b/public/react/src/modules/question/comthetestpaper/Comthetestpaperst.js index 5116dcd61..64990f3dc 100644 --- a/public/react/src/modules/question/comthetestpaper/Comthetestpaperst.js +++ b/public/react/src/modules/question/comthetestpaper/Comthetestpaperst.js @@ -331,15 +331,15 @@ class Comthetestpaperst extends Component { }); } - handleFormLayoutChange = (value) => { + handleFormLayoutChange = (e) => { //难度塞选 ////console.log("难度塞选"); ////console.log(value); this.props.form.setFieldsValue({ - rbnd: value + "", + rbnd: e.target.value + "", }); this.setState({ - rbnd: value + "", + rbnd: e.target.value + "", }) } diff --git a/public/react/src/modules/question/comthetestpaper/Intelligentcomponents.js b/public/react/src/modules/question/comthetestpaper/Intelligentcomponents.js index c6ef50d90..c40961dbb 100644 --- a/public/react/src/modules/question/comthetestpaper/Intelligentcomponents.js +++ b/public/react/src/modules/question/comthetestpaper/Intelligentcomponents.js @@ -217,32 +217,38 @@ class Intelligentcomponents extends Component { }); } - handleFormLayoutChanges = (value) => { + handleFormLayoutChanges = (e) => { + // console.log("handleFormLayoutChanges"); + // console.log(value); + // debugger //来源 this.props.form.setFieldsValue({ - rbly: value + "", + rbly: e.target.value + "", }); this.setState({ - rbly: value + "", + rbly: e.target.value + "", }) } - handleFormLayoutChange = (value) => { + handleFormLayoutChange = (e) => { + // console.log("handleFormLayoutChange"); + // console.log(value); + // debugger //难度塞选 - ////console.log("难度塞选"); - ////console.log(value); this.props.form.setFieldsValue({ - rbnd: value + "", + rbnd: e.target.value + "", }); this.setState({ - rbnd: value + "", - }) + rbnd: e.target.value + "", + }); + try { + this.props.getdatass(parseInt(e.target.value)); + }catch (e) { + } } handleFormkechen = (value) => { //课程 - ////console.log("课程"); - ////console.log(value); if(this.state.Knowpoints.length>4){ this.props.showNotification(`知识点最多选择5个`); return @@ -263,8 +269,6 @@ class Intelligentcomponents extends Component { const _result =[]; this.state.knowledgepoints.filter(item => { if (this.state.Knowpoints.findIndex(t => t.id === item.id) === -1) { - console.log("guonue"); - console.log(item); _result.push(item); } }); @@ -762,16 +766,16 @@ class Intelligentcomponents extends Component {

    题型及数量

    - this.props.getdatas()} ref={dom => { + this.props.getdatas()} ref={dom => { this.$dxt = dom; }}> - this.props.getdatas()} ref={dom => { + this.props.getdatas()} ref={dom => { this.$ddxt = dom; }}> - this.props.getdatas()} ref={dom => { + this.props.getdatas()} ref={dom => { this.$pdt = dom; }}> - this.props.getdatas()} ref={dom => { + this.props.getdatas()} ref={dom => { this.$bct = dom; }}> diff --git a/public/react/src/modules/question/comthetestpaper/lntlligentpone.js b/public/react/src/modules/question/comthetestpaper/lntlligentpone.js index b7cbab974..d9c6527c1 100644 --- a/public/react/src/modules/question/comthetestpaper/lntlligentpone.js +++ b/public/react/src/modules/question/comthetestpaper/lntlligentpone.js @@ -12,7 +12,8 @@ import { Button, Breadcrumb, Icon, - InputNumber + InputNumber, + Tooltip } from "antd"; import '../questioncss/questioncom.css'; @@ -35,13 +36,33 @@ class lntlligentpone extends Component { } increase = () => { - this.props.getdatas(); + + const datasbool=this.props.getdatas(); + // if(datasbool===undefined || datasbool===null){ + // if(this.props.mycount===0){ + // this.props.showNotification(`题数为0无法增加题目`); + // return + // } + // + // } + const count = this.state.count + 1; - this.setState({count: count, countbool: false}); + if(count<=this.props.mycount){ + this.setState({count: count, countbool: false}); + } + + }; decline = () => { - this.props.getdatas(); + const datasbool=this.props.getdatas(); + // if(datasbool===undefined || datasbool===null){ + // if(this.props.mycount===0){ + // this.props.showNotification(`题数为0无法减少题目`); + // return + // } + // } + let count = this.state.count - 1; if (count < 0) { count = 0; @@ -49,8 +70,21 @@ class lntlligentpone extends Component { this.setState({count: count, countbool: false}); }; inputsnumber = (value) => { - this.props.getdatas(); - this.setState({count: value, countbool: false}); + const datasbool=this.props.getdatas(); + // if(datasbool===undefined || datasbool===null){ + // if(this.props.mycount===0){ + // this.setState({count: 0, countbool: false}); + // this.props.showNotification(`题数为0无法输入`); + // return + // } + // } + + if(this.props.mycount===0){ + this.setState({count: 0, countbool: false}); + }else { + this.setState({count: value, countbool: false}); + } + } @@ -73,23 +107,55 @@ class lntlligentpone extends Component { return (

    {this.props.dxtx}

    -
    - -
    - -
    - -

    共{this.props.dxgt}道

    -
    + { + this.props.mycount===0? +
    + + + +
    + + + + + +
    + + + + +

    共{this.props.mycount}道

    +
    + : + +
    + +
    + +
    + +

    共{this.props.mycount}道

    +
    + + } +
    ) diff --git a/public/react/src/modules/question/questioncss/questioncom.css b/public/react/src/modules/question/questioncss/questioncom.css index 47e3eb9b6..ae405001a 100644 --- a/public/react/src/modules/question/questioncss/questioncom.css +++ b/public/react/src/modules/question/questioncss/questioncom.css @@ -1000,6 +1000,7 @@ .inpustredssdiv button { border-radius: 50%; width: 38px; + height: 38px; display: flex; flex-direction: column; align-items: center; diff --git a/public/react/src/modules/testpaper/Intecomponents.js b/public/react/src/modules/testpaper/Intecomponents.js index d16e6ae80..ad8171ae0 100644 --- a/public/react/src/modules/testpaper/Intecomponents.js +++ b/public/react/src/modules/testpaper/Intecomponents.js @@ -30,6 +30,10 @@ class Intecomponents extends Component { disciplmy: [], item_banksedit: [], newmyshixunmodelbool:false, + single_question_count:0, + multiple_question_count:0, + judgement_question_count:0, + program_question_count:0, } @@ -107,12 +111,17 @@ class Intecomponents extends Component { } getdatas=()=>{ + if (this.Judquestio.Getdatas().length === 0) { + this.scrollToAnchor("Itembankstopid"); + return false; + } + console.log(this.Judquestio.Getdatas()); var myrbkc=[]; var Getdatasdatas=this.Judquestio.Getdatas()[1].rbzsd; for(let myda of Getdatasdatas) { myrbkc.push(myda.id); } - const url="/examination_intelligent_settings/optinal_items.jso"; + const url="/examination_intelligent_settings/optinal_items.json"; var data={ sub_discipline_id:this.Judquestio.Getdatas()[2].rbkc[1], tag_discipline_id:myrbkc, @@ -124,13 +133,63 @@ class Intecomponents extends Component { data }}).then((response) => { if (response) { + console.log("智能组卷"); console.log(response); + if(response.data){ + this.setState({ + single_question_count:response.data.single_question_count, + multiple_question_count:response.data.multiple_question_count, + judgement_question_count:response.data.judgement_question_count, + program_question_count:response.data.program_question_count, + }) + + } + } }); } + getdatass=(nandu)=>{ + debugger + if (this.Judquestio.Getdatas().length === 0) { + this.scrollToAnchor("Itembankstopid"); + return false; + } + console.log(this.Judquestio.Getdatas()); + var myrbkc=[]; + var Getdatasdatas=this.Judquestio.Getdatas()[1].rbzsd; + for(let myda of Getdatasdatas) { + myrbkc.push(myda.id); + } + const url="/examination_intelligent_settings/optinal_items.json"; + var data={ + sub_discipline_id:this.Judquestio.Getdatas()[2].rbkc[1], + tag_discipline_id:myrbkc, + source:this.Judquestio.Getdatas()[7].rbly, + difficulty:nandu, + } + + axios.get(url, {params: { + data + }}).then((response) => { + if (response) { + console.log("智能组卷"); + console.log(response); + if(response.data){ + this.setState({ + single_question_count:response.data.single_question_count, + multiple_question_count:response.data.multiple_question_count, + judgement_question_count:response.data.judgement_question_count, + program_question_count:response.data.program_question_count, + }) + } + + } + }); + + } componentDidUpdate(prevProps) { @@ -203,6 +262,7 @@ class Intecomponents extends Component { .then((result) => { if (result.data.status == 0) { console.log("组卷成功"); + this.props.history.push(`/IntegenerationSee/Intelligence/${result.data.exam_setting_id}`); } }).catch((error) => { console.log(error); @@ -228,7 +288,7 @@ class Intecomponents extends Component { } render() { - let {paperlibrartdata,newmyshixunmodelbool} = this.state; + let {paperlibrartdata,newmyshixunmodelbool,single_question_count,multiple_question_count,judgement_question_count,program_question_count} = this.state; const params = this.props && this.props.match && this.props.match.params; return (
    @@ -252,7 +312,12 @@ class Intecomponents extends Component {
    this.getdatas()} + getdatass={(nd)=>this.getdatass(nd)} getJudquestio={(ref) => this.getJudquestio(ref)} > diff --git a/public/react/src/modules/testpaper/component/Contentpart.js b/public/react/src/modules/testpaper/component/Contentpart.js index 97db4844b..9df40b455 100644 --- a/public/react/src/modules/testpaper/component/Contentpart.js +++ b/public/react/src/modules/testpaper/component/Contentpart.js @@ -161,7 +161,7 @@ class Contentpart extends Component { width:"50%" }}> - +

    智能组卷

    From cdd5460653b059cee1c38b5f4cf2672fe1fc869b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Fri, 10 Jan 2020 12:03:23 +0800 Subject: [PATCH 054/156] =?UTF-8?q?=E9=A2=98=E5=BA=93=E6=99=BA=E8=83=BD?= =?UTF-8?q?=E7=BB=84=E5=8D=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/react/src/modules/testpaper/Intecomponents.js | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/public/react/src/modules/testpaper/Intecomponents.js b/public/react/src/modules/testpaper/Intecomponents.js index ad8171ae0..d393bdd7a 100644 --- a/public/react/src/modules/testpaper/Intecomponents.js +++ b/public/react/src/modules/testpaper/Intecomponents.js @@ -129,9 +129,7 @@ class Intecomponents extends Component { difficulty:this.Judquestio.Getdatas()[0].rbnd, } - axios.get(url, {params: { - data - }}).then((response) => { + axios.post(url,data).then((response) => { if (response) { console.log("智能组卷"); console.log(response); @@ -151,7 +149,6 @@ class Intecomponents extends Component { } getdatass=(nandu)=>{ - debugger if (this.Judquestio.Getdatas().length === 0) { this.scrollToAnchor("Itembankstopid"); return false; @@ -170,9 +167,7 @@ class Intecomponents extends Component { difficulty:nandu, } - axios.get(url, {params: { - data - }}).then((response) => { + axios.post(url,data).then((response) => { if (response) { console.log("智能组卷"); console.log(response); From 73f62a989d962edaa1eac9f9502d0c65b444de7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Fri, 10 Jan 2020 14:08:55 +0800 Subject: [PATCH 055/156] =?UTF-8?q?=E9=A2=98=E5=BA=93=E6=99=BA=E8=83=BD?= =?UTF-8?q?=E7=BB=84=E5=8D=B7=E6=8D=A2=E9=A2=98=E5=9E=8B=20=E6=8D=A2?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/react/src/App.js | 2 +- .../react/src/modules/question/Paperreview.js | 49 ++++++++++++------- .../src/modules/question/Paperreview_item.js | 36 ++++++++++++++ .../src/modules/question/Paperreview_items.js | 6 +++ .../modules/question/Paperreview_single.js | 23 +++++++-- .../modules/question/component/Listjihe.js | 29 +++++++++-- .../comthetestpaper/Intelligentcomponents.js | 36 ++++++++------ .../question/questioncss/questioncom.css | 11 +++++ .../src/modules/testpaper/Intecomponents.js | 2 +- .../component/Paperlibraryseeid_items.js | 18 ++++++- 10 files changed, 171 insertions(+), 41 deletions(-) diff --git a/public/react/src/App.js b/public/react/src/App.js index dabe4a50d..247e7939b 100644 --- a/public/react/src/App.js +++ b/public/react/src/App.js @@ -769,7 +769,7 @@ class App extends Component { render={ (props) => () } /> - () }/> diff --git a/public/react/src/modules/question/Paperreview.js b/public/react/src/modules/question/Paperreview.js index c0660d544..dc60b7594 100644 --- a/public/react/src/modules/question/Paperreview.js +++ b/public/react/src/modules/question/Paperreview.js @@ -66,26 +66,12 @@ class Paperreview extends Component { //初始化 componentDidMount() { console.log("Paperreview.js"); - console.log(this.props.match.params.type); + console.log(this.props.match.params); this.setState({ artificialtype:this.props.match.params.type }) - if(this.props.match.params.type==="artificial"){ - //人工组卷 - - var data = {} - this.getdata(data); - }else{ - //智能组卷 - // - var data = { - exam_setting_id:this.props.match.params.id - } + var data = {}; this.getdata(data); - } - - - let urls = `/disciplines.json`; axios.get(urls, { params: { @@ -148,6 +134,18 @@ class Paperreview extends Component { getdata = (data) => { + + if(this.props.match.params.type==="artificial"){ + //人工组卷 + + + }else{ + //智能组卷 + // + data = { + exam_setting_id:this.props.match.params.id + } + } const url = `/item_baskets.json`; this.setState({ booljupyterurls: true, @@ -290,6 +288,23 @@ class Paperreview extends Component { var data = {} this.getdata(data); } + + //换题型 + Replacementtype=(value)=>{ + console.log("换题型"); + console.log(value); + + } + //换题 + Changingtopics=(value)=>{ + console.log("换题"); + console.log(value); + } + + + + + render() { let {page, limit, count, Headertop, visible, placement, modalsType, item_type,artificialtype,Cohetepaperbool,newmyshixunmodelbool} = this.state; const params = this.props && this.props.match && this.props.match.params; @@ -354,7 +369,7 @@ class Paperreview extends Component { { Cohetepaperbool===false? - this.getdata(data)} setnewmyshixunmodelbool={(e)=>this.setnewmyshixunmodelbool(e)}> + this.Changingtopics(e)} Replacementtype={(e)=>this.Replacementtype(e)} getdata={(data)=>this.getdata(data)} setnewmyshixunmodelbool={(e)=>this.setnewmyshixunmodelbool(e)}> : diff --git a/public/react/src/modules/question/Paperreview_item.js b/public/react/src/modules/question/Paperreview_item.js index a9747e8c2..02980d1bb 100644 --- a/public/react/src/modules/question/Paperreview_item.js +++ b/public/react/src/modules/question/Paperreview_item.js @@ -460,6 +460,12 @@ class Paperreview_item extends Component { singlebool === true ?
    this.setmodalsTypedel(true, 1, "SINGLE")}>删除
    + { + this.props.match.params.type==="Intelligence"? +
    this.props.Replacementtype("单选题")}>换题型
    + : + "" + }
    this.Singlemagazine("单选题", true)}>批量设置得分
    : "" } @@ -490,6 +496,9 @@ class Paperreview_item extends Component { > this.Changingtopics(e)} key={index} paperreviewsingleindex={this.state.paperreviewsingleindex} paperreviewsinglename={this.state.paperreviewsinglename} @@ -547,6 +556,12 @@ class Paperreview_item extends Component {
    this.setmodalsTypedel(true, 1, "MULTIPLE")}>删除
    + { + this.props.match.params.type==="Intelligence"? +
    this.props.Replacementtype("多选题")}>换题型
    + : + "" + }
    this.Singlemagazine("多选题", true)}>批量设置得分
    @@ -582,6 +597,9 @@ class Paperreview_item extends Component { this.Changingtopics(e)} key={index} paperreviewsingleindex={this.state.paperreviewsingleindex} paperreviewsinglename={this.state.paperreviewsinglename} @@ -637,6 +655,12 @@ class Paperreview_item extends Component {
    this.setmodalsTypedel(true, 1, "JUDGMENT")}>删除
    + { + this.props.match.params.type==="Intelligence"? +
    this.props.Replacementtype("判断题")}>换题型
    + : + "" + }
    this.Singlemagazine("判断题", true)}>批量设置得分
    : ""} @@ -669,6 +693,9 @@ class Paperreview_item extends Component { this.Changingtopics(e)} key={index} paperreviewsingleindex={this.state.paperreviewsingleindex} paperreviewsinglename={this.state.paperreviewsinglename} @@ -728,6 +755,12 @@ class Paperreview_item extends Component { programbool === true ?
    this.setmodalsTypedel(true, 1, "PROGRAM")}>删除
    + { + this.props.match.params.type==="Intelligence"? +
    this.props.Replacementtype("编程题")}>换题型
    + : + "" + }
    this.Singlemagazine("编程题", true)}>批量设置得分
    : "" @@ -761,6 +794,9 @@ class Paperreview_item extends Component { this.Changingtopics(e)} key={index} paperreviewsingleindex={this.state.paperreviewsingleindex} paperreviewsinglename={this.state.paperreviewsinglename} diff --git a/public/react/src/modules/question/Paperreview_items.js b/public/react/src/modules/question/Paperreview_items.js index 8e86c514a..fde883105 100644 --- a/public/react/src/modules/question/Paperreview_items.js +++ b/public/react/src/modules/question/Paperreview_items.js @@ -67,6 +67,12 @@ class Paperreview_items extends Component { paperreviewsingleindex===indexs&&paperreviewsinglename===typenames?
    this.props.showsetmodalsTypedels(object.item_id,true,1)}>删除
    + { + this.props.match.params.type==="Intelligence"? +
    this.props.Changingtopics(object.item_id)}>换题
    + : + "" + }
    this.props.Singlemagazines(true,object.id,typenamesn)}>设置得分
    :
    diff --git a/public/react/src/modules/question/Paperreview_single.js b/public/react/src/modules/question/Paperreview_single.js index fdc9ff095..71c641847 100644 --- a/public/react/src/modules/question/Paperreview_single.js +++ b/public/react/src/modules/question/Paperreview_single.js @@ -76,10 +76,20 @@ class Paperreview_single extends Component { try { itemssname= JSON.parse(objectsingle.name); }catch (e) { + itemssname=objectsingle.name; } if(itemssname===undefined){ itemssname=objectsingle.name } + + var itemsnamesy=""; + try { + itemsnamesy= JSON.parse(objectsingle&&objectsingle.program_attr&&objectsingle.program_attr.description); + + }catch (e) { + itemsnamesy=objectsingle&&objectsingle.program_attr&&objectsingle.program_attr.description; + } + return (

    : @@ -199,8 +209,15 @@ class Paperreview_single extends Component {

    { objectsingle === undefined || objectsingle === null ? "" : objectsingle.choices.map((object, index) => { + var string="" + try { + string=JSON.parse(object.choice_text); + }catch (e) { + string=object.choice_text; + } + return ( -

    +

    {tagArray[index]}

    {object ? @@ -210,7 +227,7 @@ class Paperreview_single extends Component { object.choice_text.length>0? :"" : diff --git a/public/react/src/modules/question/component/Listjihe.js b/public/react/src/modules/question/component/Listjihe.js index 695fe77fd..408575053 100644 --- a/public/react/src/modules/question/component/Listjihe.js +++ b/public/react/src/modules/question/component/Listjihe.js @@ -135,6 +135,23 @@ class Listjihe extends Component { itemssname=items.name } + + var itemsnamesy=""; + try { + itemsnamesy= JSON.parse(items&&items.program_attr&&items.program_attr.description); + + }catch (e) { + itemsnamesy=items&&items.program_attr&&items.program_attr.description; + } + + var analysisnames=""; + try { + analysisnames= JSON.parse(items&&items.analysis); + + }catch (e) { + analysisnames=items&&items.analysis; + } + return (

    @@ -217,7 +234,7 @@ class Listjihe extends Component { >

    @@ -232,6 +249,12 @@ class Listjihe extends Component {

    { items === undefined || items === null ? "" : items.choices.map((object, index) => { + var string="" + try { + string=JSON.parse(object.choice_text); + }catch (e) { + string=object.choice_text; + } return (

    {tagArray[index]}

    @@ -244,7 +267,7 @@ class Listjihe extends Component { object.choice_text.length>0? :"" @@ -425,7 +448,7 @@ class Listjihe extends Component { : "" diff --git a/public/react/src/modules/question/comthetestpaper/Intelligentcomponents.js b/public/react/src/modules/question/comthetestpaper/Intelligentcomponents.js index c40961dbb..f80f44d66 100644 --- a/public/react/src/modules/question/comthetestpaper/Intelligentcomponents.js +++ b/public/react/src/modules/question/comthetestpaper/Intelligentcomponents.js @@ -764,21 +764,29 @@ class Intelligentcomponents extends Component { -

    题型及数量

    -
    - this.props.getdatas()} ref={dom => { - this.$dxt = dom; - }}> - this.props.getdatas()} ref={dom => { - this.$ddxt = dom; - }}> - this.props.getdatas()} ref={dom => { - this.$pdt = dom; - }}> - this.props.getdatas()} ref={dom => { - this.$bct = dom; - }}> + { + this.props.single_question_count===0&&this.props.multiple_question_count===0&&this.props.judgement_question_count===0&& + this.props.program_question_count===0? + "" + : +
    +

    题型及数量

    +
    + this.props.getdatas()} ref={dom => { + this.$dxt = dom; + }}> + this.props.getdatas()} ref={dom => { + this.$ddxt = dom; + }}> + this.props.getdatas()} ref={dom => { + this.$pdt = dom; + }}> + this.props.getdatas()} ref={dom => { + this.$bct = dom; + }}> +
    + }
    diff --git a/public/react/src/modules/question/questioncss/questioncom.css b/public/react/src/modules/question/questioncss/questioncom.css index ae405001a..b9d2264fc 100644 --- a/public/react/src/modules/question/questioncss/questioncom.css +++ b/public/react/src/modules/question/questioncss/questioncom.css @@ -760,6 +760,17 @@ font-size:12px; } +.szdfds{ + width:100px; + height:40px; + background:#FC7E30; + border-radius:4px 4px 0px 0px; + text-align: center; + color: #ffffff; + line-height: 40px; + margin-right: 27px; + font-size:12px; +} .pd20{ padding: 20px; diff --git a/public/react/src/modules/testpaper/Intecomponents.js b/public/react/src/modules/testpaper/Intecomponents.js index d393bdd7a..60903af14 100644 --- a/public/react/src/modules/testpaper/Intecomponents.js +++ b/public/react/src/modules/testpaper/Intecomponents.js @@ -257,7 +257,7 @@ class Intecomponents extends Component { .then((result) => { if (result.data.status == 0) { console.log("组卷成功"); - this.props.history.push(`/IntegenerationSee/Intelligence/${result.data.exam_setting_id}`); + this.props.history.push(`/Integeneration/Intelligence/${result.data.exam_setting_id}`); } }).catch((error) => { console.log(error); diff --git a/public/react/src/modules/testpaper/component/Paperlibraryseeid_items.js b/public/react/src/modules/testpaper/component/Paperlibraryseeid_items.js index 0a6a718c3..7747574dd 100644 --- a/public/react/src/modules/testpaper/component/Paperlibraryseeid_items.js +++ b/public/react/src/modules/testpaper/component/Paperlibraryseeid_items.js @@ -78,6 +78,14 @@ class Paperlibraryseeid_items extends Component { if(itemssname===undefined){ itemssname=objectsingle.name } + + var itemsnamesy=""; + try { + itemsnamesy= JSON.parse(objectsingle&&objectsingle.program_attr&&objectsingle.program_attr.description); + + }catch (e) { + itemsnamesy=objectsingle&&objectsingle.program_attr&&objectsingle.program_attr.description; + } return (

    : @@ -196,6 +204,12 @@ class Paperlibraryseeid_items extends Component {

    { objectsingle === undefined || objectsingle === null ? "" : objectsingle.choices.map((object, index) => { + var string="" + try { + string=JSON.parse(object.choice_text); + }catch (e) { + string=object.choice_text; + } return (

    {tagArray[index]} @@ -207,7 +221,7 @@ class Paperlibraryseeid_items extends Component { object.choice_text.length>0? :"" : From cea60c87d52ec64598f01a27454176b0d7205a3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Fri, 10 Jan 2020 15:08:21 +0800 Subject: [PATCH 056/156] =?UTF-8?q?=E9=A2=98=E5=BA=93=E6=99=BA=E8=83=BD?= =?UTF-8?q?=E7=BB=84=E5=8D=B7=20=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../react/src/modules/question/Paperreview.js | 108 ++++++++--- .../src/modules/question/Paperreview_item.js | 20 +- .../question/component/IntelligentModel.js | 181 ++++++++++++++++++ .../question/questioncss/questioncom.css | 8 + 4 files changed, 285 insertions(+), 32 deletions(-) create mode 100644 public/react/src/modules/question/component/IntelligentModel.js diff --git a/public/react/src/modules/question/Paperreview.js b/public/react/src/modules/question/Paperreview.js index dc60b7594..c056452b4 100644 --- a/public/react/src/modules/question/Paperreview.js +++ b/public/react/src/modules/question/Paperreview.js @@ -25,6 +25,7 @@ import Paperreview_item from "./Paperreview_item" import Bottomsubmit from "../../modules/modals/Bottomsubmit"; import Comthetestpaperst from "./comthetestpaper/Comthetestpaperst"; import NewMyShixunModel from "../question/NewMyShixunModel"; +import IntelligentModel from "../question/component/IntelligentModel" //人工组卷预览 class Paperreview extends Component { constructor(props) { @@ -52,6 +53,7 @@ class Paperreview extends Component { duration:null, newmyshixunmodelbool:false, artificialtype:"artificial", + Intelligentformation:false, } // single_questions:null, 单选题 @@ -246,7 +248,7 @@ class Paperreview extends Component { }else{ //智能组卷 - + this.setIntelligentformation(true); } @@ -272,47 +274,103 @@ class Paperreview extends Component { } setnewmyshixunmodelbool=(bool)=>{ - if(bool===true){ - let scrollToTop = window.setInterval(function() { - let pos = window.pageYOffset; - if ( pos > 0 ) { - window.scrollTo( 0, pos - 20 ); // how far to scroll on each step - } else { - window.clearInterval( scrollToTop ); - } - }, 2); - } - this.setState({ - newmyshixunmodelbool:bool - }) - var data = {} - this.getdata(data); + //人工组卷 + if(bool===true){ + let scrollToTop = window.setInterval(function() { + let pos = window.pageYOffset; + if ( pos > 0 ) { + window.scrollTo( 0, pos - 20 ); // how far to scroll on each step + } else { + window.clearInterval( scrollToTop ); + } + }, 2); + } + this.setState({ + newmyshixunmodelbool:bool + }) + var data = {} + this.getdata(data); + + + + } //换题型 Replacementtype=(value)=>{ - console.log("换题型"); - console.log(value); + var item_types=""; + if(value==="单选题"){ + item_types="SINGLE"; + } + else if(value==="多选题"){ + item_types="MULTIPLE"; + + } + else if(value==="判断题"){ + item_types="JUDGMENT"; + + } + else if(value==="编程题"){ + item_types="PROGRAM"; + } + const url=`/examination_intelligent_settings/${this.props.match.params.id}/exchange_items.json`; + let data={ + item_type:item_types, + } + axios.post(url, data) + .then((result) => { + if (result.data.status == 0) { + console.log(result); + var data = {} + this.getdata(data); + } + }).catch((error) => { + console.log(error); + }) } //换题 - Changingtopics=(value)=>{ - console.log("换题"); - console.log(value); + Changingtopics=(id)=>{ + const url=`/examination_intelligent_settings/${this.props.match.params.id}/exchange_one_item.json`; + let data={ + item_id:id, + } + axios.post(url, data) + .then((result) => { + if (result.data.status == 0) { + console.log(result); + var data = {} + this.getdata(data); + } + }).catch((error) => { + console.log(error); + }) } + setIntelligentformation=(bool)=>{ + this.setState({ + Intelligentformation:bool + }) + } + Confirmationofvolumeformations=()=>{ + this.setState({ + Intelligentformation:false + }) - - - + } render() { - let {page, limit, count, Headertop, visible, placement, modalsType, item_type,artificialtype,Cohetepaperbool,newmyshixunmodelbool} = this.state; + let {page, limit, count, Headertop, visible, placement, modalsType, item_type,artificialtype,Cohetepaperbool,newmyshixunmodelbool,Intelligentformation} = this.state; const params = this.props && this.props.match && this.props.match.params; // //console.log(params); return (

    + { + Intelligentformation===true? + this.Confirmationofvolumeformations()}> + :"" + } { newmyshixunmodelbool===true? +
    + +
    + + {getFieldDecorator('classroom', { + rules: [{required: true, message: "不能为空"}], + })( + + + + + )} +
    +
    +
    + +
    + +
    + + + {getFieldDecorator('kssc')()} + 分钟 + +
    + + + +
    提示:组卷完成后,在试卷库—我的试卷库查看!
    + +
    +
    + + ) + } +} + +const IntelligentModels = Form.create({name: 'IntelligentModel'})(IntelligentModel); +export default IntelligentModels; diff --git a/public/react/src/modules/question/questioncss/questioncom.css b/public/react/src/modules/question/questioncss/questioncom.css index b9d2264fc..bc3350525 100644 --- a/public/react/src/modules/question/questioncss/questioncom.css +++ b/public/react/src/modules/question/questioncss/questioncom.css @@ -1033,3 +1033,11 @@ .mr12{ margin-right: 12px; } +.tishiyuyan{ + color: #888888 !important; + font-size:14px; +} +.tishiyuyans{ + color: #4CACFF !important; + font-size:14px; +} From a85d7bbb37e44a0c0f5d9cd101b851adadc84aad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Fri, 10 Jan 2020 15:23:35 +0800 Subject: [PATCH 057/156] =?UTF-8?q?=E9=A2=98=E5=BA=93=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../react/src/modules/question/Paperreview.js | 2 +- .../question/component/IntelligentModel.js | 28 +++++++++++++++---- .../comthetestpaper/Comthetestpaperst.js | 2 +- .../question/questioncss/questioncom.css | 21 ++++++++++++++ 4 files changed, 45 insertions(+), 8 deletions(-) diff --git a/public/react/src/modules/question/Paperreview.js b/public/react/src/modules/question/Paperreview.js index c056452b4..b321a40a2 100644 --- a/public/react/src/modules/question/Paperreview.js +++ b/public/react/src/modules/question/Paperreview.js @@ -368,7 +368,7 @@ class Paperreview extends Component { > { Intelligentformation===true? - this.Confirmationofvolumeformations()}> + this.getdata(data)} {...this.state} {...this.props} exam_id={this.props.match.params.id} Confirmationofvolumeformations={()=>this.Confirmationofvolumeformations()}> :"" } { diff --git a/public/react/src/modules/question/component/IntelligentModel.js b/public/react/src/modules/question/component/IntelligentModel.js index 565990bb5..502e1938a 100644 --- a/public/react/src/modules/question/component/IntelligentModel.js +++ b/public/react/src/modules/question/component/IntelligentModel.js @@ -48,8 +48,23 @@ class IntelligentModel extends Component { Confirmationofvolumeformation=()=>{ this.props.form.validateFields((err, values) => { if (!err) { - console.log("Confirmationofvolumeformation"); - console.log(values); + const url=`/examination_intelligent_settings/${this.props.exam_id}/save_exam.json`; + let data={ + name:values.classroom, + duration:values.kssc + } + axios.post(url, data) + .then((result) => { + if (result.data.status == 0) { + console.log(result); + this.props.history.push(`/paperlibrary`); + } + }).catch((error) => { + console.log(error); + }) + + + } }); @@ -127,7 +142,7 @@ class IntelligentModel extends Component { className={"fl construction yslzxueshis "} dataSource={optionss} > - + )}
    @@ -165,12 +180,13 @@ class IntelligentModel extends Component { -
    提示:组卷完成后,在试卷库—我的试卷库查看!
    +
    提示:组卷完成后,在试卷库—我的试卷库查看!
    + ) diff --git a/public/react/src/modules/question/comthetestpaper/Comthetestpaperst.js b/public/react/src/modules/question/comthetestpaper/Comthetestpaperst.js index 64990f3dc..c3bc094c5 100644 --- a/public/react/src/modules/question/comthetestpaper/Comthetestpaperst.js +++ b/public/react/src/modules/question/comthetestpaper/Comthetestpaperst.js @@ -761,7 +761,7 @@ class Comthetestpaperst extends Component { className={"fl construction yslzxueshis "} dataSource={optionss} > - + )}
    diff --git a/public/react/src/modules/question/questioncss/questioncom.css b/public/react/src/modules/question/questioncss/questioncom.css index bc3350525..e69162010 100644 --- a/public/react/src/modules/question/questioncss/questioncom.css +++ b/public/react/src/modules/question/questioncss/questioncom.css @@ -1041,3 +1041,24 @@ color: #4CACFF !important; font-size:14px; } +.tikutask-btn{ + width:80px; + height:34px; + background:rgba(204,204,204,1); + border-radius:4px; +} +.tikutask-btns{ + width:80px; + height:34px; + background:rgba(76,172,255,1); + border-radius:4px; +} +.w100{ + width: 100px !important; +} +.h34{ + height: 34px !important; +} +.lh34{ + line-height: 34px !important; +} From 48b80e8c38093bb2f75bbd718a79feec571a68a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=98=8E?= <775174143@qq.com> Date: Fri, 10 Jan 2020 15:34:22 +0800 Subject: [PATCH 058/156] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/images/educoder/xcx/SMIDCard.png | Bin 0 -> 7361 bytes public/images/educoder/xcx/ZYIDCard.png | Bin 0 -> 5539 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 public/images/educoder/xcx/SMIDCard.png create mode 100644 public/images/educoder/xcx/ZYIDCard.png diff --git a/public/images/educoder/xcx/SMIDCard.png b/public/images/educoder/xcx/SMIDCard.png new file mode 100644 index 0000000000000000000000000000000000000000..cea96596d10130744accaa84dcfab8b0ed87a1dc GIT binary patch literal 7361 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 literal 0 HcmV?d00001 diff --git a/public/images/educoder/xcx/ZYIDCard.png b/public/images/educoder/xcx/ZYIDCard.png new file mode 100644 index 0000000000000000000000000000000000000000..7f2085fce564fdcc67cd6392fd7e8063321db867 GIT binary patch literal 5539 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 Date: Fri, 10 Jan 2020 15:58:44 +0800 Subject: [PATCH 059/156] =?UTF-8?q?=E9=A2=98=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../react/src/modules/modals/Bottomsubmit.js | 1 - .../question/component/IntelligentModel.js | 34 +++++- .../question/component/Itembankstop.js | 13 ++- .../comthetestpaper/Comthetestpaperst.js | 17 ++- .../comthetestpaper/Intelligentcomponents.js | 31 ++++- .../src/modules/testpaper/Intecomponents.js | 106 +++++++++++++++--- 6 files changed, 178 insertions(+), 24 deletions(-) diff --git a/public/react/src/modules/modals/Bottomsubmit.js b/public/react/src/modules/modals/Bottomsubmit.js index 670049003..16174c480 100644 --- a/public/react/src/modules/modals/Bottomsubmit.js +++ b/public/react/src/modules/modals/Bottomsubmit.js @@ -12,7 +12,6 @@ class Bottomsubmit extends Component { cannelfun = () => { // window.location.href= - debugger if(this.props.Cohetepaperbool===true){ this.props.setCohetepaperbool(false); }else { diff --git a/public/react/src/modules/question/component/IntelligentModel.js b/public/react/src/modules/question/component/IntelligentModel.js index 502e1938a..fecef37d0 100644 --- a/public/react/src/modules/question/component/IntelligentModel.js +++ b/public/react/src/modules/question/component/IntelligentModel.js @@ -24,7 +24,7 @@ class IntelligentModel extends Component { constructor(props) { super(props); this.state={ - + iconLoading:false, } } @@ -46,8 +46,12 @@ class IntelligentModel extends Component { }; Confirmationofvolumeformation=()=>{ + this.props.form.validateFields((err, values) => { if (!err) { + this.setState({ + iconLoading:true + }) const url=`/examination_intelligent_settings/${this.props.exam_id}/save_exam.json`; let data={ name:values.classroom, @@ -58,10 +62,21 @@ class IntelligentModel extends Component { if (result.data.status == 0) { console.log(result); this.props.history.push(`/paperlibrary`); + } + setTimeout(() => { + this.setState({ + iconLoading:false + }) + }, 1500) + }).catch((error) => { - console.log(error); - }) + setTimeout(() => { + this.setState({ + iconLoading:false + }) + }, 1500) + }) @@ -73,6 +88,7 @@ class IntelligentModel extends Component { render() { + let {iconLoading}=this.state; const {getFieldDecorator} = this.props.form; const optionss = this.state.searchlist && this.state.searchlist.map(d => ); var addonAfterthree=this.props.form&&this.props.form.getFieldValue('classroom'); @@ -180,13 +196,21 @@ class IntelligentModel extends Component { -
    提示:组卷完成后,在试卷库—我的试卷库查看!
    +
    提示:组卷完成后,在试卷库—我的试卷库查看!
    ) diff --git a/public/react/src/modules/question/component/Itembankstop.js b/public/react/src/modules/question/component/Itembankstop.js index 4b3cfa0f6..5a2fc7b9c 100644 --- a/public/react/src/modules/question/component/Itembankstop.js +++ b/public/react/src/modules/question/component/Itembankstop.js @@ -200,7 +200,7 @@ class Itembankstop extends Component { this.handleFormtixing(this.props.item_banksedit.item_type); } if (this.props.item_banksedit.difficulty) { - this.handleFormLayoutChange(this.props.item_banksedit.difficulty); + this.handleFormLayoutChangeysl(this.props.item_banksedit.difficulty); } if (this.props.item_banksedit.tag_disciplines) { this.handletag_disciplinesChange(this.props.item_banksedit.tag_disciplines); @@ -366,7 +366,18 @@ class Itembankstop extends Component { }); } + handleFormLayoutChangeysl = (value) => { + //难度塞选 + ////console.log("难度塞选"); + ////console.log(value); + this.props.form.setFieldsValue({ + rbnd: value+ "", + }); + this.setState({ + rbnd: value + "", + }) + } handleFormLayoutChange = (e) => { //难度塞选 ////console.log("难度塞选"); diff --git a/public/react/src/modules/question/comthetestpaper/Comthetestpaperst.js b/public/react/src/modules/question/comthetestpaper/Comthetestpaperst.js index c3bc094c5..c01ae95c8 100644 --- a/public/react/src/modules/question/comthetestpaper/Comthetestpaperst.js +++ b/public/react/src/modules/question/comthetestpaper/Comthetestpaperst.js @@ -131,7 +131,9 @@ class Comthetestpaperst extends Component { // this.handleFormtixing(this.props.item_banksedit.item_type); // } if (this.props.item_banksedit.difficulty) { - this.handleFormLayoutChange(this.props.item_banksedit.difficulty); + // this.handleFormLayoutChange(this.props.item_banksedit.difficulty); + this.handleFormLayoutChangeysl(this.props.item_banksedit.difficulty); + } if (this.props.item_banksedit.tag_disciplines) { this.handletag_disciplinesChange(this.props.item_banksedit.tag_disciplines); @@ -330,11 +332,24 @@ class Comthetestpaperst extends Component { }); } + handleFormLayoutChangeysl = (value) => { + //难度塞选 + ////console.log("难度塞选"); + ////console.log(value); + this.props.form.setFieldsValue({ + rbnd: value + "", + }); + this.setState({ + rbnd: value + "", + }) + + } handleFormLayoutChange = (e) => { //难度塞选 ////console.log("难度塞选"); ////console.log(value); + this.props.form.setFieldsValue({ rbnd: e.target.value + "", }); diff --git a/public/react/src/modules/question/comthetestpaper/Intelligentcomponents.js b/public/react/src/modules/question/comthetestpaper/Intelligentcomponents.js index f80f44d66..43deace7d 100644 --- a/public/react/src/modules/question/comthetestpaper/Intelligentcomponents.js +++ b/public/react/src/modules/question/comthetestpaper/Intelligentcomponents.js @@ -229,6 +229,12 @@ class Intelligentcomponents extends Component { rbly: e.target.value + "", }) + try { + this.props.getdatassssy(e.target.value); + }catch (e) { + + } + } handleFormLayoutChange = (e) => { // console.log("handleFormLayoutChange"); @@ -280,6 +286,12 @@ class Intelligentcomponents extends Component { knowledgepoints2: _result, }) + try { + this.props.getdatassss(this.state.Knowpoints); + }catch (e) { + + } + } handleFormzhishidian = (value) => { @@ -334,6 +346,12 @@ class Intelligentcomponents extends Component { this.setState({ rbzsd: undefined, }) + + try { + this.props.getdatasss(parseInt(value[1])); + }catch (e) { + + } } handleFormtixing = (value) => { @@ -353,7 +371,7 @@ class Intelligentcomponents extends Component { ////console.log('Clicked! But prevent default.'); } deletesobject = (item, index) => { - debugger + var tmp = this.state.Knowpoints; for (var i = 0; i < tmp.length; i++) { if (i ===index) { @@ -390,6 +408,12 @@ class Intelligentcomponents extends Component { } } + //删除知识点 + try { + this.props.getdatassss(this.state.Knowpoints); + }catch (e) { + + } } @@ -476,7 +500,12 @@ class Intelligentcomponents extends Component { }).catch((error) => { //console.log(error); }) + //新增知识点 + try { + this.getdatassss(this.state.Knowpoints); + }catch (e) { + } this.setState({ NewknTypedel:false }) diff --git a/public/react/src/modules/testpaper/Intecomponents.js b/public/react/src/modules/testpaper/Intecomponents.js index 60903af14..a69d7185b 100644 --- a/public/react/src/modules/testpaper/Intecomponents.js +++ b/public/react/src/modules/testpaper/Intecomponents.js @@ -110,6 +110,7 @@ class Intecomponents extends Component { } + //难度 getdatas=()=>{ if (this.Judquestio.Getdatas().length === 0) { this.scrollToAnchor("Itembankstopid"); @@ -129,25 +130,96 @@ class Intecomponents extends Component { difficulty:this.Judquestio.Getdatas()[0].rbnd, } - axios.post(url,data).then((response) => { - if (response) { - console.log("智能组卷"); - console.log(response); - if(response.data){ - this.setState({ - single_question_count:response.data.single_question_count, - multiple_question_count:response.data.multiple_question_count, - judgement_question_count:response.data.judgement_question_count, - program_question_count:response.data.program_question_count, - }) + this.getwangluodata(url,data); - } + } + //课程 + getdatasss=(kech)=>{ + if (this.Judquestio.Getdatas().length === 0) { + this.scrollToAnchor("Itembankstopid"); + return false; + } + console.log(this.Judquestio.Getdatas()); + var myrbkc=[]; + var Getdatasdatas=this.Judquestio.Getdatas()[1].rbzsd; + for(let myda of Getdatasdatas) { + myrbkc.push(myda.id); + } + const url="/examination_intelligent_settings/optinal_items.json"; + var data={ + sub_discipline_id:kech, + tag_discipline_id:myrbkc, + source:this.Judquestio.Getdatas()[7].rbly, + difficulty:this.Judquestio.Getdatas()[0].rbnd, + } + + this.getwangluodata(url,data); - } - }); + } + //知识点 + getdatassss=(zhishidian)=>{ + if (this.Judquestio.Getdatas().length === 0) { + this.scrollToAnchor("Itembankstopid"); + return false; + } + console.log(this.Judquestio.Getdatas()); + var myrbkc=[]; + var Getdatasdatas=zhishidian; + for(let myda of Getdatasdatas) { + myrbkc.push(myda.id); + } + const url="/examination_intelligent_settings/optinal_items.json"; + var data={ + sub_discipline_id:this.Judquestio.Getdatas()[2].rbkc[1], + tag_discipline_id:myrbkc, + source:this.Judquestio.Getdatas()[7].rbly, + difficulty:this.Judquestio.Getdatas()[0].rbnd, + } + this.getwangluodata(url,data); + } + //来源 + getdatassssy=(rbly)=>{ + if (this.Judquestio.Getdatas().length === 0) { + this.scrollToAnchor("Itembankstopid"); + return false; + } + console.log(this.Judquestio.Getdatas()); + var myrbkc=[]; + var Getdatasdatas=this.Judquestio.Getdatas()[1].rbzsd; + for(let myda of Getdatasdatas) { + myrbkc.push(myda.id); + } + const url="/examination_intelligent_settings/optinal_items.json"; + var data={ + sub_discipline_id:this.Judquestio.Getdatas()[2].rbkc[1], + tag_discipline_id:myrbkc, + source:rbly, + difficulty:this.Judquestio.Getdatas()[0].rbnd, + } + this.getwangluodata(url,data); } + + getwangluodata=(url,data)=>{ + axios.post(url,data).then((response) => { + if (response) { + console.log("智能组卷"); + console.log(response); + if(response.data){ + this.setState({ + single_question_count:response.data.single_question_count, + multiple_question_count:response.data.multiple_question_count, + judgement_question_count:response.data.judgement_question_count, + program_question_count:response.data.program_question_count, + }) + + } + + } + }); + } + //难度 getdatass=(nandu)=>{ if (this.Judquestio.Getdatas().length === 0) { this.scrollToAnchor("Itembankstopid"); @@ -313,7 +385,10 @@ class Intecomponents extends Component { program_question_count={this.state.program_question_count} getdatas={()=>this.getdatas()} getdatass={(nd)=>this.getdatass(nd)} - getJudquestio={(ref) => this.getJudquestio(ref)} + getJudquestio={(ref) => this.getJudquestio(ref)} + getdatasss={(e)=>this.getdatasss(e)} + getdatassss={(e)=>this.getdatassss(e)} + getdatassssy={(e)=>this.getdatassssy(e)} > @@ -326,6 +401,7 @@ class Intecomponents extends Component { { newmyshixunmodelbool === true ? "" : this.setCohetepaperbool(bool)} onSubmits={() => this.preservation()} url={'/paperlibrary'}> } From 744c87a7e3ae5c5e7fc701b9c99548ee113ecad5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Fri, 10 Jan 2020 16:14:34 +0800 Subject: [PATCH 060/156] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/react/src/modules/question/component/SingleEditor.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/public/react/src/modules/question/component/SingleEditor.js b/public/react/src/modules/question/component/SingleEditor.js index 36f9bc93a..899c5c197 100644 --- a/public/react/src/modules/question/component/SingleEditor.js +++ b/public/react/src/modules/question/component/SingleEditor.js @@ -421,7 +421,7 @@ class SingleEditor extends Component{ { item===undefined||item===null||item===""? :
    Date: Fri, 10 Jan 2020 16:19:22 +0800 Subject: [PATCH 061/156] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/react/src/common/educoder.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/public/react/src/common/educoder.js b/public/react/src/common/educoder.js index 9a19c6ee2..2c4def4f2 100644 --- a/public/react/src/common/educoder.js +++ b/public/react/src/common/educoder.js @@ -3,22 +3,22 @@ // export { default as OrderStateUtil } from '../routes/Order/components/OrderStateUtil'; export { getImageUrl as getImageUrl, getRandomNumber as getRandomNumber,getUrl as getUrl, publicSearchs as publicSearchs,getRandomcode as getRandomcode,getUrlmys as getUrlmys, getUrl2 as getUrl2, setImagesUrl as setImagesUrl - , getUploadActionUrl as getUploadActionUrl,getUploadActionUrltwo as getUploadActionUrltwo ,getUploadActionUrlthree as getUploadActionUrlthree, getUploadActionUrlOfAuth as getUploadActionUrlOfAuth - , getTaskUrlById as getTaskUrlById, TEST_HOST ,htmlEncode as htmlEncode } from './UrlTool'; + , getUploadActionUrl as getUploadActionUrl,getUploadActionUrltwo as getUploadActionUrltwo ,getUploadActionUrlthree as getUploadActionUrlthree, getUploadActionUrlOfAuth as getUploadActionUrlOfAuth + , getTaskUrlById as getTaskUrlById, TEST_HOST ,htmlEncode as htmlEncode } from './UrlTool'; export {setmiyah as setmiyah} from './Component'; export { default as queryString } from './UrlTool2'; export { SnackbarHOC as SnackbarHOC } from './SnackbarHOC'; export { trigger as trigger, on as on, off as off - , broadcastChannelPostMessage, broadcastChannelOnmessage } from './EventUtil'; + , broadcastChannelPostMessage, broadcastChannelOnmessage } from './EventUtil'; export { updatePageParams as updatePageParams } from './RouterUtil'; export { bytesToSize as bytesToSize } from './UnitUtil'; export { markdownToHTML, uploadNameSizeSeperator, appendFileSizeToUploadFile, appendFileSizeToUploadFileAll, isImageExtension, - downloadFile, sortDirections } from './TextUtil' + downloadFile, sortDirections } from './TextUtil' export { handleDateString, getNextHalfHourOfMoment,formatDuring } from './DateUtil' export { configShareForIndex, configShareForPaths, configShareForShixuns, configShareForCourses, configShareForCustom } from './util/ShareUtil' @@ -30,7 +30,7 @@ export { toStore as toStore, fromStore as fromStore } from './Store' export { trace_collapse, trace, debug, info, warn, error, trace_c, debug_c, info_c, warn_c, error_c } from './LogUtil' export { EDU_ADMIN, EDU_BUSINESS, EDU_SHIXUN_MANAGER, EDU_SHIXUN_MEMBER, EDU_CERTIFICATION_TEACHER - , EDU_GAME_MANAGER, EDU_TEACHER, EDU_NORMAL} from './Const' + , EDU_GAME_MANAGER, EDU_TEACHER, EDU_NORMAL} from './Const' export { default as AttachmentList } from './components/attachment/AttachmentList' From 5f120bcf875c9fb95181ceb436d5c31417162318 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=98=8E?= <775174143@qq.com> Date: Fri, 10 Jan 2020 16:29:01 +0800 Subject: [PATCH 062/156] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/modules/courses/boards/TopicDetail.js | 1 + .../courses/common/comments/CommonReply.js | 1 + .../tasks/GraduationTaskssettingReply.js | 46 +++++++++---------- .../graduation/topics/GraduateTopicReply.js | 2 +- public/react/src/modules/forums/MemoDetail.js | 4 +- 5 files changed, 28 insertions(+), 26 deletions(-) diff --git a/public/react/src/modules/courses/boards/TopicDetail.js b/public/react/src/modules/courses/boards/TopicDetail.js index e8767fb87..f4df177c7 100644 --- a/public/react/src/modules/courses/boards/TopicDetail.js +++ b/public/react/src/modules/courses/boards/TopicDetail.js @@ -682,6 +682,7 @@ class TopicDetail extends Component {
    {!isCourseEnd && } {/* onClick={ this.createNewComment } diff --git a/public/react/src/modules/courses/common/comments/CommonReply.js b/public/react/src/modules/courses/common/comments/CommonReply.js index 42ec3d65a..50f2b60cb 100644 --- a/public/react/src/modules/courses/common/comments/CommonReply.js +++ b/public/react/src/modules/courses/common/comments/CommonReply.js @@ -252,6 +252,7 @@ class CommonReply extends Component{ {/* bor-bottom-greyE */} diff --git a/public/react/src/modules/courses/graduation/tasks/GraduationTaskssettingReply.js b/public/react/src/modules/courses/graduation/tasks/GraduationTaskssettingReply.js index 4281d0ec6..ce0554488 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduationTaskssettingReply.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduationTaskssettingReply.js @@ -18,7 +18,7 @@ import { generateComments, generateChildComments, _findById, handleContentBefore const REPLY_PAGE_COUNT = 10 const $ = window.$; -/* +/* 相比较GraduateTopicReply 改动的地方 列表接口名 /graduation_tasks/${graduation_topic_id}/show_comment.json?parent_id=${parent.id}&limit=500 回复类型名 jour_type: 'GraduationTask', @@ -34,7 +34,7 @@ class GraduationTaskssettingReply extends Component{ componentDidMount(){ this.fetchReplies() - + } _getUser() { const { current_user } = this.props; @@ -58,7 +58,7 @@ class GraduationTaskssettingReply extends Component{ // m_parent_id reply_id: memo.user_id } - } + } ).then((response) => { if (response.data.status === -1) { console.error('服务端异常') @@ -66,18 +66,18 @@ class GraduationTaskssettingReply extends Component{ } // this.props.showNotification('帖子发表成功') - if (response.data && response.data.id) { + if (response.data && response.data.id) { const _id = response.data.id; // md editor.setValue && editor.setValue('') - + const user = this._getUser(); this.setState({ comments: addNewComment(this.state.comments, _id, content, user, this.props.isSuperAdmin(), this), total_count: this.state.total_count + 1 }) this.refs.editor.showEditor(); - + } }).catch((error) => { console.log(error) @@ -95,13 +95,13 @@ class GraduationTaskssettingReply extends Component{ return; } const url = `/users/reply_message.json`; - + const { comments } = this.state; const user = this._getUser(); const graduation_topic_id = this.props.memo.id const commentIndex = this._findById(id, comments); let comment = comments[commentIndex]; - + commentContent = handleContentBeforeCreateSecondLevelComment(commentContent) axios.post(url, { journals_for_message: { @@ -113,9 +113,9 @@ class GraduationTaskssettingReply extends Component{ } }, { - } + } ).then((response) => { - if (response.data.id) { + if (response.data.id) { let newId = response.data.id; this.setState({ @@ -128,7 +128,7 @@ class GraduationTaskssettingReply extends Component{ memo: newMemo2 }) } - + }).catch((error) => { console.log(error) }) @@ -142,7 +142,7 @@ class GraduationTaskssettingReply extends Component{ }) .then((response) => { const { comments } = response.data - + // const memo = Object.assign({}, this.state.memo) // memo.sum_replies_count = sum_replies_count; @@ -160,7 +160,7 @@ class GraduationTaskssettingReply extends Component{ this.fetchReplies() }) } - + fetchReplies = () => { const graduation_topic_id = this.props.memo.id const course_id = this.props.course_id @@ -170,7 +170,7 @@ class GraduationTaskssettingReply extends Component{ }) .then((response) => { const { comments, messages_count } = response.data - + this.setState({ comments: generateComments(comments, this.transformReply), // : this.state.comments.concat(comments), @@ -180,7 +180,7 @@ class GraduationTaskssettingReply extends Component{ console.log(error) }) } - + transformReply = (reply, children = []) => { const isAdmin = this.props.isAdmin() const isSuperAdmin = this.props.isSuperAdmin() @@ -189,7 +189,7 @@ class GraduationTaskssettingReply extends Component{ isSuperAdmin: isSuperAdmin, permission: true, // children: children, - hidden: reply.hidden, + hidden: reply.hidden, id: reply.id, image_url: reply.author.image_url, reward: null, // @@ -235,7 +235,7 @@ class GraduationTaskssettingReply extends Component{ -
    - - - {/* { true ? : + + + {/* { true ? :
    写评论
    } */}
    - - { total_count > REPLY_PAGE_COUNT && + + { total_count > REPLY_PAGE_COUNT &&
    写评论
    diff --git a/public/react/src/modules/courses/graduation/topics/GraduateTopicReply.js b/public/react/src/modules/courses/graduation/topics/GraduateTopicReply.js index df6152c04..f08938b4e 100644 --- a/public/react/src/modules/courses/graduation/topics/GraduateTopicReply.js +++ b/public/react/src/modules/courses/graduation/topics/GraduateTopicReply.js @@ -226,7 +226,7 @@ class GraduateTopicReply extends Component{ return( -
    { window.__useKindEditor === true ? - + : - + } {/* onClick={ this.createNewComment } */} From 9417970f62fca11e382a1aef4ff1ebea65eb8465 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Fri, 10 Jan 2020 16:32:14 +0800 Subject: [PATCH 063/156] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/react/src/common/educoder.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/react/src/common/educoder.js b/public/react/src/common/educoder.js index 9a19c6ee2..b0ef6d692 100644 --- a/public/react/src/common/educoder.js +++ b/public/react/src/common/educoder.js @@ -4,7 +4,7 @@ export { getImageUrl as getImageUrl, getRandomNumber as getRandomNumber,getUrl as getUrl, publicSearchs as publicSearchs,getRandomcode as getRandomcode,getUrlmys as getUrlmys, getUrl2 as getUrl2, setImagesUrl as setImagesUrl , getUploadActionUrl as getUploadActionUrl,getUploadActionUrltwo as getUploadActionUrltwo ,getUploadActionUrlthree as getUploadActionUrlthree, getUploadActionUrlOfAuth as getUploadActionUrlOfAuth - , getTaskUrlById as getTaskUrlById, TEST_HOST ,htmlEncode as htmlEncode } from './UrlTool'; + , getTaskUrlById as getTaskUrlById, TEST_HOST ,htmlEncode as htmlEncode ,getupload_git_file as getupload_git_file} from './UrlTool'; export {setmiyah as setmiyah} from './Component'; export { default as queryString } from './UrlTool2'; From 4f8b4ee7130d9552c2591e0a5af65e7174fe4dfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Fri, 10 Jan 2020 16:34:29 +0800 Subject: [PATCH 064/156] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/react/src/common/educoder.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/react/src/common/educoder.js b/public/react/src/common/educoder.js index 2c4def4f2..c4988dce2 100644 --- a/public/react/src/common/educoder.js +++ b/public/react/src/common/educoder.js @@ -4,7 +4,7 @@ export { getImageUrl as getImageUrl, getRandomNumber as getRandomNumber,getUrl as getUrl, publicSearchs as publicSearchs,getRandomcode as getRandomcode,getUrlmys as getUrlmys, getUrl2 as getUrl2, setImagesUrl as setImagesUrl , getUploadActionUrl as getUploadActionUrl,getUploadActionUrltwo as getUploadActionUrltwo ,getUploadActionUrlthree as getUploadActionUrlthree, getUploadActionUrlOfAuth as getUploadActionUrlOfAuth - , getTaskUrlById as getTaskUrlById, TEST_HOST ,htmlEncode as htmlEncode } from './UrlTool'; + , getTaskUrlById as getTaskUrlById, TEST_HOST ,htmlEncode as htmlEncode ,getupload_git_file as getupload_git_file} from './UrlTool'; export {setmiyah as setmiyah} from './Component'; export { default as queryString } from './UrlTool2'; From 7237b34c9a444e4365e17ec55d500bb7d41b7733 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Fri, 10 Jan 2020 16:46:40 +0800 Subject: [PATCH 065/156] =?UTF-8?q?=E8=B0=83=E6=95=B4=E9=A2=98=E5=BA=93?= =?UTF-8?q?=E5=9B=BE=E7=89=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/modules/question/comthetestpaper/Comthetestpaperst.js | 2 +- .../modules/question/comthetestpaper/Intelligentcomponents.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/public/react/src/modules/question/comthetestpaper/Comthetestpaperst.js b/public/react/src/modules/question/comthetestpaper/Comthetestpaperst.js index c01ae95c8..959840c96 100644 --- a/public/react/src/modules/question/comthetestpaper/Comthetestpaperst.js +++ b/public/react/src/modules/question/comthetestpaper/Comthetestpaperst.js @@ -706,7 +706,7 @@ class Comthetestpaperst extends Component { - this.NewknTypedeldel(true)}/> + this.NewknTypedeldel(true)}/> diff --git a/public/react/src/modules/question/comthetestpaper/Intelligentcomponents.js b/public/react/src/modules/question/comthetestpaper/Intelligentcomponents.js index 43deace7d..63beaf28c 100644 --- a/public/react/src/modules/question/comthetestpaper/Intelligentcomponents.js +++ b/public/react/src/modules/question/comthetestpaper/Intelligentcomponents.js @@ -617,7 +617,7 @@ class Intelligentcomponents extends Component { - this.NewknTypedeldel(true)}/> + this.NewknTypedeldel(true)}/> From 4d9c4e42927f0b5ee1ba938eff4695d90ae14256 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=98=8E?= <775174143@qq.com> Date: Fri, 10 Jan 2020 16:54:29 +0800 Subject: [PATCH 066/156] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/react/src/modules/forums/MemoDetailMDEditor.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/public/react/src/modules/forums/MemoDetailMDEditor.js b/public/react/src/modules/forums/MemoDetailMDEditor.js index 8076c5e6a..b8bcc47fb 100644 --- a/public/react/src/modules/forums/MemoDetailMDEditor.js +++ b/public/react/src/modules/forums/MemoDetailMDEditor.js @@ -75,7 +75,10 @@ class MemoDetailMDEditor extends Component { } onCommit = () => { - + if(this.props.checkIfLogin()===false){ + this.props.showLoginDialog() + return + } if(this.props.checkIfProfileCompleted()===false){ this.props.showhideAccountPhoneemailDialog() return From 59ed6bd1f669fbf45bbca158a8c22208e98db451 Mon Sep 17 00:00:00 2001 From: daiao <358551898@qq.com> Date: Fri, 10 Jan 2020 17:03:17 +0800 Subject: [PATCH 067/156] =?UTF-8?q?HTML=E5=AE=9E=E8=AE=AD=E8=B7=B3?= =?UTF-8?q?=E8=BF=87=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/myshixuns_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/myshixuns_controller.rb b/app/controllers/myshixuns_controller.rb index 7847d58ed..350ee581f 100644 --- a/app/controllers/myshixuns_controller.rb +++ b/app/controllers/myshixuns_controller.rb @@ -3,7 +3,7 @@ class MyshixunsController < ApplicationController before_action :find_myshixun, :except => [:training_task_status, :code_runinng_message] before_action :find_repo_name, :except => [:training_task_status, :code_runinng_message] skip_before_action :verify_authenticity_token, :only => [:html_content] - skip_before_action :check_sign, only: [:training_task_status, :code_runinng_message] + skip_before_action :check_sign, only: [:training_task_status, :code_runinng_message, :html_content] ## TPI关卡列表 def challenges From 9c4bd37ea2da0c67e8fb94495e32d25dc815fe09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=98=8E?= <775174143@qq.com> Date: Fri, 10 Jan 2020 17:38:02 +0800 Subject: [PATCH 068/156] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/react/src/modules/tpm/shixuns/ShixunCardList.js | 9 +++++---- public/react/src/modules/tpm/shixuns/ShixunsIndex.js | 8 +++++--- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/public/react/src/modules/tpm/shixuns/ShixunCardList.js b/public/react/src/modules/tpm/shixuns/ShixunCardList.js index 948bbed48..46abc5bf0 100644 --- a/public/react/src/modules/tpm/shixuns/ShixunCardList.js +++ b/public/react/src/modules/tpm/shixuns/ShixunCardList.js @@ -75,17 +75,18 @@ class ShixunCardList extends Component { type="new"; } + if(typekeyid===key){ if(upcircle===true){ this.setState({ upcircle:false, }) - this.props.Shixunsupcircles("desc") + // this.props.Shixunsupcircles("desc") }else if(upcircle===false){ this.setState({ upcircle:true, }) - this.props.Shixunsupcircles("asc") + // this.props.Shixunsupcircles("desc") } }else{ this.setState({ @@ -93,8 +94,8 @@ class ShixunCardList extends Component { }) } - //allevent - this.props.ShixunsState(false,type); + + this.props.ShixunsState(false,type,"desc"); } diff --git a/public/react/src/modules/tpm/shixuns/ShixunsIndex.js b/public/react/src/modules/tpm/shixuns/ShixunsIndex.js index f14afb0ac..82fa6a3f9 100644 --- a/public/react/src/modules/tpm/shixuns/ShixunsIndex.js +++ b/public/react/src/modules/tpm/shixuns/ShixunsIndex.js @@ -296,21 +296,23 @@ class ShixunsIndex extends Component { console.log(error) }); } - ShixunsState=(val,type)=>{ + ShixunsState=(val,type,sorts)=>{ // sort, let {tag_level, tag_id, page, limit, keyword, status, diff,sort} = this.state; - let newsort=sort; + let newsort=sorts?sorts:sort; this.setState({ order_by:type, typepvisible:true, pages:1, - // sort:sort + sort:sorts?sorts:sort }) let params // let vals=false if(newsort===undefined){ newsort="desc" + }else{ + newsort=sorts?sorts:sort } params= { order_by:type, From 3324ca4b52c30525fefd67c9ce7ff6b288f81199 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Fri, 10 Jan 2020 17:42:40 +0800 Subject: [PATCH 069/156] =?UTF-8?q?=E9=A2=98=E5=BA=93=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../react/src/common/quillForEditor/index.js | 29 ++++++++++--------- .../modules/question/Questionitem_banks.js | 8 ++--- .../question/component/ChoquesEditor.js | 2 +- .../question/component/SingleEditor.js | 8 ++--- 4 files changed, 24 insertions(+), 23 deletions(-) diff --git a/public/react/src/common/quillForEditor/index.js b/public/react/src/common/quillForEditor/index.js index 525feba09..378111af8 100644 --- a/public/react/src/common/quillForEditor/index.js +++ b/public/react/src/common/quillForEditor/index.js @@ -1,7 +1,7 @@ /* * @Description: quill 编辑器 * @Author: tangjiang - * @Github: + * @Github: * @Date: 2019-12-18 08:49:30 * @LastEditors : tangjiang * @LastEditTime : 2020-01-10 15:05:27 @@ -57,7 +57,7 @@ function QuillForEditor ({ {size: ['12px', '14px', '16px', '18px', '20px']}, {align: []}, {list: 'ordered'}, {list: 'bullet'}, // 列表 {script: 'sub'}, {script: 'super'}, - { 'color': [] }, { 'background': [] }, + { 'color': [] }, { 'background': [] }, {header: [1,2,3,4,5,false]}, 'blockquote', 'code-block', 'link', 'image', 'video', @@ -67,7 +67,7 @@ function QuillForEditor ({ const editorRef = useRef(null); // quill 实例 - const [quill, setQuill] = useState(null); + const [quill, setQuill] = useState(null); const [selection, setSelection] = useState(null); const [fillCount, setFillCount] = useState(0); const [quillCtx, setQuillCtx] = useState({}); @@ -77,7 +77,7 @@ function QuillForEditor ({ // getQuillContent && getQuillContent(quill); onContentChange && onContentChange(content, quill); }; - + const renderOptions = options || defaultConfig; const bindings = { @@ -96,10 +96,10 @@ function QuillForEditor ({ backspace: { key: 'Backspace', /** - * @param {*} range + * @param {*} range * { index, // 删除元素的位置 * length // 删除元素的个数, 当删除一个时, length=0, 其它等于删除的元素的个数 - * } + * } * @param {*} context 上下文 */ handler: function (range, context) { @@ -126,7 +126,7 @@ function QuillForEditor ({ // } else { // return false; // } - return true; + return true; } } }; @@ -190,7 +190,7 @@ function QuillForEditor ({ onClick: showUploadImage, width, height - }); + }); } } }); @@ -208,19 +208,19 @@ function QuillForEditor ({ // 1. 获取编辑器内容 }); - // TODO + // TODO /** * 1.获取键盘删除事件 * 2.点击时获取删除的叶子节点 getLeaf(range.index) */ }, []); - - // 设置值 + + // 设置值 useEffect(() => { if (!quill) return const previous = quill.getContents() - + if (value && value.hasOwnProperty('ops')) { // console.log(value.ops); const ops = value.ops || []; @@ -234,7 +234,8 @@ function QuillForEditor ({ const current = value if (!deepEqual(previous, current)) { setSelection(quill.getSelection()) - if (typeof value === 'string') { + if (typeof value === 'string' && value) { + // debugger quill.clipboard.dangerouslyPasteHTML(value, 'api'); if (autoFocus) { quill.focus(); @@ -268,7 +269,7 @@ function QuillForEditor ({ if (typeof handleOnChange !== 'function') return; let handler; quill.on( - 'text-change', + 'text-change', (handler = (delta, oldDelta, source) => { const _ctx = quill.getContents(); setQuillCtx(_ctx); diff --git a/public/react/src/modules/question/Questionitem_banks.js b/public/react/src/modules/question/Questionitem_banks.js index 129e29d69..0c27dc0fa 100644 --- a/public/react/src/modules/question/Questionitem_banks.js +++ b/public/react/src/modules/question/Questionitem_banks.js @@ -476,7 +476,7 @@ class Questionitem_banks extends Component { this.setState({ item_type: item_type }) - + this.scrollToAnchor("Itembankstopid"); } render() { @@ -515,6 +515,7 @@ class Questionitem_banks extends Component { > +
    { item_type && item_type === "SINGLE" ? @@ -555,9 +556,8 @@ class Questionitem_banks extends Component { : item_type && item_type === "PROGRAM" ? "" : "" - } - - + } +
    diff --git a/public/react/src/modules/question/component/ChoquesEditor.js b/public/react/src/modules/question/component/ChoquesEditor.js index 93283c307..16aef2e2d 100644 --- a/public/react/src/modules/question/component/ChoquesEditor.js +++ b/public/react/src/modules/question/component/ChoquesEditor.js @@ -399,7 +399,7 @@ class ChoquesEditor extends Component{ { item===undefined||item===null||item===""? + - {this.props&&this.props.is_jupyter===true&&this.props&&this.props.user.user_identity==="学生"?"":this.state.isopentitletype==="Less"?"":this.state.opentitletype===true?this.opentitle()} className={"pointer Breadcrumbfont color-grey-9 "}> + {this.state.enlarge===false?"":this.state.isopentitletype==="Less"?"":this.state.opentitletype===true?this.opentitle()} className={"pointer Breadcrumbfont color-grey-9 "}> 阅读全文 :this.opentitle()} className={"pointer Breadcrumbfont color-grey-9 "}> 收起全文 @@ -725,10 +725,11 @@ class Challengesjupyter extends Component {
    - :"" + : "" : ( admin===true||business===true||mysidentity===true? +
    From 31d1f268e8fa598f83c630de6a2fe8ca1c1b9069 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=98=8E?= <775174143@qq.com> Date: Fri, 10 Jan 2020 18:59:53 +0800 Subject: [PATCH 079/156] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Challenges/Challengesjupyter.js | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/public/react/src/modules/tpm/shixunchild/Challenges/Challengesjupyter.js b/public/react/src/modules/tpm/shixunchild/Challenges/Challengesjupyter.js index 0586df638..61782d69f 100644 --- a/public/react/src/modules/tpm/shixunchild/Challenges/Challengesjupyter.js +++ b/public/react/src/modules/tpm/shixunchild/Challenges/Challengesjupyter.js @@ -77,20 +77,20 @@ class Challengesjupyter extends Component { }else{ if(boxoffsetHeigh>=300){ - if(this.state.enlarge===false){ - this.setState({ - opentitletype:false, - isopentitletype:"greater", - boxoffsetHeigh:boxoffsetHeigh - }) - }else{ - this.setState({ - opentitletype:true, - isopentitletype:"greater", - boxoffsetHeigh:boxoffsetHeigh - }) - } - + // if(this.state.enlarge===false){ + // this.setState({ + // opentitletype:false, + // isopentitletype:"greater", + // boxoffsetHeigh:boxoffsetHeigh + // }) + // }else{ + // + // } + this.setState({ + opentitletype:true, + isopentitletype:"greater", + boxoffsetHeigh:boxoffsetHeigh + }) }else{ this.setState({ isopentitletype:"Less", @@ -645,8 +645,8 @@ class Challengesjupyter extends Component { ` } - - {this.state.enlarge===false?"":this.state.isopentitletype==="Less"?"":this.state.opentitletype===true?this.opentitle()} className={"pointer Breadcrumbfont color-grey-9 "}> + {/*this.state.enlarge===false?"":*/} + {this.state.isopentitletype==="Less"?"":this.state.opentitletype===true?this.opentitle()} className={"pointer Breadcrumbfont color-grey-9 "}> 阅读全文 :this.opentitle()} className={"pointer Breadcrumbfont color-grey-9 "}> 收起全文 From d1ce7997b07a78942ea806dac3d2975b1a730428 Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Fri, 10 Jan 2020 19:05:32 +0800 Subject: [PATCH 080/156] =?UTF-8?q?=E5=AD=97=E7=AC=A6=E9=99=90=E5=88=B6?= =?UTF-8?q?=E7=9A=84=E6=96=87=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/forms/examination_banks/save_exam_form.rb | 2 +- app/forms/item_banks/save_item_form.rb | 6 +++--- app/forms/validate/user.rb | 2 +- app/models/attachment.rb | 2 +- app/models/challenge.rb | 2 +- app/models/challenge_answer.rb | 2 +- app/models/challenge_choose.rb | 2 +- app/models/challenge_question.rb | 2 +- app/models/chart_rule.rb | 2 +- app/models/competition.rb | 2 +- app/models/competition_module_md_content.rb | 2 +- app/models/course.rb | 2 +- app/models/course_group.rb | 2 +- app/models/course_module.rb | 2 +- app/models/course_second_category.rb | 2 +- app/models/course_stage.rb | 4 ++-- app/models/discuss.rb | 2 +- app/models/exercise.rb | 4 ++-- app/models/exercise_answer.rb | 2 +- app/models/exercise_answer_comment.rb | 2 +- app/models/exercise_bank.rb | 4 ++-- app/models/exercise_bank_choice.rb | 2 +- app/models/exercise_bank_question.rb | 2 +- app/models/exercise_bank_standard_answer.rb | 2 +- app/models/exercise_choice.rb | 2 +- app/models/exercise_question.rb | 2 +- app/models/exercise_standard_answer.rb | 2 +- app/models/graduation_task.rb | 4 ++-- app/models/graduation_topic.rb | 6 ++---- app/models/graduation_work.rb | 2 +- app/models/graduation_work_score.rb | 2 +- app/models/gtask_bank.rb | 4 ++-- app/models/gtopic_bank.rb | 6 ++---- app/models/hack.rb | 4 ++-- app/models/hack_set.rb | 4 ++-- app/models/homework_bank.rb | 6 +++--- app/models/homework_common.rb | 8 ++++---- app/models/inform.rb | 4 ++-- app/models/journals_for_message.rb | 2 +- app/models/library.rb | 2 +- app/models/memo.rb | 2 +- app/models/message.rb | 2 +- app/models/message_detail.rb | 2 +- app/models/poll.rb | 4 ++-- app/models/poll_answer.rb | 2 +- app/models/poll_question.rb | 2 +- app/models/poll_vote.rb | 2 +- app/models/shixun_info.rb | 4 ++-- app/models/shixun_work_comment.rb | 4 ++-- app/models/stage.rb | 4 ++-- app/models/student_work.rb | 2 +- app/models/student_works_score.rb | 2 +- app/models/subject.rb | 6 +++--- app/models/test_set.rb | 4 ++-- app/models/trustie_hack.rb | 2 +- 55 files changed, 79 insertions(+), 83 deletions(-) diff --git a/app/forms/examination_banks/save_exam_form.rb b/app/forms/examination_banks/save_exam_form.rb index b84b32eb1..1fc690a2f 100644 --- a/app/forms/examination_banks/save_exam_form.rb +++ b/app/forms/examination_banks/save_exam_form.rb @@ -6,7 +6,7 @@ class ExaminationBanks::SaveExamForm validates :discipline_id, presence: true validates :sub_discipline_id, presence: true validates :difficulty, presence: true, inclusion: {in: 1..3}, numericality: { only_integer: true } - validates :name, presence: true, length: { maximum: 60 } + validates :name, presence: true, length: { maximum: 60, too_long: "名称不能超过60个字符" } validate :validate_duration def validate_duration diff --git a/app/forms/item_banks/save_item_form.rb b/app/forms/item_banks/save_item_form.rb index 2bfd99fc3..d0a5649db 100644 --- a/app/forms/item_banks/save_item_form.rb +++ b/app/forms/item_banks/save_item_form.rb @@ -7,8 +7,8 @@ class ItemBanks::SaveItemForm validates :sub_discipline_id, presence: true validates :item_type, presence: true, inclusion: {in: %W(SINGLE MULTIPLE JUDGMENT COMPLETION SUBJECTIVE PRACTICAL PROGRAM)} validates :difficulty, presence: true, inclusion: {in: 1..3}, numericality: { only_integer: true } - validates :name, presence: true, length: { maximum: 1000 } - validates :analysis, length: { maximum: 1000 } + validates :name, presence: true, length: { maximum: 1000, too_long: "题干不能超过1000个字符" } + validates :analysis, length: { maximum: 1000, too_long: "解析不能超过1000个字符" } def validate! super @@ -27,7 +27,7 @@ class ItemBanks::SaveItemForm attr_accessor :choice_text, :is_answer - validates :choice_text, presence: true, length: { maximum: 100 } + validates :choice_text, presence: true, length: { maximum: 500, too_long: "选项不能超过500个字符" } validates :is_answer, presence: true, inclusion: {in: 0..1}, numericality: { only_integer: true } end end \ No newline at end of file diff --git a/app/forms/validate/user.rb b/app/forms/validate/user.rb index 0f8f5e9ba..c378a36c4 100644 --- a/app/forms/validate/user.rb +++ b/app/forms/validate/user.rb @@ -4,7 +4,7 @@ module Validate attr_accessor :nickname, :lastname - validates :nickname, presence: true, length: { maximum: 10 } + validates :nickname, presence: true, length: { maximum: 10, too_long: "昵称不能超过10个字符" } validates :lastname, presence: true end end diff --git a/app/models/attachment.rb b/app/models/attachment.rb index ac051428f..64531db46 100644 --- a/app/models/attachment.rb +++ b/app/models/attachment.rb @@ -25,7 +25,7 @@ class Attachment < ApplicationRecord scope :search_by_container, -> (ids) {where(container_id: ids)} scope :unified_setting, -> {where("unified_setting = ? ", 1)} - validates_length_of :description, maximum: 100 + validates_length_of :description, maximum: 100, message: "资源描述不能超过100个字符" DCODES = %W(2 3 4 5 6 7 8 9 a b c f e f g h i j k l m n o p q r s t u v w x y z) diff --git a/app/models/challenge.rb b/app/models/challenge.rb index e9bef0c9d..4cada46bc 100644 --- a/app/models/challenge.rb +++ b/app/models/challenge.rb @@ -28,7 +28,7 @@ class Challenge < ApplicationRecord scope :fields_for_list, -> { select([:id, :subject, :st, :score, :position, :shixun_id]) } - validates :task_pass, length: { maximum: 10000 } + validates :task_pass, length: { maximum: 10000, too_long: "过关任务不能超过10000个字符" } after_commit :create_diff_record diff --git a/app/models/challenge_answer.rb b/app/models/challenge_answer.rb index d3fd69cd0..8fc3c4a21 100644 --- a/app/models/challenge_answer.rb +++ b/app/models/challenge_answer.rb @@ -3,7 +3,7 @@ class ChallengeAnswer < ApplicationRecord belongs_to :challenge has_many :game_answers, :dependent => :destroy - validates :contents, length: { maximum: 5000 } + validates :contents, length: { maximum: 5000 , too_long: "答案内容不能超过5000个字符"} def view_answer_time(user_id) game_answers.where(user_id: user_id).last&.view_time diff --git a/app/models/challenge_choose.rb b/app/models/challenge_choose.rb index 2b8858f21..9a73fbc0a 100644 --- a/app/models/challenge_choose.rb +++ b/app/models/challenge_choose.rb @@ -4,6 +4,6 @@ class ChallengeChoose < ApplicationRecord has_many :challenge_tags, :dependent => :destroy has_many :challenge_questions, dependent: :destroy - validates :subject, length: { maximum: 1000 } + validates :subject, length: { maximum: 1000, too_long: "题干不能超过1000个字符" } end diff --git a/app/models/challenge_question.rb b/app/models/challenge_question.rb index 959b033f9..7267f1bb4 100644 --- a/app/models/challenge_question.rb +++ b/app/models/challenge_question.rb @@ -1,6 +1,6 @@ class ChallengeQuestion < ApplicationRecord belongs_to :challenge_choose - validates :option_name, length: { maximum: 500 } + validates :option_name, length: { maximum: 500, too_long: "选项不能超过500个字符" } end diff --git a/app/models/chart_rule.rb b/app/models/chart_rule.rb index de8fceaf1..532c7f0e7 100644 --- a/app/models/chart_rule.rb +++ b/app/models/chart_rule.rb @@ -2,5 +2,5 @@ class ChartRule < ApplicationRecord belongs_to :competition belongs_to :competition_stage, optional: true - validates :content, length: { maximum: 1000 } + validates :content, length: { maximum: 1000, too_long: "内容不能超过1000个字符" } end diff --git a/app/models/competition.rb b/app/models/competition.rb index 1d10e2032..90f2f63da 100644 --- a/app/models/competition.rb +++ b/app/models/competition.rb @@ -33,7 +33,7 @@ class Competition < ApplicationRecord has_many :competition_prizes, dependent: :destroy has_many :competition_prize_users, dependent: :destroy - validates :introduction, length: { maximum: 500 } + validates :introduction, length: { maximum: 500, too_long: "简介不能超过500个字符" } before_save :set_laboratory after_create :create_competition_modules diff --git a/app/models/competition_module_md_content.rb b/app/models/competition_module_md_content.rb index 936ded8ef..919859236 100644 --- a/app/models/competition_module_md_content.rb +++ b/app/models/competition_module_md_content.rb @@ -5,6 +5,6 @@ class CompetitionModuleMdContent < ApplicationRecord # validates :name, presence: true validates :content, presence: true - validates :content, length: { maximum: 10000 } + validates :content, length: { maximum: 10000 , too_long: "内容不能超过10000个字符"} end \ No newline at end of file diff --git a/app/models/course.rb b/app/models/course.rb index 83d2bb56e..5808d2295 100644 --- a/app/models/course.rb +++ b/app/models/course.rb @@ -108,7 +108,7 @@ class Course < ApplicationRecord NORMAL = 6 # 普通用户 Anonymous = 7 # 普未登录 - validates :name, presence: true, length: { maximum: 60 } + validates :name, presence: true, length: { maximum: 60, too_long: "课堂名称不能超过60个字符" } before_save :set_laboratory after_create :create_board_sync, :act_as_course_activity, :send_tiding diff --git a/app/models/course_group.rb b/app/models/course_group.rb index 9486c9043..b49f88bde 100644 --- a/app/models/course_group.rb +++ b/app/models/course_group.rb @@ -9,7 +9,7 @@ class CourseGroup < ApplicationRecord has_many :homework_group_settings, :dependent => :destroy scope :by_group_ids, lambda { |ids| where(id: ids)} - validates :name, length: { maximum: 60 } + validates :name, length: { maximum: 60, too_long: "分班名称不能超过60个字符" } validates_uniqueness_of :name, scope: :course_id, message: "不能创建相同名称的分班" after_create :generate_invite_code diff --git a/app/models/course_module.rb b/app/models/course_module.rb index 641c70425..a1b6a7345 100644 --- a/app/models/course_module.rb +++ b/app/models/course_module.rb @@ -5,7 +5,7 @@ class CourseModule < ApplicationRecord # 二级目录 has_many :course_second_categories - validates :module_name, length: { maximum: 20 } + validates :module_name, length: { maximum: 20, too_long: "目录名称不能超过20个字符" } scope :not_hidden, -> { where(hidden: 0) } scope :graduation_module, -> { where(module_type: "graduation") } diff --git a/app/models/course_second_category.rb b/app/models/course_second_category.rb index 630b74807..6a0ae24bb 100644 --- a/app/models/course_second_category.rb +++ b/app/models/course_second_category.rb @@ -5,7 +5,7 @@ class CourseSecondCategory < ApplicationRecord belongs_to :course_module has_many :homework_commons - validates :name, length: { maximum: 60 } + validates :name, length: { maximum: 60, too_long: "名称不能超过60个字符" } def category_type_str category_type == "graduation" && name == "毕设选题" ? "graduation_topics" : ( diff --git a/app/models/course_stage.rb b/app/models/course_stage.rb index f105e25f6..c29737484 100644 --- a/app/models/course_stage.rb +++ b/app/models/course_stage.rb @@ -4,6 +4,6 @@ class CourseStage < ApplicationRecord has_many :course_stage_shixuns, -> { order("course_stage_shixuns.position ASC") }, dependent: :destroy has_many :shixuns, :through => :course_stage_shixuns - validates :name, length: { maximum: 60 } - validates :description, length: { maximum: 300 } + validates :name, length: { maximum: 60 , too_long: "章节名称不能超过60个字符"} + validates :description, length: { maximum: 1000, too_long: "章节描述不能超过1000个字符" } end diff --git a/app/models/discuss.rb b/app/models/discuss.rb index f35ca4751..743a436e0 100644 --- a/app/models/discuss.rb +++ b/app/models/discuss.rb @@ -13,7 +13,7 @@ class Discuss < ApplicationRecord belongs_to :challenge, optional: true validate :validate_sensitive_string - validates :content, length: { maximum: 1000 } + validates :content, length: { maximum: 1000, too_long: "内容不能超过1000个字符" } after_create :send_tiding diff --git a/app/models/exercise.rb b/app/models/exercise.rb index 1fd84d1f7..86e85b2d0 100644 --- a/app/models/exercise.rb +++ b/app/models/exercise.rb @@ -19,8 +19,8 @@ class Exercise < ApplicationRecord scope :exercise_search, lambda { |keywords| where("exercise_name LIKE ?", "%#{keywords}%") unless keywords.blank?} - validates :exercise_name, length: { maximum: 60, too_long: "60 characters is the maximum allowed" } - validates :exercise_description, length: { maximum: 100 } + validates :exercise_name, length: { maximum: 60, too_long: "试卷名称不能超过60个字符" } + validates :exercise_description, length: { maximum: 100, too_long: "试卷须知不能超过100个字符" } after_create :create_exercise_list diff --git a/app/models/exercise_answer.rb b/app/models/exercise_answer.rb index 00c08dd77..fb9c8d51f 100644 --- a/app/models/exercise_answer.rb +++ b/app/models/exercise_answer.rb @@ -11,6 +11,6 @@ class ExerciseAnswer < ApplicationRecord scope :exercise_answer_is_right, -> {where("score > ?",0.0)} #判断答案是否正确,根据分数总和大于0 scope :score_reviewed, lambda {where("score >= ?",0.0)} #是否评分,用于判断主观题的 - validates :answer_text, length: { maximum: 5000 } + validates :answer_text, length: { maximum: 5000, too_long: "答案不能超过5000个字符" } end \ No newline at end of file diff --git a/app/models/exercise_answer_comment.rb b/app/models/exercise_answer_comment.rb index 110efc737..62c7360c9 100644 --- a/app/models/exercise_answer_comment.rb +++ b/app/models/exercise_answer_comment.rb @@ -7,5 +7,5 @@ class ExerciseAnswerComment < ApplicationRecord scope :search_answer_comments, lambda {|name,ids| where("#{name}":ids)} - validates :comment, length: { maximum: 100 } + validates :comment, length: { maximum: 100, too_long: "评语不能超过100个字符" } end diff --git a/app/models/exercise_bank.rb b/app/models/exercise_bank.rb index 067d080b5..fb089ecbc 100644 --- a/app/models/exercise_bank.rb +++ b/app/models/exercise_bank.rb @@ -18,7 +18,7 @@ class ExerciseBank < ApplicationRecord scope :exercise_bank_search, lambda { |keywords| where("name LIKE ?", "%#{keywords}%") unless keywords.blank?} - validates :name, length: { maximum: 60, too_long: "60 characters is the maximum allowed" } - validates :description, length: { maximum: 100, too_long: "100 characters is the maximum allowed" } + validates :name, length: { maximum: 60, too_long: "试卷名称不能超过60个字符" } + validates :description, length: { maximum: 100, too_long: "试卷须知不能超过100个字符" } end \ No newline at end of file diff --git a/app/models/exercise_bank_choice.rb b/app/models/exercise_bank_choice.rb index 8f1dc9028..542b27e97 100644 --- a/app/models/exercise_bank_choice.rb +++ b/app/models/exercise_bank_choice.rb @@ -5,6 +5,6 @@ class ExerciseBankChoice < ApplicationRecord scope :find_choice_custom, lambda {|k,v| where("#{k} = ?",v)} #根据传入的参数查找问题 scope :left_choice_choose, lambda {|k,v| where("#{k} > ?",v)} #根据传入的参数查找问题 - validates :choice_text, length: { maximum: 500 } + validates :choice_text, length: { maximum: 500, too_long: "选项不能超过500个字符" } end \ No newline at end of file diff --git a/app/models/exercise_bank_question.rb b/app/models/exercise_bank_question.rb index fbb6da88f..4857b1a55 100644 --- a/app/models/exercise_bank_question.rb +++ b/app/models/exercise_bank_question.rb @@ -11,7 +11,7 @@ class ExerciseBankQuestion < ApplicationRecord scope :left_question_choose, lambda {|k,v| where("#{k} > ?",v)} #根据传入的参数查找问题 scope :find_objective_questions, -> {where("question_type != ?",4)} #查找全部客观题 - validates :question_title, length: { maximum: 1000 } + validates :question_title, length: { maximum: 1000, too_long: "题干不能超过1000个字符" } def question_type_name case self.question_type diff --git a/app/models/exercise_bank_standard_answer.rb b/app/models/exercise_bank_standard_answer.rb index 9bfbd67aa..4eabd2790 100644 --- a/app/models/exercise_bank_standard_answer.rb +++ b/app/models/exercise_bank_standard_answer.rb @@ -4,6 +4,6 @@ class ExerciseBankStandardAnswer < ApplicationRecord #attr_accessible :answer_text scope :standard_by_ids, lambda { |s| where(exercise_bank_choice_id: s) } - validates :answer_text, length: { maximum: 5000 } + validates :answer_text, length: { maximum: 5000, too_long: "参考答案不能超过5000个字符" } end \ No newline at end of file diff --git a/app/models/exercise_choice.rb b/app/models/exercise_choice.rb index 54b844ad9..1d3e78d8e 100644 --- a/app/models/exercise_choice.rb +++ b/app/models/exercise_choice.rb @@ -7,6 +7,6 @@ class ExerciseChoice < ApplicationRecord scope :find_choice_custom, lambda {|k,v| where("#{k} = ?",v)} #根据传入的参数查找问题 scope :left_choice_choose, lambda {|k,v| where("#{k} > ?",v)} #根据传入的参数查找问题 - validates :choice_text, length: { maximum: 500 } + validates :choice_text, length: { maximum: 500, too_long: "选项不能超过500个字符" } end \ No newline at end of file diff --git a/app/models/exercise_question.rb b/app/models/exercise_question.rb index 3f1a49625..ea588cba5 100644 --- a/app/models/exercise_question.rb +++ b/app/models/exercise_question.rb @@ -16,7 +16,7 @@ class ExerciseQuestion < ApplicationRecord scope :left_question_choose, lambda {|k,v| where("#{k} > ?",v)} #根据传入的参数查找问题 scope :find_objective_questions, -> {where("question_type != ?",4)} #查找全部客观题 - validates :question_title, length: { maximum: 1000 } + validates :question_title, length: { maximum: 1000, too_long: "题干不能超过1000个字符" } def question_type_name diff --git a/app/models/exercise_standard_answer.rb b/app/models/exercise_standard_answer.rb index ccf5c1203..d527809ef 100644 --- a/app/models/exercise_standard_answer.rb +++ b/app/models/exercise_standard_answer.rb @@ -6,5 +6,5 @@ class ExerciseStandardAnswer < ApplicationRecord scope :find_standard_answer_custom, lambda {|k,v| where("#{k} = ?",v)} #根据传入的参数查找问题 scope :standard_by_ids, lambda { |s| where(exercise_choice_id: s) } - validates :answer_text, length: { maximum: 5000 } + validates :answer_text, length: { maximum: 5000, too_long: "参考答案不能超过5000个字符" } end diff --git a/app/models/graduation_task.rb b/app/models/graduation_task.rb index c9838954a..9776eb564 100644 --- a/app/models/graduation_task.rb +++ b/app/models/graduation_task.rb @@ -29,8 +29,8 @@ class GraduationTask < ApplicationRecord belongs_to :gtask_bank, optional: true - validates :name, length: { maximum: 60 } - validates :description, length: { maximum: 5000 } + validates :name, length: { maximum: 60, too_long: "任务名称不能超过60个字符" } + validates :description, length: { maximum: 5000, too_long: "任务描述不能超过5000个字符" } # 未提交 scope :unfinished, -> {where(status: 0)} diff --git a/app/models/graduation_topic.rb b/app/models/graduation_topic.rb index 294bfa785..96e7ea353 100644 --- a/app/models/graduation_topic.rb +++ b/app/models/graduation_topic.rb @@ -19,10 +19,8 @@ class GraduationTopic < ApplicationRecord #after_create :act_as_course_activity # 课题名称和描述字段长度限制 - validates :name, length: { maximum: 60, - too_long: "60 characters is the maximum allowed" } - validates :description, length: { maximum: 5000, - too_long: "5000 characters is the maximum allowed" } + validates :name, length: { maximum: 60, too_long: "选题名称不能超过60个字符" } + validates :description, length: { maximum: 5000, too_long: "选题描述不能超过5000个字符" } def status_name case self.status diff --git a/app/models/graduation_work.rb b/app/models/graduation_work.rb index 7fb0ecc24..33f09d2f8 100644 --- a/app/models/graduation_work.rb +++ b/app/models/graduation_work.rb @@ -19,7 +19,7 @@ class GraduationWork < ApplicationRecord # has_many :formal_graduation_task_group_assignations, -> { formal }, class_name: "GraduationTaskGroupAssignation" # has_many :temporary_graduation_task_group_assignations, -> { temporary }, class_name: "GraduationTaskGroupAssignation" - validates :description, length: { maximum: 5000 } + validates :description, length: { maximum: 5000, too_long: "作品描述不能超过5000个字符" } scope :has_committed, lambda { where("work_status != 0") } diff --git a/app/models/graduation_work_score.rb b/app/models/graduation_work_score.rb index 853b996a1..71bd9e00f 100644 --- a/app/models/graduation_work_score.rb +++ b/app/models/graduation_work_score.rb @@ -5,5 +5,5 @@ class GraduationWorkScore < ApplicationRecord belongs_to :graduation_task has_many :attachments, as: :container, dependent: :destroy - validates :comment, length: { maximum: 1000 } + validates :comment, length: { maximum: 1000, too_long: "评语不能超过1000个字符" } end diff --git a/app/models/gtask_bank.rb b/app/models/gtask_bank.rb index f9d38d33f..5e9b580c4 100644 --- a/app/models/gtask_bank.rb +++ b/app/models/gtask_bank.rb @@ -9,6 +9,6 @@ class GtaskBank < ApplicationRecord scope :myself, ->(user_id) { where(user_id: user_id)} scope :is_public, -> { where(:is_public => true) } - validates :name, length: { maximum: 60 } - validates :description, length: { maximum: 5000 } + validates :name, length: { maximum: 60, too_long: "任务名称不能超过60个字符" } + validates :description, length: { maximum: 5000, too_long: "任务描述不能超过5000个字符" } end diff --git a/app/models/gtopic_bank.rb b/app/models/gtopic_bank.rb index fe9f184eb..76ed122e4 100644 --- a/app/models/gtopic_bank.rb +++ b/app/models/gtopic_bank.rb @@ -10,8 +10,6 @@ class GtopicBank < ApplicationRecord # 课题名称和描述字段长度限制 - validates :name, length: { maximum: 60, - too_long: "60 characters is the maximum allowed" } - validates :description, length: { maximum: 5000, - too_long: "5000 characters is the maximum allowed" } + validates :name, length: { maximum: 60, too_long: "选题名称不能超过60个字符" } + validates :description, length: { maximum: 5000, too_long: "选题描述不能超过5000个字符" } end diff --git a/app/models/hack.rb b/app/models/hack.rb index e89212cc3..d0a874f76 100644 --- a/app/models/hack.rb +++ b/app/models/hack.rb @@ -2,8 +2,8 @@ class Hack < ApplicationRecord # status: 0 未发布; 1已发布 # diffcult: 难度 1:简单;2:中等; 3:困难 # 编程题 - validates_length_of :name, maximum: 60 - validates_length_of :description, maximum: 5000 + validates_length_of :name, maximum: 60, message: "名称不能超过60个字符" + validates_length_of :description, maximum: 5000, message: "描述不能超过5000个字符" validates :description, presence: { message: "描述不能为空" } validates :name, presence: { message: "名称不能为空" } # 测试集 diff --git a/app/models/hack_set.rb b/app/models/hack_set.rb index 9b03ee8d0..dd4cac7b2 100644 --- a/app/models/hack_set.rb +++ b/app/models/hack_set.rb @@ -1,6 +1,6 @@ class HackSet < ApplicationRecord - validates_length_of :input, maximum: 1000 - validates_length_of :output, maximum: 1000 + validates_length_of :input, maximum: 1000, message: "测试集输入不能超过5000个字符" + validates_length_of :output, maximum: 1000, message: "测试集输出不能超过5000个字符" validates :input, presence: { message: "测试集输入不能为空" } validates :output, presence: { message: "测试集输出不能为空" } validates_uniqueness_of :input, scope: [:hack_id, :input], message: "多个测试集的输入不能相同" diff --git a/app/models/homework_bank.rb b/app/models/homework_bank.rb index d6db7bfab..e4f941375 100644 --- a/app/models/homework_bank.rb +++ b/app/models/homework_bank.rb @@ -10,7 +10,7 @@ class HomeworkBank < ApplicationRecord scope :is_public, -> { where(is_public: true)} scope :myself, ->(user_id) { where(user_id: user_id)} - validates :name, length: { maximum: 60 } - validates :description, length: { maximum: 15000 } - validates :reference_answer, length: { maximum: 15000 } + validates :name, length: { maximum: 60, too_long: "作业名称不能超过60个字符" } + validates :description, length: { maximum: 15000, too_long: "作业描述不能超过15000个字符" } + validates :reference_answer, length: { maximum: 15000, too_long: "参考答案不能超过15000个字符" } end diff --git a/app/models/homework_common.rb b/app/models/homework_common.rb index 58b52bdd2..040ab65f9 100644 --- a/app/models/homework_common.rb +++ b/app/models/homework_common.rb @@ -35,10 +35,10 @@ class HomeworkCommon < ApplicationRecord # 学生的查重情况 has_many :homework_review_results, :dependent => :destroy - validates :name, length: { maximum: 60 } - validates :description, length: { maximum: 15000 } - validates :explanation, length: { maximum: 5000 } - validates :reference_answer, length: { maximum: 15000 } + validates :name, length: { maximum: 60, too_long: "作业名称不能超过60个字符" } + validates :description, length: { maximum: 15000, too_long: "作业描述不能超过15000个字符" } + validates :explanation, length: { maximum: 5000, too_long: "说明不能超过5000个字符" } + validates :reference_answer, length: { maximum: 15000, too_long: "参考答案不能超过15000个字符" } # after_update :update_activity before_destroy :update_homework_bank_quotes diff --git a/app/models/inform.rb b/app/models/inform.rb index dc979ef32..ce549b2b9 100644 --- a/app/models/inform.rb +++ b/app/models/inform.rb @@ -1,8 +1,8 @@ class Inform < ApplicationRecord belongs_to :container, polymorphic: true, optional: true - validates :name, length: { maximum: 60 } - validates :description, length: { maximum: 5000 } + validates :name, length: { maximum: 60, too_long: "名称不能超过60个字符" } + validates :description, length: { maximum: 5000, too_long: "内容不能超过5000个字符" } has_many :attachments, as: :container, dependent: :destroy diff --git a/app/models/journals_for_message.rb b/app/models/journals_for_message.rb index 66ab98c9b..e1482d52b 100644 --- a/app/models/journals_for_message.rb +++ b/app/models/journals_for_message.rb @@ -26,7 +26,7 @@ class JournalsForMessage < ApplicationRecord # "is_comprehensive_evaluation", # 1 教师评论、2 匿评、3 留言 # "hidden", 隐藏、 - validates :notes, length: { maximum: 1000 } + validates :notes, length: { maximum: 1000, too_long: "内容不能超过1000个字符" } after_create :send_tiding diff --git a/app/models/library.rb b/app/models/library.rb index 982db732b..e9920c7b4 100644 --- a/app/models/library.rb +++ b/app/models/library.rb @@ -13,7 +13,7 @@ class Library < ApplicationRecord has_one :praise_tread_cache, foreign_key: :object_id has_many :praise_treads, as: :praise_tread_object, dependent: :destroy - validates :content, length: { maximum: 5000 } + validates :content, length: { maximum: 5000, too_long: "内容不能超过5000个字符" } validates :uuid, presence: true, uniqueness: true diff --git a/app/models/memo.rb b/app/models/memo.rb index 9140fb5db..8b38a911e 100644 --- a/app/models/memo.rb +++ b/app/models/memo.rb @@ -27,7 +27,7 @@ class Memo < ApplicationRecord scope :hot, -> { order("all_replies_count desc, updated_at desc") } scope :posts, -> { where(root_id: nil, forum_id: [3, 5]) } - validates :content, length: { maximum: 10000 } + validates :content, length: { maximum: 10000, too_long: "帖子内容不能超过10000个字符" } after_create :send_tiding diff --git a/app/models/message.rb b/app/models/message.rb index 7620ef11d..76ea303a9 100644 --- a/app/models/message.rb +++ b/app/models/message.rb @@ -33,7 +33,7 @@ class Message < ApplicationRecord #转发表 # has_many :forwards, as: :from, dependent: :destroy - validates :subject, length: { maximum: 255 } + validates :subject, length: { maximum: 255, too_long: "标题不能超过255个字符" } def update_content(content) message_detail.update_attributes(content: content) diff --git a/app/models/message_detail.rb b/app/models/message_detail.rb index 0d7aaa1c1..9f5269bc5 100644 --- a/app/models/message_detail.rb +++ b/app/models/message_detail.rb @@ -1,5 +1,5 @@ class MessageDetail < ApplicationRecord belongs_to :message, :touch => true - validates :content, length: { maximum: 5000 } + validates :content, length: { maximum: 5000, too_long: "内容不能超过5000个字符" } end diff --git a/app/models/poll.rb b/app/models/poll.rb index 1c38d2426..432bb01d2 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -24,8 +24,8 @@ class Poll < ApplicationRecord scope :poll_search, lambda { |keywords| where("polls_name LIKE ?", "%#{keywords}%") unless keywords.blank?} - validates :polls_name, length: { maximum: 60, too_long: "60 characters is the maximum allowed" } - validates :polls_description, length: { maximum: 100 } + validates :polls_name, length: { maximum: 60, too_long: "问卷名称不能超过60个字符" } + validates :polls_description, length: { maximum: 100, too_long: "问卷须知不能超过100个字符" } after_create :create_polls_list diff --git a/app/models/poll_answer.rb b/app/models/poll_answer.rb index c7fa7e75c..156be0974 100644 --- a/app/models/poll_answer.rb +++ b/app/models/poll_answer.rb @@ -8,6 +8,6 @@ class PollAnswer < ApplicationRecord scope :find_answer_by_custom, lambda {|k,v| where("#{k}":v)} #根据传入的参数查找问题 scope :left_answer_choose, lambda {|k,v| where("#{k} > ?",v)} #根据传入的参数查找问题 - validates :answer_text, length: { maximum: 500 } + validates :answer_text, length: { maximum: 500, too_long: "选项不能超过500个字符" } end \ No newline at end of file diff --git a/app/models/poll_question.rb b/app/models/poll_question.rb index dd7f3f95f..98c1201da 100644 --- a/app/models/poll_question.rb +++ b/app/models/poll_question.rb @@ -9,7 +9,7 @@ class PollQuestion < ApplicationRecord scope :ques_necessary, -> {where("is_necessary = ?",1)} scope :insert_question, lambda {|k| where("question_number > ?",k)} - validates :question_title, length: { maximum: 1000 } + validates :question_title, length: { maximum: 1000, too_long: "题干不能超过1000个字符" } def question_type_name case self.question_type diff --git a/app/models/poll_vote.rb b/app/models/poll_vote.rb index 2e70f1342..440881871 100644 --- a/app/models/poll_vote.rb +++ b/app/models/poll_vote.rb @@ -9,6 +9,6 @@ class PollVote < ApplicationRecord scope :find_current_vote,lambda {|k,v| where("#{k}": v)} scope :find_vote_text,-> {where("vote_text IS NOT NULL")} - validates :vote_text, length: { maximum: 5000 } + validates :vote_text, length: { maximum: 5000, too_long: "内容不能超过5000个字符" } end \ No newline at end of file diff --git a/app/models/shixun_info.rb b/app/models/shixun_info.rb index e3a8d334b..a7da422da 100644 --- a/app/models/shixun_info.rb +++ b/app/models/shixun_info.rb @@ -1,10 +1,10 @@ class ShixunInfo < ApplicationRecord belongs_to :shixun validates_uniqueness_of :shixun_id - validates_length_of :fork_reason, maximum: 60 + validates_length_of :fork_reason, maximum: 60, message: "fork原因不能超过60个字符" after_commit :create_diff_record - validates :description, length: { maximum: 5000 } + validates :description, length: { maximum: 5000, too_long: "简介不能超过5000个字符" } private diff --git a/app/models/shixun_work_comment.rb b/app/models/shixun_work_comment.rb index 1d23718d3..c20f5c509 100644 --- a/app/models/shixun_work_comment.rb +++ b/app/models/shixun_work_comment.rb @@ -2,6 +2,6 @@ class ShixunWorkComment < ApplicationRecord belongs_to :student_work belongs_to :user belongs_to :challenge, optional: true - validates :comment, length: { maximum: 500 } - validates :hidden_comment, length: { maximum: 500 } + validates :comment, length: { maximum: 500, too_long: "评语不能超过500个字符" } + validates :hidden_comment, length: { maximum: 500, too_long: "隐藏评语不能超过500个字符" } end diff --git a/app/models/stage.rb b/app/models/stage.rb index 84873b01f..f6d6b3e56 100644 --- a/app/models/stage.rb +++ b/app/models/stage.rb @@ -6,6 +6,6 @@ class Stage < ApplicationRecord has_many :stage_shixuns, -> { order("stage_shixuns.position ASC") }, dependent: :destroy has_many :shixuns, :through => :stage_shixuns - validates :name, length: { maximum: 60 } - validates :description, length: { maximum: 1000 } + validates :name, length: { maximum: 60 , too_long: "章节名称不能超过60个字符" } + validates :description, length: { maximum: 1000, too_long: "章节描述不能超过1000个字符" } end diff --git a/app/models/student_work.rb b/app/models/student_work.rb index 473efa756..83e6c7b94 100644 --- a/app/models/student_work.rb +++ b/app/models/student_work.rb @@ -19,7 +19,7 @@ class StudentWork < ApplicationRecord before_save :set_work_score - validates :description, length: { maximum: 5000 } + validates :description, length: { maximum: 5000, too_long: "描述不能超过5000个字符" } scope :has_committed, lambda { where("work_status != 0") } # 未提交 diff --git a/app/models/student_works_score.rb b/app/models/student_works_score.rb index f9f4f4220..dc8c1451b 100644 --- a/app/models/student_works_score.rb +++ b/app/models/student_works_score.rb @@ -7,7 +7,7 @@ class StudentWorksScore < ApplicationRecord has_many :tidings, as: :container, dependent: :destroy has_many :attachments, as: :container, dependent: :destroy - validates :comment, length: { maximum: 1000 } + validates :comment, length: { maximum: 1000, too_long: "评语不能超过1000个字符" } scope :shixun_comment, lambda { where(is_ultimate: 0) } diff --git a/app/models/subject.rb b/app/models/subject.rb index df9271e5f..459889004 100644 --- a/app/models/subject.rb +++ b/app/models/subject.rb @@ -31,9 +31,9 @@ class Subject < ApplicationRecord has_many :subject_shixun_infos, dependent: :destroy has_many :subject_user_infos, dependent: :destroy - validates :name, length: { maximum: 60 } - validates :description, length: { maximum: 8000 } - validates :learning_notes, length: { maximum: 2000 } + validates :name, length: { maximum: 60, too_long: "实践课程名称不能超过60个字符" } + validates :description, length: { maximum: 8000, too_long: "实践课程简介不能超过8000个字符" } + validates :learning_notes, length: { maximum: 2000, too_long: "实践课程须知不能超过2000个字符" } scope :visible, lambda{where(status: 2)} scope :published, lambda{where(status: 1)} diff --git a/app/models/test_set.rb b/app/models/test_set.rb index 1fae89afa..f843bfc43 100644 --- a/app/models/test_set.rb +++ b/app/models/test_set.rb @@ -1,7 +1,7 @@ class TestSet < ApplicationRecord # match_rule: 匹配规则: full: 完全匹配, last: 末尾匹配 # - validates :input, length: { maximum: 5000 } - validates :input, length: { maximum: 5000 } + validates :input, length: { maximum: 5000, too_long: "输入不能超过5000个字符" } + validates :output, length: { maximum: 5000, too_long: "输出不能超过5000个字符" } end diff --git a/app/models/trustie_hack.rb b/app/models/trustie_hack.rb index 7c2f3264b..eb2cc06e4 100644 --- a/app/models/trustie_hack.rb +++ b/app/models/trustie_hack.rb @@ -1,5 +1,5 @@ class TrustieHack < ApplicationRecord - validates_length_of :description, maximum: 500 + validates_length_of :description, maximum: 500, message: "描述不能超过500个字符" has_many :hack_users, :dependent => :destroy belongs_to :trustie_hackathon, counter_cache: true From 0d7e81d150a64e02d377bfd617072ac89c6d6949 Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Fri, 10 Jan 2020 19:08:25 +0800 Subject: [PATCH 081/156] =?UTF-8?q?=E5=AD=97=E7=AC=A6=E9=99=90=E5=88=B6?= =?UTF-8?q?=E7=9A=84=E6=96=87=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/graduation_tasks_controller.rb | 8 ++++---- app/controllers/memos_controller.rb | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/controllers/graduation_tasks_controller.rb b/app/controllers/graduation_tasks_controller.rb index dcb9a3bc3..cac763344 100644 --- a/app/controllers/graduation_tasks_controller.rb +++ b/app/controllers/graduation_tasks_controller.rb @@ -606,10 +606,10 @@ class GraduationTasksController < ApplicationController end def graduation_task_params - tip_exception("task_type参数不能为空") if params[:task_type].blank? - tip_exception("name参数不能为空") if params[:name].blank? - tip_exception("name参数不能超过60个字符") if params[:name].length > 60 #6.11 -hs - tip_exception("description参数不能为空") if params[:description].blank? + tip_exception("类型参数不能为空") if params[:task_type].blank? + tip_exception("名称不能为空") if params[:name].blank? + tip_exception("名称不能超过60个字符") if params[:name].length > 60 #6.11 -hs + tip_exception("描述不能为空") if params[:description].blank? params.require(:graduation_task).permit(:task_type, :name, :description) end diff --git a/app/controllers/memos_controller.rb b/app/controllers/memos_controller.rb index 3c76972b8..a4d72371c 100644 --- a/app/controllers/memos_controller.rb +++ b/app/controllers/memos_controller.rb @@ -144,7 +144,7 @@ class MemosController < ApplicationController def reply tip_exception("parent_id不能为空") if params[:parent_id].blank? tip_exception("content不能为空") if params[:content].blank? - tip_exception("content不能超过1000字符") if params[:content].length > 1000 + tip_exception("内容不能超过1000字符") if params[:content].length > 1000 ActiveRecord::Base.transaction do begin From 5e4f53570fcbc01e73f0949d56e4990c45c43502 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Fri, 10 Jan 2020 19:15:57 +0800 Subject: [PATCH 082/156] =?UTF-8?q?=E6=B8=85=E7=90=86conslog?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/modules/question/NewMyShixunModel.js | 40 +++++++------- .../react/src/modules/question/Paperreview.js | 18 +++---- .../src/modules/question/Paperreview_item.js | 22 ++++---- .../src/modules/question/Paperreview_items.js | 6 +-- .../modules/question/Paperreview_judgment.js | 2 +- .../modules/question/Paperreview_multlple.js | 2 +- .../modules/question/Paperreview_program.js | 2 +- public/react/src/modules/question/Question.js | 36 ++++++------- .../modules/question/Questionitem_banks.js | 42 +++++++-------- .../question/component/ChoquesEditor.js | 24 ++++----- .../modules/question/component/Contentpart.js | 4 +- .../question/component/Contentquestionbank.js | 10 ++-- .../question/component/Headplugselection.js | 4 +- .../question/component/Headplugselections.js | 17 +++--- .../question/component/IntelligentModel.js | 2 +- .../question/component/Itembankstop.js | 54 +++++++++---------- .../question/component/JudquestionEditor.js | 34 ++++++------ .../question/component/Newknledpots.js | 10 ++-- .../component/Paperreview_itemModel.js | 4 +- .../component/Paperreview_itemModels.js | 4 +- .../modules/question/component/SiderBars.js | 6 +-- .../question/component/SingleEditor.js | 48 ++++++++++------- .../comthetestpaper/Comthetestpaperst.js | 38 ++++++------- .../comthetestpaper/Intelligentcomponents.js | 30 +++++------ .../src/modules/testpaper/Intecomponents.js | 32 +++++------ .../modules/testpaper/Paperlibraryeditid.js | 10 ++-- .../modules/testpaper/Paperlibraryseeid.js | 4 +- .../src/modules/testpaper/Testpaperlibrary.js | 20 +++---- .../component/Contentquestionbank.js | 10 ++-- .../component/Paperlibraryseeid_item.js | 36 ++++++------- .../component/Paperlibraryseeid_itemss.js | 22 ++++---- 31 files changed, 299 insertions(+), 294 deletions(-) diff --git a/public/react/src/modules/question/NewMyShixunModel.js b/public/react/src/modules/question/NewMyShixunModel.js index 8922abd76..232ba9d72 100644 --- a/public/react/src/modules/question/NewMyShixunModel.js +++ b/public/react/src/modules/question/NewMyShixunModel.js @@ -97,7 +97,7 @@ class NewMyShixunModel extends Component { } - setsub_discipline_id=(sub_discipline_id)=>{ + setsub_discipline_id=(discipline_id,sub_discipline_id)=>{ this.setState({ sub_discipline_id:sub_discipline_id, tag_discipline_id:null, @@ -107,7 +107,7 @@ class NewMyShixunModel extends Component { oj_status:null }) var data = { - discipline_id:this.state.discipline_id, + discipline_id:discipline_id, sub_discipline_id:sub_discipline_id, tag_discipline_id:null, public: this.state.defaultActiveKey, @@ -161,8 +161,8 @@ class NewMyShixunModel extends Component { this.callback(defaultActiveKeys); let url = `/users/get_navigation_info.json`; axios.get(url, {}).then((response) => { - // ////console.log("开始请求/get_navigation_info.json"); - // ////console.log(response); + // //////console.log("开始请求/get_navigation_info.json"); + // //////console.log(response); if (response != undefined) { if (response.status === 200) { this.setState({ @@ -180,8 +180,8 @@ class NewMyShixunModel extends Component { axios.get(urls, {params: { source:"question" }}).then((response) => { - console.log("Questiondisciplines"); - console.log(response.data); + //console.log("Questiondisciplines"); + //console.log(response.data); if (response) { this.setState({ disciplinesdata: response.data.disciplines, @@ -254,15 +254,15 @@ class NewMyShixunModel extends Component { } else { } - ////console.log("item_banks"); - ////console.log(response); + //////console.log("item_banks"); + //////console.log(response); this.setState({ Contentdata: response.data, items_count: response.data.items_count, }) this.getdataslen(response.data.items); }).catch((error) => { - ////console.log(error) + //////console.log(error) this.setState({ booljupyterurls:false, }) @@ -288,8 +288,8 @@ class NewMyShixunModel extends Component { } else { } - ////console.log("item_banks"); - ////console.log(response); + //////console.log("item_banks"); + //////console.log(response); this.setState({ Contentdata: response.data, items_count: response.data.items_count, @@ -590,7 +590,7 @@ class NewMyShixunModel extends Component { } }) .catch(function (error) { - //console.log(error); + ////console.log(error); }); } publicopentimu = (id) => { @@ -616,7 +616,7 @@ class NewMyShixunModel extends Component { this.getdata(data); } }).catch((error) => { - //console.log(error); + ////console.log(error); }) } @@ -625,8 +625,8 @@ class NewMyShixunModel extends Component { // const url = "/item_baskets/basket_list.json"; // axios.get(url) // .then((result) => { - // // //console.log("getbasket_listdata"); - // // //console.log(result.data); + // // ////console.log("getbasket_listdata"); + // // ////console.log(result.data); // this.setState({ // completion_questions_count: result.data.completion_questions_count, // judgement_questions_count: result.data.judgement_questions_count, @@ -638,7 +638,7 @@ class NewMyShixunModel extends Component { // }) // // }).catch((error) => { - // // //console.log(error); + // // ////console.log(error); // this.setState({ // completion_questions_count: 0, // judgement_questions_count: 0, @@ -687,7 +687,7 @@ class NewMyShixunModel extends Component { // }) } }).catch((error) => { - //console.log(error); + ////console.log(error); }) } // 撤销 @@ -715,7 +715,7 @@ class NewMyShixunModel extends Component { this.getbasket_listdata(); } }).catch((error) => { - //console.log(error); + ////console.log(error); }) }else{ url=`/examination_banks/${this.props.exam_id}/revoke_item.json`; @@ -741,7 +741,7 @@ class NewMyShixunModel extends Component { this.getbasket_listdata(); } }).catch((error) => { - //console.log(error); + ////console.log(error); }) } @@ -815,7 +815,7 @@ class NewMyShixunModel extends Component { } }) .catch(function (error) { - //console.log(error); + ////console.log(error); }); } diff --git a/public/react/src/modules/question/Paperreview.js b/public/react/src/modules/question/Paperreview.js index b321a40a2..2adc77c03 100644 --- a/public/react/src/modules/question/Paperreview.js +++ b/public/react/src/modules/question/Paperreview.js @@ -67,8 +67,8 @@ class Paperreview extends Component { //初始化 componentDidMount() { - console.log("Paperreview.js"); - console.log(this.props.match.params); + //console.log("Paperreview.js"); + //console.log(this.props.match.params); this.setState({ artificialtype:this.props.match.params.type }) @@ -185,7 +185,7 @@ class Paperreview extends Component { } }).catch((error) => { - ////console.log(error) + //////console.log(error) this.setState({ booljupyterurls: false, }) @@ -238,7 +238,7 @@ class Paperreview extends Component { this.props.history.replace('/paperlibrary'); } }).catch((error) => { - console.log(error); + //console.log(error); }) }else{ @@ -321,12 +321,12 @@ class Paperreview extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - console.log(result); + //console.log(result); var data = {} this.getdata(data); } }).catch((error) => { - console.log(error); + //console.log(error); }) } //换题 @@ -338,12 +338,12 @@ class Paperreview extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - console.log(result); + //console.log(result); var data = {} this.getdata(data); } }).catch((error) => { - console.log(error); + //console.log(error); }) } @@ -361,7 +361,7 @@ class Paperreview extends Component { render() { let {page, limit, count, Headertop, visible, placement, modalsType, item_type,artificialtype,Cohetepaperbool,newmyshixunmodelbool,Intelligentformation} = this.state; const params = this.props && this.props.match && this.props.match.params; - // //console.log(params); + // ////console.log(params); return (
    { - console.log(error); + //console.log(error); }) } @@ -114,7 +114,7 @@ class Paperreview_item extends Component { this.props.getdata({}); } }).catch((error) => { - console.log(error); + //console.log(error); }) @@ -135,7 +135,7 @@ class Paperreview_item extends Component { this.props.getdata({}); } }).catch((error) => { - console.log(error); + //console.log(error); }) } @@ -155,7 +155,7 @@ class Paperreview_item extends Component { this.props.getdata({}); } }).catch((error) => { - console.log(error); + //console.log(error); }) } @@ -190,7 +190,7 @@ class Paperreview_item extends Component { this.Singlemagazine("", false); } }).catch((error) => { - console.log(error); + //console.log(error); }) } @@ -207,7 +207,7 @@ class Paperreview_item extends Component { this.Singlemagazines(false); } }).catch((error) => { - console.log(error); + //console.log(error); }) } @@ -255,7 +255,7 @@ class Paperreview_item extends Component { } }) .catch(function (error) { - //console.log(error); + ////console.log(error); }); @@ -299,7 +299,7 @@ class Paperreview_item extends Component { } hideparagraph = (name) => { - console.log("hideparagraph"); + //console.log("hideparagraph"); } @@ -312,7 +312,7 @@ class Paperreview_item extends Component { }) } showparagraph = (name) => { - console.log("showparagraph"); + //console.log("showparagraph"); if (name === "SINGLE") { this.setState({ singlebool: true, @@ -364,8 +364,8 @@ class Paperreview_item extends Component { } showparagraphs = (e,name) => { - // console.log("showparagraphs"); - // console.log(e); + // //console.log("showparagraphs"); + // //console.log(e); this.setState({ paperreviewsingleindex: e, paperreviewsinglename:name, diff --git a/public/react/src/modules/question/Paperreview_items.js b/public/react/src/modules/question/Paperreview_items.js index fde883105..75ed4a248 100644 --- a/public/react/src/modules/question/Paperreview_items.js +++ b/public/react/src/modules/question/Paperreview_items.js @@ -58,9 +58,9 @@ class Paperreview_items extends Component { render() { let {paperreviewsingleindex,paperreviewsinglename,typenames,indexs,object,typenamesn}=this.props; - // console.log(object); - // console.log("Paperreview_items"); - // console.log(object.item_id); + // //console.log(object); + // //console.log("Paperreview_items"); + // //console.log(object.item_id); return (
    { diff --git a/public/react/src/modules/question/Paperreview_judgment.js b/public/react/src/modules/question/Paperreview_judgment.js index 7e5b884be..c2736356d 100644 --- a/public/react/src/modules/question/Paperreview_judgment.js +++ b/public/react/src/modules/question/Paperreview_judgment.js @@ -59,7 +59,7 @@ class Paperreview_judgment extends Component { render() { let {questions,totalscore,total,items} = this.state; - // //console.log(params); + // ////console.log(params); return (
    { + setsub_discipline_id=(discipline_id,sub_discipline_id)=>{ this.setState({ sub_discipline_id:sub_discipline_id, tag_discipline_id:null, @@ -123,7 +123,7 @@ class Question extends Component { oj_status:null }) var data = { - discipline_id:this.state.discipline_id, + discipline_id:discipline_id, sub_discipline_id:sub_discipline_id, tag_discipline_id:null, public: this.state.defaultActiveKey, @@ -179,8 +179,8 @@ class Question extends Component { axios.get(urls, {params: { source:"question" }}).then((response) => { - console.log("Questiondisciplines"); - console.log(response.data); + //console.log("Questiondisciplines"); + //console.log(response.data); if (response) { this.setState({ disciplinesdata: response.data.disciplines, @@ -234,15 +234,15 @@ class Question extends Component { } else { } - ////console.log("item_banks"); - ////console.log(response); + //////console.log("item_banks"); + //////console.log(response); this.setState({ Contentdata: response.data, items_count: response.data.items_count, }) this.getdataslen(response.data.items); }).catch((error) => { - ////console.log(error) + //////console.log(error) this.setState({ booljupyterurls:false, }) @@ -268,8 +268,8 @@ class Question extends Component { } else { } - ////console.log("item_banks"); - ////console.log(response); + //////console.log("item_banks"); + //////console.log(response); this.setState({ Contentdata: response.data, items_count: response.data.items_count, @@ -566,7 +566,7 @@ class Question extends Component { } }) .catch(function (error) { - //console.log(error); + ////console.log(error); }); } publicopentimu = (id) => { @@ -590,7 +590,7 @@ class Question extends Component { this.getdata(data); } }).catch((error) => { - //console.log(error); + ////console.log(error); }) } @@ -599,8 +599,8 @@ class Question extends Component { const url = "/item_baskets/basket_list.json"; axios.get(url) .then((result) => { - // //console.log("getbasket_listdata"); - // //console.log(result.data); + // ////console.log("getbasket_listdata"); + // ////console.log(result.data); this.setState({ completion_questions_count: result.data.completion_questions_count, judgement_questions_count: result.data.judgement_questions_count, @@ -612,7 +612,7 @@ class Question extends Component { }) }).catch((error) => { - // //console.log(error); + // ////console.log(error); this.setState({ completion_questions_count: 0, judgement_questions_count: 0, @@ -654,7 +654,7 @@ class Question extends Component { // }) } }).catch((error) => { - //console.log(error); + ////console.log(error); }) } // 撤销 @@ -681,7 +681,7 @@ class Question extends Component { this.getbasket_listdata(); } }).catch((error) => { - //console.log(error); + ////console.log(error); }) } //全选试题库 @@ -750,7 +750,7 @@ class Question extends Component { } }) .catch(function (error) { - //console.log(error); + ////console.log(error); }); } @@ -902,7 +902,7 @@ class Question extends Component { setdifficulty={(e) => this.setdifficulty(e)} setitem_types={(e) => this.setitem_types(e)} setdiscipline_id={(e)=>this.setdiscipline_id(e)} - setsub_discipline_id={(e)=>this.setsub_discipline_id(e)} + setsub_discipline_id={(e,id)=>this.setsub_discipline_id(e,id)} settag_discipline_id={(e)=>this.settag_discipline_id(e)} /> {/*头部*/} diff --git a/public/react/src/modules/question/Questionitem_banks.js b/public/react/src/modules/question/Questionitem_banks.js index 0c27dc0fa..549bcc5ae 100644 --- a/public/react/src/modules/question/Questionitem_banks.js +++ b/public/react/src/modules/question/Questionitem_banks.js @@ -52,8 +52,8 @@ class Questionitem_banks extends Component { // axios.get(url, { // // }).then((response) => { - // // //////console.log("开始请求/get_navigation_info.json"); - // // //////console.log(response); + // // ////////console.log("开始请求/get_navigation_info.json"); + // // ////////console.log(response); // if(response!=undefined){ // if(response.status===200){ // this.setState({ @@ -80,15 +80,15 @@ class Questionitem_banks extends Component { } else { } - //////console.log("item_banks"); - //console.log("Questionitem_banks"); - //console.log(response.data); + ////////console.log("item_banks"); + ////console.log("Questionitem_banks"); + ////console.log(response.data); this.setState({ item_banksedit: response.data, }) }).catch((error) => { - //////console.log(error) + ////////console.log(error) }); @@ -173,10 +173,10 @@ class Questionitem_banks extends Component { // }else{ // // } - // //////console.log("item_banks"); - // //////console.log(response); + // ////////console.log("item_banks"); + // ////////console.log(response); // }).catch((error) => { - // //////console.log(error) + // ////////console.log(error) // // }); } @@ -239,7 +239,7 @@ class Questionitem_banks extends Component { if (this.state.item_type === "SINGLE") { if (this.answerMdRef != null) { //单选题 - // //console.log(this.answerMdRef.onSave()); + // ////console.log(this.answerMdRef.onSave()); if (this.answerMdRef.onSave().length === 0) { return; @@ -287,7 +287,7 @@ class Questionitem_banks extends Component { } }).catch((error) => { - //console.log(error); + ////console.log(error); }) } else { axios.put(url, data) @@ -299,7 +299,7 @@ class Questionitem_banks extends Component { } }).catch((error) => { - //console.log(error); + ////console.log(error); }) } @@ -311,7 +311,7 @@ class Questionitem_banks extends Component { if (this.state.item_type === "MULTIPLE") { if (this.Choques != null) { //多选题 - // //console.log(this.Choques.onSave()); + // ////console.log(this.Choques.onSave()); if (this.Choques.onSave().length === 0) { return; } @@ -319,8 +319,8 @@ class Questionitem_banks extends Component { const choices = []; // 1: [3] // 2: (4) ["1", "2", "3", "4"] - //console.log("MULTIPLE"); - //console.log(anserdata); + ////console.log("MULTIPLE"); + ////console.log(anserdata); for (var k = 0; k < anserdata[2].length; k++) { var bool = false @@ -366,7 +366,7 @@ class Questionitem_banks extends Component { } }).catch((error) => { - //console.log(error); + ////console.log(error); }) } else { @@ -379,7 +379,7 @@ class Questionitem_banks extends Component { } }).catch((error) => { - //console.log(error); + ////console.log(error); }) } @@ -390,7 +390,7 @@ class Questionitem_banks extends Component { if (this.state.item_type === "JUDGMENT") { if (this.Judquestio != null) { //判断题 - // //console.log(this.Judquestio.onSave()); + // ////console.log(this.Judquestio.onSave()); if (this.Judquestio.onSave().length === 0) { return; } @@ -432,7 +432,7 @@ class Questionitem_banks extends Component { } }).catch((error) => { - //console.log(error); + ////console.log(error); }) } else { @@ -444,7 +444,7 @@ class Questionitem_banks extends Component { } }).catch((error) => { - //console.log(error); + ////console.log(error); }) } @@ -482,7 +482,7 @@ class Questionitem_banks extends Component { render() { let {page, limit, count, Headertop, visible, placement, modalsType, item_type} = this.state; const params = this.props && this.props.match && this.props.match.params; - // //console.log(params); + // ////console.log(params); return (
    { const { question_choices, standard_answers } = this.state; - // ////console.log("addOption"); - // ////console.log(question_choices); - // ////console.log(standard_answers); + // //////console.log("addOption"); + // //////console.log(question_choices); + // //////console.log(standard_answers); question_choices.push('') @@ -95,8 +95,8 @@ class ChoquesEditor extends Component{ deleteOption = (index) => { let {question_choices}=this.state; - // ////console.log("deleteOption"); - // ////console.log(question_choices); + // //////console.log("deleteOption"); + // //////console.log(question_choices); if(question_choices[index]===""){ // repeat code @@ -199,9 +199,9 @@ class ChoquesEditor extends Component{ } } componentDidUpdate(prevProps) { - //console.log("componentDidUpdate"); - // //console.log(prevProps); - // //console.log(this.props.item_banksedit); + ////console.log("componentDidUpdate"); + // ////console.log(prevProps); + // ////console.log(this.props.item_banksedit); if(prevProps.item_banksedit !== this.props.item_banksedit) { this.setState({ @@ -244,7 +244,7 @@ class ChoquesEditor extends Component{ } let question_choices = this.state.question_choices.slice(0); question_choices[index] = texts; - console.log(question_choices); + //console.log(question_choices); this.setState({ question_choices }); } @@ -333,9 +333,9 @@ class ChoquesEditor extends Component{ // [true, false, true] -> [0, 2] const answerTagArray = standard_answers.map((item, index) => { return item == true ? tagArray[index] : -1 }).filter(item => item != -1); - // ////console.log("xuanzheshijuan"); - // ////console.log(answerTagArray); - // ////console.log(!exerciseIsPublish); + // //////console.log("xuanzheshijuan"); + // //////console.log(answerTagArray); + // //////console.log(!exerciseIsPublish); return(
    diff --git a/public/react/src/modules/question/component/Contentpart.js b/public/react/src/modules/question/component/Contentpart.js index 11305f3eb..96ac64153 100644 --- a/public/react/src/modules/question/component/Contentpart.js +++ b/public/react/src/modules/question/component/Contentpart.js @@ -135,8 +135,8 @@ class Contentpart extends Component { ); - console.log("Contentpart.js"); - console.log(this.props.defaultActiveKey); + //console.log("Contentpart.js"); + //console.log(this.props.defaultActiveKey); return (
    diff --git a/public/react/src/modules/question/component/Contentquestionbank.js b/public/react/src/modules/question/component/Contentquestionbank.js index 8ec8cf955..79e8bbb88 100644 --- a/public/react/src/modules/question/component/Contentquestionbank.js +++ b/public/react/src/modules/question/component/Contentquestionbank.js @@ -20,9 +20,9 @@ class Contentquestionbank extends Component { } //初始化 componentDidMount(){ - ////console.log("componentDidMount"); - ////console.log(this.state); - ////console.log(this.props); + //////console.log("componentDidMount"); + //////console.log(this.state); + //////console.log(this.props); // let homeworkid = this.props.match.params.homeworkid; // let url = "/homework_commons/" + homeworkid + "/end_groups.json"; // axios.get(url).then((response) => { @@ -30,12 +30,12 @@ class Contentquestionbank extends Component { // this.setState({}) // } // }).catch((error) => { - // ////console.log(error) + // //////console.log(error) // }); } onChange=(e)=> { - ////console.log(`checked = ${e.target.checked}`); + //////console.log(`checked = ${e.target.checked}`); } render() { diff --git a/public/react/src/modules/question/component/Headplugselection.js b/public/react/src/modules/question/component/Headplugselection.js index 142a316cb..26495fdf8 100644 --- a/public/react/src/modules/question/component/Headplugselection.js +++ b/public/react/src/modules/question/component/Headplugselection.js @@ -77,8 +77,8 @@ class Headplugselection extends Component { } render() { let {page,titlestting,titlesttings,titlesttingss}=this.state; - // console.log("Headplugselection"); - // console.log(this.props.disciplinesdata); + // //console.log("Headplugselection"); + // //console.log(this.props.disciplinesdata); // disciplinesdatakc:kc, // disciplinesdatazsd:zsd, var kc=0; diff --git a/public/react/src/modules/question/component/Headplugselections.js b/public/react/src/modules/question/component/Headplugselections.js index 206b556e9..643729ec1 100644 --- a/public/react/src/modules/question/component/Headplugselections.js +++ b/public/react/src/modules/question/component/Headplugselections.js @@ -48,10 +48,7 @@ class Headplugselections extends Component { componentDidMount(){ } -// -// setdiscipline_id={(e)=>this.setdiscipline_id(e)} -// setsub_discipline_id={(e)=>this.setsub_discipline_id(e)} -// settag_discipline_id={(e)=>this.settag_discipline_id(e)} + settitlestting=(name,id)=>{ //如果全部其他的选项重置 this.setState({ @@ -87,8 +84,8 @@ class Headplugselections extends Component { //获取方向 shixunsearchAll = (id) => { - console.log("获取方向"); - console.log(id); + //console.log("获取方向"); + //console.log(id); if(id!=undefined){ this.setState({ shixunsearchAllvalue:id, @@ -130,16 +127,16 @@ class Headplugselections extends Component { } getshixunchildValue = (id,ids) => { - console.log("getshixunchildValue"); - console.log(id); - debugger + // //console.log("getshixunchildValue"); + // //console.log(id); + // debugger if(id!=undefined ||ids!=undefined){ this.setState({ shixunsearchAllvalue:ids }) try { - this.props.setsub_discipline_id(id); + this.props.setsub_discipline_id(ids,id); }catch (e) { } diff --git a/public/react/src/modules/question/component/IntelligentModel.js b/public/react/src/modules/question/component/IntelligentModel.js index fecef37d0..016c00d2c 100644 --- a/public/react/src/modules/question/component/IntelligentModel.js +++ b/public/react/src/modules/question/component/IntelligentModel.js @@ -60,7 +60,7 @@ class IntelligentModel extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - console.log(result); + //console.log(result); this.props.history.push(`/paperlibrary`); } diff --git a/public/react/src/modules/question/component/Itembankstop.js b/public/react/src/modules/question/component/Itembankstop.js index d931286b5..b7143f6a1 100644 --- a/public/react/src/modules/question/component/Itembankstop.js +++ b/public/react/src/modules/question/component/Itembankstop.js @@ -99,10 +99,10 @@ class Itembankstop extends Component { options: this.props.disciplmy, }) - console.log("数据"); - console.log(this.props); + //console.log("数据"); + //console.log(this.props); const parsed = queryString.parse(this.props.location.search); - console.log(parsed); + //console.log(parsed); try { if(JSON.stringify(parsed)==={}||JSON.stringify(parsed)==="{}"){ @@ -156,7 +156,7 @@ class Itembankstop extends Component { }) } if(prevProps.disciplinesdata!== this.props.disciplinesdata){ - console.log("新增开始加载了") + //console.log("新增开始加载了") try { if(this.props.item_banksedit.discipline &&this.props.item_banksedit.sub_discipline){ const didata = this.props.disciplinesdata; @@ -351,8 +351,8 @@ class Itembankstop extends Component { this.props.form.validateFields((err, values) => { data = [] if (!err) { - // ////console.log("获取的form 数据"); - // ////console.log(values); + // //////console.log("获取的form 数据"); + // //////console.log(values); data.push({ rbnd: parseInt(values.rbnd) }) @@ -376,8 +376,8 @@ class Itembankstop extends Component { e.preventDefault(); this.props.form.validateFields((err, values) => { if (!err) { - ////console.log("获取的form 数据"); - ////console.log(values); + //////console.log("获取的form 数据"); + //////console.log(values); } @@ -386,8 +386,8 @@ class Itembankstop extends Component { } handleFormLayoutChangeysl = (value) => { //难度塞选 - ////console.log("难度塞选"); - ////console.log(value); + //////console.log("难度塞选"); + //////console.log(value); this.props.form.setFieldsValue({ rbnd: value+ "", }); @@ -398,8 +398,8 @@ class Itembankstop extends Component { } handleFormLayoutChange = (e) => { //难度塞选 - ////console.log("难度塞选"); - ////console.log(value); + //////console.log("难度塞选"); + //////console.log(value); this.props.form.setFieldsValue({ rbnd: e.target.value + "", }); @@ -410,8 +410,8 @@ class Itembankstop extends Component { } handleFormkechen = (value) => { //课程 - ////console.log("课程"); - ////console.log(value); + //////console.log("课程"); + //////console.log(value); if(this.state.Knowpoints.length>4){ this.props.showNotification(`知识点最多选择5个`); return @@ -432,8 +432,8 @@ class Itembankstop extends Component { const _result =[]; this.state.knowledgepoints.filter(item => { if (this.state.Knowpoints.findIndex(t => t.id === item.id) === -1) { - // console.log("guonue"); - // console.log(item); + // //console.log("guonue"); + // //console.log(item); _result.push(item); } }); @@ -448,8 +448,8 @@ class Itembankstop extends Component { } handleFormzhishidian = (value) => { - console.log("handleFormzhishidian 课程"); - console.log(value); + //console.log("handleFormzhishidian 课程"); + //console.log(value); //课程 this.props.form.setFieldsValue({ @@ -458,8 +458,8 @@ class Itembankstop extends Component { this.setState({ rbkc:value, }) - // console.log("handleFormzhishidian"); - // console.log(this.props.disciplinesdata); + // //console.log("handleFormzhishidian"); + // //console.log(this.props.disciplinesdata); const didata = this.props.disciplinesdata; const knowledgepointsdata = []; @@ -503,8 +503,8 @@ class Itembankstop extends Component { handleFormtixing = (value) => { //题型 - //console.log("题型"); - //console.log(value); + ////console.log("题型"); + ////console.log(value); this.setState({ rbtx: value + "", }) @@ -515,7 +515,7 @@ class Itembankstop extends Component { } preventDefault = (e) => { e.preventDefault(); - ////console.log('Clicked! But prevent default.'); + //////console.log('Clicked! But prevent default.'); } deletesobject = (item, index) => { @@ -644,7 +644,7 @@ class Itembankstop extends Component { } }).catch((error) => { - //console.log(error); + ////console.log(error); }) this.setState({ @@ -657,9 +657,9 @@ class Itembankstop extends Component { let {page, options,NewknTypedel,knowledgepoints,knowledgepoints2,Knowpoints} = this.state; const {getFieldDecorator} = this.props.form; - // console.log("this.state.rbkc"); - // console.log(this.state.rbkc); - // console.log(options); + // //console.log("this.state.rbkc"); + // //console.log(this.state.rbkc); + // //console.log(options); return ( diff --git a/public/react/src/modules/question/component/JudquestionEditor.js b/public/react/src/modules/question/component/JudquestionEditor.js index 5888efeb0..0ab6176b2 100644 --- a/public/react/src/modules/question/component/JudquestionEditor.js +++ b/public/react/src/modules/question/component/JudquestionEditor.js @@ -62,9 +62,9 @@ class JudquestionEditor extends Component{ addOption = () => { const { question_choices, standard_answers } = this.state; - // //////console.log("addOption"); - // //////console.log(question_choices); - // //////console.log(standard_answers); + // ////////console.log("addOption"); + // ////////console.log(question_choices); + // ////////console.log(standard_answers); question_choices.push('') @@ -74,8 +74,8 @@ class JudquestionEditor extends Component{ deleteOption = (index) => { let {question_choices}=this.state; - // //////console.log("deleteOption"); - // //////console.log(question_choices); + // ////////console.log("deleteOption"); + // ////////console.log(question_choices); if(question_choices[index]===""){ // repeat code @@ -190,9 +190,9 @@ class JudquestionEditor extends Component{ } componentDidUpdate(prevProps) { - //console.log("componentDidUpdate"); - //console.log(prevProps); - //console.log(this.props.item_banksedit); + ////console.log("componentDidUpdate"); + ////console.log(prevProps); + ////console.log(this.props.item_banksedit); if(prevProps.item_banksedit !== this.props.item_banksedit){ this.setState({ @@ -230,10 +230,10 @@ class JudquestionEditor extends Component{ onOptionClick = (index) => { let standard_answers = this.state.standard_answers.slice(0); - // //////console.log("onOptionClick"); - // //////console.log(standard_answers); - // //////console.log(standard_answers[index]); - // //////console.log(!standard_answers[index]); + // ////////console.log("onOptionClick"); + // ////////console.log(standard_answers); + // ////////console.log(standard_answers[index]); + // ////////console.log(!standard_answers[index]); for (var i=0;i{ - //////console.log("难度塞选"); - //////console.log(value); + ////////console.log("难度塞选"); + ////////console.log(value); this.setState({ zqda:e.target.value, @@ -348,9 +348,9 @@ class JudquestionEditor extends Component{ // [true, false, true] -> [0, 2] const answerTagArray = standard_answers.map((item, index) => { return item == true ? tagArray[index] : -1 }).filter(item => item != -1); - // //////console.log("xuanzheshijuan"); - // //////console.log(answerTagArray); - // //////console.log(!exerciseIsPublish); + // ////////console.log("xuanzheshijuan"); + // ////////console.log(answerTagArray); + // ////////console.log(!exerciseIsPublish); const params= this.props&&this.props.match&&this.props.match.params; return(
    diff --git a/public/react/src/modules/question/component/Newknledpots.js b/public/react/src/modules/question/component/Newknledpots.js index 4668c5e5a..36dd88e10 100644 --- a/public/react/src/modules/question/component/Newknledpots.js +++ b/public/react/src/modules/question/component/Newknledpots.js @@ -18,15 +18,15 @@ class PaperDeletModel extends Component { // this.setState({ // newkntypeinput: e.target.value // }) - // console.log(e.target.value); - // console.log(e.target.value.length); + // //console.log(e.target.value); + // //console.log(e.target.value.length); this.setState({ newkntypeinput: e.target.value }) this.props.setboolred(false); // // debugger - // console.log(e); + // //console.log(e); // // if(e.target.value.length>0){ // if(e.target.value.length>=16){ @@ -38,11 +38,11 @@ class PaperDeletModel extends Component { // } } mysinputOnBlur=(e)=>{ - console.log("失去焦点了"); + //console.log("失去焦点了"); } inputOnFocus=(e)=>{ - console.log("获取焦点"); + //console.log("获取焦点"); } render() { diff --git a/public/react/src/modules/question/component/Paperreview_itemModel.js b/public/react/src/modules/question/component/Paperreview_itemModel.js index 0759bb677..b4ceacc02 100644 --- a/public/react/src/modules/question/component/Paperreview_itemModel.js +++ b/public/react/src/modules/question/component/Paperreview_itemModel.js @@ -13,8 +13,8 @@ class Paperreview_itemModel extends Component { } onChange=(value)=>{ - console.log("设置批量得分"); - console.log(value); + //console.log("设置批量得分"); + //console.log(value); this.setState({ value:value, }) diff --git a/public/react/src/modules/question/component/Paperreview_itemModels.js b/public/react/src/modules/question/component/Paperreview_itemModels.js index 167769313..ba7978aff 100644 --- a/public/react/src/modules/question/component/Paperreview_itemModels.js +++ b/public/react/src/modules/question/component/Paperreview_itemModels.js @@ -14,8 +14,8 @@ class Paperreview_itemModels extends Component { } onChange=(value)=>{ - console.log("Paperreview_itemModels"); - console.log(value); + //console.log("Paperreview_itemModels"); + //console.log(value); this.setState({ value:value, }) diff --git a/public/react/src/modules/question/component/SiderBars.js b/public/react/src/modules/question/component/SiderBars.js index 66ccb77dc..23934ea32 100644 --- a/public/react/src/modules/question/component/SiderBars.js +++ b/public/react/src/modules/question/component/SiderBars.js @@ -25,7 +25,7 @@ $(window).scroll(function(){ function rightSlider(){ var poi=parseInt((parseInt($(window).width())- 1200 )/2)-81; - // console.log(parseInt($(window).width())+" "+poi); + // //console.log(parseInt($(window).width())+" "+poi); if(poi>0){ $(".-task-sidebar").css("right",poi); }else{ @@ -89,8 +89,8 @@ class SiderBars extends Component { render() { - // console.log("SiderBar"); - // console.log(this.props); + // //console.log("SiderBar"); + // //console.log(this.props); var mypath= this.props&&this.props.match&&this.props.match.path; let{myvisible,Datacount,animateStyle}=this.props; diff --git a/public/react/src/modules/question/component/SingleEditor.js b/public/react/src/modules/question/component/SingleEditor.js index 876cb4354..dffbf620c 100644 --- a/public/react/src/modules/question/component/SingleEditor.js +++ b/public/react/src/modules/question/component/SingleEditor.js @@ -52,8 +52,8 @@ class SingleEditor extends Component{ if(this.props.item_banksedit.choices){ this.props.item_banksedit.choices.forEach((item, index) => { - //console.log("SingleEditor"); - //console.log(item); + ////console.log("SingleEditor"); + ////console.log(item); choicescomy.push({ choice_text:item.choice_text, standard_boolean:item.is_answer, @@ -87,9 +87,9 @@ class SingleEditor extends Component{ addOption = () => { const { question_choices, standard_answers } = this.state; - // ////console.log("addOption"); - // ////console.log(question_choices); - // ////console.log(standard_answers); + // //////console.log("addOption"); + // //////console.log(question_choices); + // //////console.log(standard_answers); question_choices.push('') @@ -99,8 +99,8 @@ class SingleEditor extends Component{ deleteOption = (index) => { let {question_choices}=this.state; - // ////console.log("deleteOption"); - // ////console.log(question_choices); + // //////console.log("deleteOption"); + // //////console.log(question_choices); if(question_choices[index]===""){ // repeat code @@ -209,9 +209,9 @@ class SingleEditor extends Component{ } } componentDidUpdate(prevProps) { - //console.log("componentDidUpdate"); - // //console.log(prevProps); - // //console.log(this.props.item_banksedit); + ////console.log("componentDidUpdate"); + // ////console.log(prevProps); + // ////console.log(this.props.item_banksedit); if(prevProps.item_banksedit !== this.props.item_banksedit) { this.setState({ @@ -228,10 +228,10 @@ class SingleEditor extends Component{ onOptionClick = (index) => { let standard_answers = this.state.standard_answers.slice(0); - // ////console.log("onOptionClick"); - // ////console.log(standard_answers); - // ////console.log(standard_answers[index]); - // ////console.log(!standard_answers[index]); + // //////console.log("onOptionClick"); + // //////console.log(standard_answers); + // //////console.log(standard_answers[index]); + // //////console.log(!standard_answers[index]); for (var i=0;i{ - const _text = quill.getText(); + var _text = quill.getText(); + const reg = /^[\s\S]*.*[^\s][\s\S]*$/; if (!reg.test(_text)) { // 处理编辑器内容为空 @@ -295,6 +296,7 @@ class SingleEditor extends Component{ }) } else { // 提交到后台的内容需要处理一下; + var texts=""; if(_text.length>=1001){ var result = _text.substring(0,1000); @@ -307,6 +309,12 @@ class SingleEditor extends Component{ this.setState({ question_titleysl:texts }) + try { + //console.log("onContentChange"); + //console.log(quill.getText().length); + }catch (e) { + + } } } onContentChanges=(value,quill)=>{ @@ -333,8 +341,8 @@ class SingleEditor extends Component{ } } handleShowImage = (url) => { - console.log("点击了图片放大"); - console.log(url); + //console.log("点击了图片放大"); + //console.log(url); alert(url); } @@ -357,9 +365,9 @@ class SingleEditor extends Component{ // [true, false, true] -> [0, 2] const answerTagArray = standard_answers.map((item, index) => { return item == true ? tagArray[index] : -1 }).filter(item => item != -1); - // ////console.log("xuanzheshijuan"); - // ////console.log(answerTagArray); - // ////console.log(!exerciseIsPublish); + // //////console.log("xuanzheshijuan"); + // //////console.log(answerTagArray); + // //////console.log(!exerciseIsPublish); return(
    diff --git a/public/react/src/modules/question/comthetestpaper/Comthetestpaperst.js b/public/react/src/modules/question/comthetestpaper/Comthetestpaperst.js index 959840c96..bc1e8cd00 100644 --- a/public/react/src/modules/question/comthetestpaper/Comthetestpaperst.js +++ b/public/react/src/modules/question/comthetestpaper/Comthetestpaperst.js @@ -239,7 +239,7 @@ class Comthetestpaperst extends Component { }; handleChange=(e)=>{ - console.log(e); + //console.log(e); this.props.form.setFieldsValue({ // course:value, classroom:e.target.value, @@ -324,8 +324,8 @@ class Comthetestpaperst extends Component { e.preventDefault(); this.props.form.validateFields((err, values) => { if (!err) { - ////console.log("获取的form 数据"); - ////console.log(values); + //////console.log("获取的form 数据"); + //////console.log(values); } @@ -334,8 +334,8 @@ class Comthetestpaperst extends Component { } handleFormLayoutChangeysl = (value) => { //难度塞选 - ////console.log("难度塞选"); - ////console.log(value); + //////console.log("难度塞选"); + //////console.log(value); this.props.form.setFieldsValue({ rbnd: value + "", @@ -347,8 +347,8 @@ class Comthetestpaperst extends Component { } handleFormLayoutChange = (e) => { //难度塞选 - ////console.log("难度塞选"); - ////console.log(value); + //////console.log("难度塞选"); + //////console.log(value); this.props.form.setFieldsValue({ rbnd: e.target.value + "", @@ -360,8 +360,8 @@ class Comthetestpaperst extends Component { } handleFormkechen = (value) => { //课程 - ////console.log("课程"); - ////console.log(value); + //////console.log("课程"); + //////console.log(value); if(this.state.Knowpoints.length>4){ this.props.showNotification(`知识点最多选择5个`); return @@ -382,8 +382,8 @@ class Comthetestpaperst extends Component { const _result =[]; this.state.knowledgepoints.filter(item => { if (this.state.Knowpoints.findIndex(t => t.id === item.id) === -1) { - console.log("guonue"); - console.log(item); + //console.log("guonue"); + //console.log(item); _result.push(item); } }); @@ -398,8 +398,8 @@ class Comthetestpaperst extends Component { } handleFormzhishidian = (value) => { - console.log("handleFormzhishidian 课程"); - console.log(value); + //console.log("handleFormzhishidian 课程"); + //console.log(value); //课程 this.props.form.setFieldsValue({ @@ -408,8 +408,8 @@ class Comthetestpaperst extends Component { this.setState({ rbkc:value, }) - // console.log("handleFormzhishidian"); - // console.log(this.props.disciplinesdata); + // //console.log("handleFormzhishidian"); + // //console.log(this.props.disciplinesdata); const didata = this.props.disciplinesdata; const knowledgepointsdata = []; @@ -453,8 +453,8 @@ class Comthetestpaperst extends Component { handleFormtixing = (value) => { //题型 - //console.log("题型"); - //console.log(value); + ////console.log("题型"); + ////console.log(value); this.setState({ rbtx: value + "", }) @@ -465,7 +465,7 @@ class Comthetestpaperst extends Component { } preventDefault = (e) => { e.preventDefault(); - ////console.log('Clicked! But prevent default.'); + //////console.log('Clicked! But prevent default.'); } deletesobject = (item, index) => { debugger @@ -589,7 +589,7 @@ class Comthetestpaperst extends Component { } } }).catch((error) => { - //console.log(error); + ////console.log(error); }) this.setState({ diff --git a/public/react/src/modules/question/comthetestpaper/Intelligentcomponents.js b/public/react/src/modules/question/comthetestpaper/Intelligentcomponents.js index 63beaf28c..64d57e452 100644 --- a/public/react/src/modules/question/comthetestpaper/Intelligentcomponents.js +++ b/public/react/src/modules/question/comthetestpaper/Intelligentcomponents.js @@ -94,7 +94,7 @@ class Intelligentcomponents extends Component { }; handleChange=(e)=>{ - console.log(e); + //console.log(e); if(e.target.value){ if(e.target.value.length>60){ @@ -209,8 +209,8 @@ class Intelligentcomponents extends Component { e.preventDefault(); this.props.form.validateFields((err, values) => { if (!err) { - ////console.log("获取的form 数据"); - ////console.log(values); + //////console.log("获取的form 数据"); + //////console.log(values); } @@ -218,8 +218,8 @@ class Intelligentcomponents extends Component { }); } handleFormLayoutChanges = (e) => { - // console.log("handleFormLayoutChanges"); - // console.log(value); + // //console.log("handleFormLayoutChanges"); + // //console.log(value); // debugger //来源 this.props.form.setFieldsValue({ @@ -237,8 +237,8 @@ class Intelligentcomponents extends Component { } handleFormLayoutChange = (e) => { - // console.log("handleFormLayoutChange"); - // console.log(value); + // //console.log("handleFormLayoutChange"); + // //console.log(value); // debugger //难度塞选 this.props.form.setFieldsValue({ @@ -295,8 +295,8 @@ class Intelligentcomponents extends Component { } handleFormzhishidian = (value) => { - console.log("handleFormzhishidian 课程"); - console.log(value); + //console.log("handleFormzhishidian 课程"); + //console.log(value); //课程 this.props.form.setFieldsValue({ @@ -305,8 +305,8 @@ class Intelligentcomponents extends Component { this.setState({ rbkc:value, }) - // console.log("handleFormzhishidian"); - // console.log(this.props.disciplinesdata); + // //console.log("handleFormzhishidian"); + // //console.log(this.props.disciplinesdata); const didata = this.props.disciplinesdata; const knowledgepointsdata = []; @@ -356,8 +356,8 @@ class Intelligentcomponents extends Component { handleFormtixing = (value) => { //题型 - //console.log("题型"); - //console.log(value); + ////console.log("题型"); + ////console.log(value); this.setState({ rbtx: value + "", }) @@ -368,7 +368,7 @@ class Intelligentcomponents extends Component { } preventDefault = (e) => { e.preventDefault(); - ////console.log('Clicked! But prevent default.'); + //////console.log('Clicked! But prevent default.'); } deletesobject = (item, index) => { @@ -498,7 +498,7 @@ class Intelligentcomponents extends Component { } } }).catch((error) => { - //console.log(error); + ////console.log(error); }) //新增知识点 try { diff --git a/public/react/src/modules/testpaper/Intecomponents.js b/public/react/src/modules/testpaper/Intecomponents.js index a69d7185b..8776b6a9e 100644 --- a/public/react/src/modules/testpaper/Intecomponents.js +++ b/public/react/src/modules/testpaper/Intecomponents.js @@ -40,8 +40,8 @@ class Intecomponents extends Component { } getJudquestio = (Ref) => { - console.log("子组件对象"); - console.log(Ref); + //console.log("子组件对象"); + //console.log(Ref); this.Judquestio = Ref; } @@ -116,7 +116,7 @@ class Intecomponents extends Component { this.scrollToAnchor("Itembankstopid"); return false; } - console.log(this.Judquestio.Getdatas()); + //console.log(this.Judquestio.Getdatas()); var myrbkc=[]; var Getdatasdatas=this.Judquestio.Getdatas()[1].rbzsd; for(let myda of Getdatasdatas) { @@ -139,7 +139,7 @@ class Intecomponents extends Component { this.scrollToAnchor("Itembankstopid"); return false; } - console.log(this.Judquestio.Getdatas()); + //console.log(this.Judquestio.Getdatas()); var myrbkc=[]; var Getdatasdatas=this.Judquestio.Getdatas()[1].rbzsd; for(let myda of Getdatasdatas) { @@ -162,7 +162,7 @@ class Intecomponents extends Component { this.scrollToAnchor("Itembankstopid"); return false; } - console.log(this.Judquestio.Getdatas()); + //console.log(this.Judquestio.Getdatas()); var myrbkc=[]; var Getdatasdatas=zhishidian; for(let myda of Getdatasdatas) { @@ -184,7 +184,7 @@ class Intecomponents extends Component { this.scrollToAnchor("Itembankstopid"); return false; } - console.log(this.Judquestio.Getdatas()); + //console.log(this.Judquestio.Getdatas()); var myrbkc=[]; var Getdatasdatas=this.Judquestio.Getdatas()[1].rbzsd; for(let myda of Getdatasdatas) { @@ -204,8 +204,8 @@ class Intecomponents extends Component { getwangluodata=(url,data)=>{ axios.post(url,data).then((response) => { if (response) { - console.log("智能组卷"); - console.log(response); + //console.log("智能组卷"); + //console.log(response); if(response.data){ this.setState({ single_question_count:response.data.single_question_count, @@ -225,7 +225,7 @@ class Intecomponents extends Component { this.scrollToAnchor("Itembankstopid"); return false; } - console.log(this.Judquestio.Getdatas()); + //console.log(this.Judquestio.Getdatas()); var myrbkc=[]; var Getdatasdatas=this.Judquestio.Getdatas()[1].rbzsd; for(let myda of Getdatasdatas) { @@ -241,8 +241,8 @@ class Intecomponents extends Component { axios.post(url,data).then((response) => { if (response) { - console.log("智能组卷"); - console.log(response); + //console.log("智能组卷"); + //console.log(response); if(response.data){ this.setState({ single_question_count:response.data.single_question_count, @@ -291,9 +291,9 @@ class Intecomponents extends Component { for(let myda of Getdatasdatas) { myrbkc.push(myda.id); } - // console.log(myrbkc); - // console.log("preservation"); - // console.log(this.Judquestio.Getdatas()); + // //console.log(myrbkc); + // //console.log("preservation"); + // //console.log(this.Judquestio.Getdatas()); var question_settings =[ @@ -328,11 +328,11 @@ class Intecomponents extends Component { axios.post(url, data) .then((result) => { if (result.data.status == 0) { - console.log("组卷成功"); + //console.log("组卷成功"); this.props.history.push(`/Integeneration/Intelligence/${result.data.exam_setting_id}`); } }).catch((error) => { - console.log(error); + //console.log(error); }) } diff --git a/public/react/src/modules/testpaper/Paperlibraryeditid.js b/public/react/src/modules/testpaper/Paperlibraryeditid.js index 449de0219..c65191e96 100644 --- a/public/react/src/modules/testpaper/Paperlibraryeditid.js +++ b/public/react/src/modules/testpaper/Paperlibraryeditid.js @@ -43,8 +43,8 @@ class Paperlibraryeditid extends Component { } getJudquestio = (Ref) => { - console.log("子组件对象"); - console.log(Ref); + //console.log("子组件对象"); + //console.log(Ref); this.Judquestio = Ref; } @@ -170,7 +170,7 @@ class Paperlibraryeditid extends Component { this.props.history.push('/paperlibrary'); } }).catch((error) => { - console.log(error); + //console.log(error); }) } @@ -208,8 +208,8 @@ class Paperlibraryeditid extends Component { render() { let {paperlibrartdata,newmyshixunmodelbool} = this.state; const params = this.props && this.props.match && this.props.match.params; - // console.log("newmyshixunmodelbool"); - // console.log(newmyshixunmodelbool); + // //console.log("newmyshixunmodelbool"); + // //console.log(newmyshixunmodelbool); return (
    { - // ////console.log("开始请求/get_navigation_info.json"); - // ////console.log(response); + // //////console.log("开始请求/get_navigation_info.json"); + // //////console.log(response); if (response != undefined) { if (response.status === 200) { this.setState({ @@ -158,14 +158,14 @@ class Testpaperlibrary extends Component { } else { } - ////console.log("item_banks"); - ////console.log(response); + //////console.log("item_banks"); + //////console.log(response); this.setState({ Contentdata: response.data, items_count: response.data.exam_count, }) }).catch((error) => { - ////console.log(error) + //////console.log(error) this.setState({ booljupyterurls:false, }) @@ -194,7 +194,7 @@ class Testpaperlibrary extends Component { this.getdata(data); } - setsub_discipline_id=(sub_discipline_id)=>{ + setsub_discipline_id=(discipline_id,sub_discipline_id)=>{ this.setState({ sub_discipline_id:sub_discipline_id, tag_discipline_id:null, @@ -203,7 +203,7 @@ class Testpaperlibrary extends Component { per_page:10, }) var data = { - discipline_id:this.state.discipline_id, + discipline_id:discipline_id, sub_discipline_id:sub_discipline_id, tag_discipline_id:null, public: this.state.defaultActiveKey, @@ -291,7 +291,7 @@ class Testpaperlibrary extends Component { this.getdata(data); } }).catch((error) => { - //console.log(error); + ////console.log(error); }) } @@ -318,7 +318,7 @@ class Testpaperlibrary extends Component { } }) .catch(function (error) { - //console.log(error); + ////console.log(error); }); } @@ -434,7 +434,7 @@ class Testpaperlibrary extends Component { this.setdiscipline_id(e)} - setsub_discipline_id={(e)=>this.setsub_discipline_id(e)} + setsub_discipline_id={(e,id)=>this.setsub_discipline_id(e,id)} settag_discipline_id={(e)=>this.settag_discipline_id(e)} setitem_types={(e) => this.setitem_types(e)} setdifficulty={(e) => this.setdifficulty(e)} diff --git a/public/react/src/modules/testpaper/component/Contentquestionbank.js b/public/react/src/modules/testpaper/component/Contentquestionbank.js index 1e036f858..2ed246023 100644 --- a/public/react/src/modules/testpaper/component/Contentquestionbank.js +++ b/public/react/src/modules/testpaper/component/Contentquestionbank.js @@ -20,9 +20,9 @@ class Contentquestionbank extends Component { } //初始化 componentDidMount(){ - ////console.log("componentDidMount"); - ////console.log(this.state); - ////console.log(this.props); + //////console.log("componentDidMount"); + //////console.log(this.state); + //////console.log(this.props); // let homeworkid = this.props.match.params.homeworkid; // let url = "/homework_commons/" + homeworkid + "/end_groups.json"; // axios.get(url).then((response) => { @@ -30,12 +30,12 @@ class Contentquestionbank extends Component { // this.setState({}) // } // }).catch((error) => { - // ////console.log(error) + // //////console.log(error) // }); } onChange=(e)=> { - ////console.log(`checked = ${e.target.checked}`); + //////console.log(`checked = ${e.target.checked}`); } render() { diff --git a/public/react/src/modules/testpaper/component/Paperlibraryseeid_item.js b/public/react/src/modules/testpaper/component/Paperlibraryseeid_item.js index f85ab67d0..06298299f 100644 --- a/public/react/src/modules/testpaper/component/Paperlibraryseeid_item.js +++ b/public/react/src/modules/testpaper/component/Paperlibraryseeid_item.js @@ -69,8 +69,8 @@ class Paperreview_item extends Component { } onDragEnd = (result) => { - console.log("单选题"); - console.log(result); + //console.log("单选题"); + //console.log(result); const ids = this.props.single_questions.questions[result.source.index].id; const positions = this.props.single_questions.questions[result.destination.index].position; @@ -85,13 +85,13 @@ class Paperreview_item extends Component { this.props.getdata(); } }).catch((error) => { - console.log(error); + //console.log(error); }) } onDragEnds = (result) => { - console.log("多选题"); - console.log(result); + //console.log("多选题"); + //console.log(result); const ids = this.props.multiple_questions.questions[result.source.index].id; const positions = this.props.multiple_questions.questions[result.destination.index].position; const url = `/examination_items/${ids}/adjust_position.json`; @@ -105,7 +105,7 @@ class Paperreview_item extends Component { this.props.getdata(); } }).catch((error) => { - console.log(error); + //console.log(error); }) @@ -113,8 +113,8 @@ class Paperreview_item extends Component { onDragEndss = (result) => { - console.log("判断题"); - console.log(result); + //console.log("判断题"); + //console.log(result); const ids = this.props.judgement_questions.questions[result.source.index].id; const positions = this.props.judgement_questions.questions[result.destination.index].position; const url = `/examination_items/${ids}/adjust_position.json`; @@ -129,14 +129,14 @@ class Paperreview_item extends Component { this.props.getdata(); } }).catch((error) => { - console.log(error); + //console.log(error); }) } onDragEndsss = (result) => { - console.log("编程题"); - console.log(result); + //console.log("编程题"); + //console.log(result); const ids = this.props.program_questions.questions[result.source.index].id; const positions = this.props.program_questions.questions[result.destination.index].position; @@ -151,7 +151,7 @@ class Paperreview_item extends Component { this.props.getdata(); } }).catch((error) => { - console.log(error); + //console.log(error); }) } @@ -186,7 +186,7 @@ class Paperreview_item extends Component { this.Singlemagazine("", false); } }).catch((error) => { - console.log(error); + //console.log(error); }) } @@ -203,7 +203,7 @@ class Paperreview_item extends Component { this.Singlemagazines(false); } }).catch((error) => { - console.log(error); + //console.log(error); }) } @@ -225,7 +225,7 @@ class Paperreview_item extends Component { } hideparagraph = (name) => { - console.log("hideparagraph"); + //console.log("hideparagraph"); } @@ -238,7 +238,7 @@ class Paperreview_item extends Component { }) } showparagraph = (name) => { - console.log("showparagraph"); + //console.log("showparagraph"); if (name === "SINGLE") { this.setState({ singlebool: true, @@ -290,8 +290,8 @@ class Paperreview_item extends Component { } showparagraphs = (e,name) => { - // console.log("showparagraphs"); - // console.log(e); + // //console.log("showparagraphs"); + // //console.log(e); this.setState({ paperreviewsingleindex: e, paperreviewsinglename:name, diff --git a/public/react/src/modules/testpaper/component/Paperlibraryseeid_itemss.js b/public/react/src/modules/testpaper/component/Paperlibraryseeid_itemss.js index 066b0e4ef..b725b4e5e 100644 --- a/public/react/src/modules/testpaper/component/Paperlibraryseeid_itemss.js +++ b/public/react/src/modules/testpaper/component/Paperlibraryseeid_itemss.js @@ -93,7 +93,7 @@ class Paperlibraryseeid_itemss extends Component { this.props.getdata({}); } }).catch((error) => { - console.log(error); + //console.log(error); }) } @@ -112,7 +112,7 @@ class Paperlibraryseeid_itemss extends Component { this.props.getdata({}); } }).catch((error) => { - console.log(error); + //console.log(error); }) @@ -133,7 +133,7 @@ class Paperlibraryseeid_itemss extends Component { this.props.getdata({}); } }).catch((error) => { - console.log(error); + //console.log(error); }) } @@ -153,7 +153,7 @@ class Paperlibraryseeid_itemss extends Component { this.props.getdata({}); } }).catch((error) => { - console.log(error); + //console.log(error); }) } @@ -189,7 +189,7 @@ class Paperlibraryseeid_itemss extends Component { this.Singlemagazine("", false); } }).catch((error) => { - console.log(error); + //console.log(error); }) } @@ -206,7 +206,7 @@ class Paperlibraryseeid_itemss extends Component { this.Singlemagazines(false); } }).catch((error) => { - console.log(error); + //console.log(error); }) } @@ -255,7 +255,7 @@ class Paperlibraryseeid_itemss extends Component { } }) .catch(function (error) { - //console.log(error); + ////console.log(error); }); @@ -299,7 +299,7 @@ class Paperlibraryseeid_itemss extends Component { } hideparagraph = (name) => { - console.log("hideparagraph"); + //console.log("hideparagraph"); } @@ -312,7 +312,7 @@ class Paperlibraryseeid_itemss extends Component { }) } showparagraph = (name) => { - console.log("showparagraph"); + //console.log("showparagraph"); if (name === "SINGLE") { this.setState({ singlebool: true, @@ -364,8 +364,8 @@ class Paperlibraryseeid_itemss extends Component { } showparagraphs = (e,name) => { - // console.log("showparagraphs"); - // console.log(e); + // //console.log("showparagraphs"); + // //console.log(e); this.setState({ paperreviewsingleindex: e, paperreviewsinglename:name, From 0c6e09a75ee64dfe85b376db0a6df284702b8792 Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Fri, 10 Jan 2020 19:24:56 +0800 Subject: [PATCH 083/156] =?UTF-8?q?=E5=AD=97=E7=AC=A6=E9=99=90=E5=88=B6?= =?UTF-8?q?=E7=9A=84=E6=96=87=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/journals_for_message.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/journals_for_message.rb b/app/models/journals_for_message.rb index e1482d52b..ec59c6dca 100644 --- a/app/models/journals_for_message.rb +++ b/app/models/journals_for_message.rb @@ -26,7 +26,7 @@ class JournalsForMessage < ApplicationRecord # "is_comprehensive_evaluation", # 1 教师评论、2 匿评、3 留言 # "hidden", 隐藏、 - validates :notes, length: { maximum: 1000, too_long: "内容不能超过1000个字符" } + validates :notes, length: { maximum: 1000, message: "内容不能超过1000个字符" } after_create :send_tiding From a22eb6abd855a2bb1959a74afa0ee65a5e2674e9 Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Fri, 10 Jan 2020 19:26:50 +0800 Subject: [PATCH 084/156] =?UTF-8?q?=E5=AD=97=E7=AC=A6=E9=99=90=E5=88=B6?= =?UTF-8?q?=E7=9A=84=E6=96=87=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/journals_for_message.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/journals_for_message.rb b/app/models/journals_for_message.rb index ec59c6dca..35a58ec4c 100644 --- a/app/models/journals_for_message.rb +++ b/app/models/journals_for_message.rb @@ -26,7 +26,7 @@ class JournalsForMessage < ApplicationRecord # "is_comprehensive_evaluation", # 1 教师评论、2 匿评、3 留言 # "hidden", 隐藏、 - validates :notes, length: { maximum: 1000, message: "内容不能超过1000个字符" } + validates_length_of :notes, maximum: 1000, message: "内容不能超过1000个字符" after_create :send_tiding From 51aa5ea566ee163e724f8eeba5a9051e31ea5bf7 Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Fri, 10 Jan 2020 19:36:00 +0800 Subject: [PATCH 085/156] =?UTF-8?q?=E5=AD=97=E7=AC=A6=E9=99=90=E5=88=B6?= =?UTF-8?q?=E7=9A=84=E6=96=87=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/journals_for_message.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/journals_for_message.rb b/app/models/journals_for_message.rb index 35a58ec4c..e1482d52b 100644 --- a/app/models/journals_for_message.rb +++ b/app/models/journals_for_message.rb @@ -26,7 +26,7 @@ class JournalsForMessage < ApplicationRecord # "is_comprehensive_evaluation", # 1 教师评论、2 匿评、3 留言 # "hidden", 隐藏、 - validates_length_of :notes, maximum: 1000, message: "内容不能超过1000个字符" + validates :notes, length: { maximum: 1000, too_long: "内容不能超过1000个字符" } after_create :send_tiding From 868d2bc43c8db43dc8868823a0de934abc38dae9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Fri, 10 Jan 2020 20:43:40 +0800 Subject: [PATCH 086/156] =?UTF-8?q?=E9=A2=98=E5=BA=93=20=E6=A0=B7=E5=BC=8F?= =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/modules/question/Paperreview_single.js | 6 ++++-- .../modules/question/component/ChoquesEditor.js | 2 +- .../src/modules/question/component/Listjihe.js | 16 +++++----------- .../component/Paperlibraryseeid_items.js | 6 ++++-- 4 files changed, 14 insertions(+), 16 deletions(-) diff --git a/public/react/src/modules/question/Paperreview_single.js b/public/react/src/modules/question/Paperreview_single.js index 71c641847..a030048f3 100644 --- a/public/react/src/modules/question/Paperreview_single.js +++ b/public/react/src/modules/question/Paperreview_single.js @@ -99,7 +99,8 @@ class Paperreview_single extends Component { diff --git a/public/react/src/modules/testpaper/component/Paperlibraryseeid_items.js b/public/react/src/modules/testpaper/component/Paperlibraryseeid_items.js index 7747574dd..d4212c3f1 100644 --- a/public/react/src/modules/testpaper/component/Paperlibraryseeid_items.js +++ b/public/react/src/modules/testpaper/component/Paperlibraryseeid_items.js @@ -95,7 +95,8 @@ class Paperlibraryseeid_items extends Component {
    网址克隆
    @@ -354,11 +381,15 @@ class VNCContainer extends Component { > - - {/* */} + {/* {this.state.vnc_reseting ? : } 重置桌面系统 + */} + + {this.state.vnc_reseting ? + : } + 重置实训 {/* diff --git a/public/react/src/modules/page/VNCDisplay.js b/public/react/src/modules/page/VNCDisplay.js index b9ec77988..17dbff309 100644 --- a/public/react/src/modules/page/VNCDisplay.js +++ b/public/react/src/modules/page/VNCDisplay.js @@ -166,7 +166,8 @@ class VNCDisplay extends Component { `}
    Loading
    -
    Send CtrlAltDel
    + {/*
    Send CtrlAltDel
    */} +
    diff --git a/public/react/src/modules/page/header.scss b/public/react/src/modules/page/header.scss new file mode 100644 index 000000000..b8320638f --- /dev/null +++ b/public/react/src/modules/page/header.scss @@ -0,0 +1,6 @@ +.headerRight .exit_btn{ + color: rgba(237,237,237,1); + &:hover{ + // color: #fff; + } +} \ No newline at end of file diff --git a/public/react/src/modules/page/tpiPage.css b/public/react/src/modules/page/tpiPage.css index 0c4faee83..015a66b98 100644 --- a/public/react/src/modules/page/tpiPage.css +++ b/public/react/src/modules/page/tpiPage.css @@ -120,8 +120,10 @@ button.buttonHoverColor:hover a { #myshixun_top { - display: flex; - height: 54px; + display: flex; + position: fixed; + height: 54px; + z-index: 1 !important; } .headerLeft { flex: 0 0 400px; From 1fe5acad9991091b487b9fb4524cc683d944c194 Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Sat, 11 Jan 2020 16:48:59 +0800 Subject: [PATCH 113/156] =?UTF-8?q?=E8=AF=95=E5=8D=B7=E9=A2=98=E7=9A=84?= =?UTF-8?q?=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/courses_controller.rb | 2 +- .../exercise_answers_controller.rb | 144 ++++++++---------- 2 files changed, 66 insertions(+), 80 deletions(-) diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb index 753a3d942..b19ad96e8 100644 --- a/app/controllers/courses_controller.rb +++ b/app/controllers/courses_controller.rb @@ -182,7 +182,7 @@ class CoursesController < ApplicationController CreateSubjectCourseStudentJob.perform_later(@course.id) if @course.subject && @course.subject.subject_appointments.count > 0 rescue => e uid_logger_error(e.message) - tip_exception("调用失败") + tip_exception(e.message) raise ActiveRecord::Rollback end end diff --git a/app/controllers/exercise_answers_controller.rb b/app/controllers/exercise_answers_controller.rb index d74e14fe1..dfbe68cb5 100644 --- a/app/controllers/exercise_answers_controller.rb +++ b/app/controllers/exercise_answers_controller.rb @@ -2,94 +2,80 @@ class ExerciseAnswersController < ApplicationController before_action :require_login, :check_auth before_action :get_exercise_question include ExercisesHelper - - # model validation error - rescue_from ActiveRecord::RecordInvalid do |ex| - render_error(ex.record.errors.full_messages.join(',')) - end - # form validation error - rescue_from ActiveModel::ValidationError do |ex| - render_error(ex.model.errors.full_messages.join(',')) - end + include ControllerRescueHandler def create #每一次答案的点击,请求一次,实训题不在这里回答 - begin - q_type = @exercise_question.question_type #试卷的类型 - choice_id = params[:exercise_choice_id].present? ? params[:exercise_choice_id] : "" - answer_text = params[:answer_text].present? ? params[:answer_text].strip : "" #为字符串 - if q_type < Exercise::SUBJECTIVE && (q_type != Exercise::MULTIPLE) && choice_id.blank? - normal_status(-1,"请选择序号") - else - ea = @exercise_question.exercise_answers.search_answer_users("user_id",current_user.id) #试卷的当前用户的答案 - if q_type == Exercise::SINGLE || q_type == Exercise::JUDGMENT #选择题(单选)/判断题 - if ea.exists? - ea.first.update!(exercise_choice_id: choice_id ) - else - answer_option = { - :user_id => current_user.id, - :exercise_question_id => @exercise_question.id, - :exercise_choice_id => choice_id, - :answer_text => "" - } - ex_a = ExerciseAnswer.new(answer_option) - ex_a.save! - end - elsif q_type == Exercise::MULTIPLE #多选题的 - choice_ids = params[:exercise_choice_id].present? ? params[:exercise_choice_id] : [] - - ea_ids = ea.pluck(:exercise_choice_id) - common_answer_ids = choice_ids & ea_ids #已经存在的试卷选项id - new_ids = (choice_ids - common_answer_ids).uniq # 新增的id - old_ids = (ea_ids - common_answer_ids).uniq #没有选择的,则删掉 - if new_ids.size > 0 - new_ids.each do |e| - answer_option = { - :user_id => current_user.id, - :exercise_question_id => @exercise_question.id, - :exercise_choice_id => e, - :answer_text => "" - } - ex_a = ExerciseAnswer.new(answer_option) - ex_a.save! - end - end - if old_ids.size > 0 - ea_answer = ea.search_answer_users("exercise_choice_id",old_ids) - ea_answer.destroy_all - end - elsif q_type == Exercise::COMPLETION #填空题 - answer_option = { - :user_id => current_user.id, - :exercise_question_id => @exercise_question.id, - :exercise_choice_id => choice_id, - :answer_text => answer_text - } - ea_answer = ea.search_answer_users("exercise_choice_id",choice_id) - if ea.present? && ea_answer.present? - ea_answer.update!(answer_option) - else - ex_new = ExerciseAnswer.new(answer_option) - ex_new.save! - end - elsif q_type == Exercise::SUBJECTIVE #简答题 + q_type = @exercise_question.question_type #试卷的类型 + choice_id = params[:exercise_choice_id].present? ? params[:exercise_choice_id] : "" + answer_text = params[:answer_text].present? ? params[:answer_text].strip : "" #为字符串 + if q_type < Exercise::SUBJECTIVE && (q_type != Exercise::MULTIPLE) && choice_id.blank? + normal_status(-1,"请选择序号") + else + ea = @exercise_question.exercise_answers.search_answer_users("user_id",current_user.id) #试卷的当前用户的答案 + if q_type == Exercise::SINGLE || q_type == Exercise::JUDGMENT #选择题(单选)/判断题 + if ea.exists? + ea.first.update!(exercise_choice_id: choice_id ) + else answer_option = { - :user_id => current_user.id, - :exercise_question_id => @exercise_question.id + :user_id => current_user.id, + :exercise_question_id => @exercise_question.id, + :exercise_choice_id => choice_id, + :answer_text => "" } - if ea.present? #已经回答了的, - ea.first.update!(answer_text: answer_text) - else - answer_option.merge!(answer_text:answer_text) + ex_a = ExerciseAnswer.new(answer_option) + ex_a.save! + end + elsif q_type == Exercise::MULTIPLE #多选题的 + choice_ids = params[:exercise_choice_id].present? ? params[:exercise_choice_id] : [] + + ea_ids = ea.pluck(:exercise_choice_id) + common_answer_ids = choice_ids & ea_ids #已经存在的试卷选项id + new_ids = (choice_ids - common_answer_ids).uniq # 新增的id + old_ids = (ea_ids - common_answer_ids).uniq #没有选择的,则删掉 + if new_ids.size > 0 + new_ids.each do |e| + answer_option = { + :user_id => current_user.id, + :exercise_question_id => @exercise_question.id, + :exercise_choice_id => e, + :answer_text => "" + } ex_a = ExerciseAnswer.new(answer_option) ex_a.save! end end - normal_status(0,"回答成功") + if old_ids.size > 0 + ea_answer = ea.search_answer_users("exercise_choice_id",old_ids) + ea_answer.destroy_all + end + elsif q_type == Exercise::COMPLETION #填空题 + answer_option = { + :user_id => current_user.id, + :exercise_question_id => @exercise_question.id, + :exercise_choice_id => choice_id, + :answer_text => answer_text + } + ea_answer = ea.search_answer_users("exercise_choice_id",choice_id) + if ea.present? && ea_answer.present? + ea_answer.update!(answer_option) + else + ex_new = ExerciseAnswer.new(answer_option) + ex_new.save! + end + elsif q_type == Exercise::SUBJECTIVE #简答题 + answer_option = { + :user_id => current_user.id, + :exercise_question_id => @exercise_question.id + } + if ea.present? #已经回答了的, + ea.first.update!(answer_text: answer_text) + else + answer_option.merge!(answer_text:answer_text) + ex_a = ExerciseAnswer.new(answer_option) + ex_a.save! + end end - rescue Exception => e - uid_logger_error(e.message) - tip_exception("页面调用失败!") - raise ActiveRecord::Rollback + normal_status(0,"回答成功") end end From 4098b420d133fe40378f487249d57da689f2b5ed Mon Sep 17 00:00:00 2001 From: tangjiang <465264938@qq.com> Date: Sat, 11 Jan 2020 16:51:10 +0800 Subject: [PATCH 114/156] update diff --- public/react/src/common/educoder.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/public/react/src/common/educoder.js b/public/react/src/common/educoder.js index b8c735e24..ded33c43a 100644 --- a/public/react/src/common/educoder.js +++ b/public/react/src/common/educoder.js @@ -3,13 +3,9 @@ // export { default as OrderStateUtil } from '../routes/Order/components/OrderStateUtil'; export { getImageUrl as getImageUrl, getRandomNumber as getRandomNumber,getUrl as getUrl, publicSearchs as publicSearchs,getRandomcode as getRandomcode,getUrlmys as getUrlmys, getUrl2 as getUrl2, setImagesUrl as setImagesUrl -<<<<<<< HEAD , getUploadActionUrl as getUploadActionUrl,getUploadActionUrltwo as getUploadActionUrltwo ,getUploadActionUrlthree as getUploadActionUrlthree, getUploadActionUrlOfAuth as getUploadActionUrlOfAuth , getTaskUrlById as getTaskUrlById, TEST_HOST ,htmlEncode as htmlEncode ,getupload_git_file as getupload_git_file} from './UrlTool'; -======= - , getUploadActionUrl as getUploadActionUrl,getUploadActionUrltwo as getUploadActionUrltwo ,getUploadActionUrlthree as getUploadActionUrlthree, getUploadActionUrlOfAuth as getUploadActionUrlOfAuth - , getTaskUrlById as getTaskUrlById, TEST_HOST ,htmlEncode as htmlEncode ,getupload_git_file as getupload_git_file} from './UrlTool'; ->>>>>>> dev_aliyun + export {setmiyah as setmiyah} from './Component'; export { default as queryString } from './UrlTool2'; From a5601a2b2d0460fcb73cf29b9646e09092213a6a Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Sat, 11 Jan 2020 16:55:02 +0800 Subject: [PATCH 115/156] =?UTF-8?q?=E8=AF=95=E5=8D=B7=E9=A2=98=E7=9A=84?= =?UTF-8?q?=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/exercise_answers_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/exercise_answers_controller.rb b/app/controllers/exercise_answers_controller.rb index dfbe68cb5..3556ab8d3 100644 --- a/app/controllers/exercise_answers_controller.rb +++ b/app/controllers/exercise_answers_controller.rb @@ -57,7 +57,7 @@ class ExerciseAnswersController < ApplicationController } ea_answer = ea.search_answer_users("exercise_choice_id",choice_id) if ea.present? && ea_answer.present? - ea_answer.update!(answer_option) + ea_answer.first.update!(answer_option) else ex_new = ExerciseAnswer.new(answer_option) ex_new.save! From e26ef0f133c46fb6f4c84f67401645fff697f461 Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Sat, 11 Jan 2020 16:59:38 +0800 Subject: [PATCH 116/156] =?UTF-8?q?=E8=AF=95=E5=8D=B7=E9=A2=98=E7=9A=84?= =?UTF-8?q?=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/exercise_answers_controller.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/controllers/exercise_answers_controller.rb b/app/controllers/exercise_answers_controller.rb index 3556ab8d3..158628475 100644 --- a/app/controllers/exercise_answers_controller.rb +++ b/app/controllers/exercise_answers_controller.rb @@ -2,7 +2,6 @@ class ExerciseAnswersController < ApplicationController before_action :require_login, :check_auth before_action :get_exercise_question include ExercisesHelper - include ControllerRescueHandler def create #每一次答案的点击,请求一次,实训题不在这里回答 q_type = @exercise_question.question_type #试卷的类型 From d5e2446016bf55c4c2cb9a0781b52f29124c1299 Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Sat, 11 Jan 2020 17:10:39 +0800 Subject: [PATCH 117/156] =?UTF-8?q?=E8=AF=95=E5=8D=B7=E7=9A=84=E9=AA=8C?= =?UTF-8?q?=E8=AF=81=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/exercises_controller.rb | 3733 ++++++++++++++++------- 1 file changed, 2619 insertions(+), 1114 deletions(-) diff --git a/app/controllers/exercises_controller.rb b/app/controllers/exercises_controller.rb index ea4e38ab9..408f95945 100644 --- a/app/controllers/exercises_controller.rb +++ b/app/controllers/exercises_controller.rb @@ -1,26 +1,26 @@ class ExercisesController < ApplicationController before_action :require_login, :check_auth, except: [:index] - before_action :find_course,only: [:index,:new,:create,:my_exercises,:public_exercises,:set_public,:destroys, - :join_exercise_banks,:publish_modal,:publish,:end_modal,:end_exercise] #需要有课堂id参数的 - before_action :get_exercise,except: [:index,:new,:create,:my_exercises,:public_exercises,:set_public,:destroys, - :join_exercise_banks,:publish_modal,:publish,:end_modal,:end_exercise] + before_action :find_course, only: [:index, :new, :create, :my_exercises, :public_exercises, :set_public, :destroys, + :join_exercise_banks, :publish_modal, :publish, :end_modal, :end_exercise] #需要有课堂id参数的 + before_action :get_exercise, except: [:index, :new, :create, :my_exercises, :public_exercises, :set_public, :destroys, + :join_exercise_banks, :publish_modal, :publish, :end_modal, :end_exercise] before_action :user_course_identity - before_action :is_course_teacher,except: [:index,:start_answer,:exercise_setting,:commit_exercise,:exercise_lists,:review_exercise, - :exercise_result,:common_header,:cancel_exercise,:begin_commit] - before_action :get_left_banner_id,only:[:common_header,:start_answer,:review_exercise,:index,:new,:edit] - before_action :validates_exercise_params,only: [:create,:update] - before_action :get_exercise_question_counts,only: [:show,:edit,:start_answer,:review_exercise,:blank_exercise,:export_exercise] - before_action :validate_publish_time,only: [:commit_setting] #提交设置时,需判断时间是否符合 - before_action :check_course_public,only: [:set_public] - before_action :check_user_on_answer,only: [:show,:start_answer,:exercise_lists] #判断当前用户在试卷的权限/老师是否属于分班的权限 - before_action :only_student_in,only: [:start_answer] - before_action :check_user_id_start_answer,only: [:start_answer,:review_exercise] + before_action :is_course_teacher, except: [:index, :start_answer, :exercise_setting, :commit_exercise, :exercise_lists, :review_exercise, + :exercise_result, :common_header, :cancel_exercise, :begin_commit] + before_action :get_left_banner_id, only: [:common_header, :start_answer, :review_exercise, :index, :new, :edit] + before_action :validates_exercise_params, only: [:create, :update] + before_action :get_exercise_question_counts, only: [:show, :edit, :start_answer, :review_exercise, :blank_exercise, :export_exercise] + before_action :validate_publish_time, only: [:commit_setting] #提交设置时,需判断时间是否符合 + before_action :check_course_public, only: [:set_public] + before_action :check_user_on_answer, only: [:show, :start_answer, :exercise_lists] #判断当前用户在试卷的权限/老师是否属于分班的权限 + before_action :only_student_in, only: [:start_answer] + before_action :check_user_id_start_answer, only: [:start_answer, :review_exercise] # before_action :commit_user_exercise,only: [:start_answer,:exercise_lists,:review_exercise] #已有定时的任务 - before_action :check_exercise_time,only: [:commit_exercise] #提交试卷时,判断时间是否超过 - before_action :check_exercise_status,only: [:redo_modal,:redo_exercise] + before_action :check_exercise_time, only: [:commit_exercise] #提交试卷时,判断时间是否超过 + before_action :check_exercise_status, only: [:redo_modal, :redo_exercise] before_action :check_exercise_is_end, only: [:review_exercise] - before_action :check_exercise_public,only: [:exercise_result] #试卷是否为公开 - before_action :commit_shixun_present,only: [:commit_shixun] + before_action :check_exercise_public, only: [:exercise_result] #试卷是否为公开 + before_action :commit_shixun_present, only: [:commit_shixun] include ExportHelper include ExercisesHelper @@ -37,28 +37,28 @@ class ExercisesController < ApplicationController begin # 按发布时间或创建时间排序 @exercises_all = @course.exercises - member_show_exercises = @exercises_all.is_exercise_published #已发布的或已截止的试卷 + member_show_exercises = @exercises_all.is_exercise_published #已发布的或已截止的试卷 @current_user_ = current_user # 课堂的学生人数 @course_all_members = @course.students #当前课堂的全部学生 - @current_student = @course_all_members.course_find_by_ids("user_id",current_user.id) #当前用户是否为课堂的学生 + @current_student = @course_all_members.course_find_by_ids("user_id", current_user.id) #当前用户是否为课堂的学生 # exercises的不同用户群体的显示 - if @user_course_identity < Course::STUDENT # @is_teacher_or 1为老师/管理员/助教 + if @user_course_identity < Course::STUDENT # @is_teacher_or 1为老师/管理员/助教 @is_teacher_or = 1 - @exercises = @exercises_all #老师能看到全部的试卷,不管是已发布的/未发布的/已截止的/统一设置的/私有设置的(看到内容不同) - elsif @user_course_identity == Course::STUDENT # 2为课堂成员,能看到统一设置的和自己班级的 + @exercises = @exercises_all #老师能看到全部的试卷,不管是已发布的/未发布的/已截止的/统一设置的/私有设置的(看到内容不同) + elsif @user_course_identity == Course::STUDENT # 2为课堂成员,能看到统一设置的和自己班级的 @is_teacher_or = 2 - @member_group_id = @current_student.first.try(:course_group_id).to_i # 成员的分班id,默认为0 - if @member_group_id == 0 #表示是课堂的未分班成员,只能查看统一设置的试卷(已发布的/已截止的) + @member_group_id = @current_student.first.try(:course_group_id).to_i # 成员的分班id,默认为0 + if @member_group_id == 0 #表示是课堂的未分班成员,只能查看统一设置的试卷(已发布的/已截止的) @exercises = member_show_exercises.exists? ? member_show_exercises.unified_setting : [] - else #已分班级的成员,可以查看统一设置和单独设置(试卷是发布在该班级)试卷 + else #已分班级的成员,可以查看统一设置和单独设置(试卷是发布在该班级)试卷 # 已发布 当前用户班级分组的 试卷id publish_exercise_ids = @course.exercise_group_settings.exercise_group_published.where("course_group_id = #{@member_group_id}").pluck(:exercise_id) @exercises = member_show_exercises.unified_setting.or(member_show_exercises.where(id: publish_exercise_ids)) end - else #用户未登陆或不是该课堂成员,仅显示统一设置的(已发布的/已截止的),如有公开,则不显示锁,不公开,则显示锁 + else #用户未登陆或不是该课堂成员,仅显示统一设置的(已发布的/已截止的),如有公开,则不显示锁,不公开,则显示锁 @is_teacher_or = 0 @exercises = member_show_exercises.unified_setting end @@ -75,7 +75,7 @@ class ExercisesController < ApplicationController ex_setting_ids = @course.exercise_group_settings.where("course_group_id = #{@member_group_id}").exercise_group_not_published.pluck(:exercise_id) when 2 ex_setting_ids = @course.exercise_group_settings.where("course_group_id = #{@member_group_id}") - .where("publish_time is not null and publish_time <= ? and end_time > ?",Time.now,Time.now).pluck(:exercise_id) + .where("publish_time is not null and publish_time <= ? and end_time > ?", Time.now, Time.now).pluck(:exercise_id) when 3 ex_setting_ids = @course.exercise_group_settings.where("course_group_id = #{@member_group_id}").exercise_group_ended.pluck(:exercise_id) end @@ -90,11 +90,11 @@ class ExercisesController < ApplicationController @exercises = @exercises.exercise_search(search_type) end - @exercises_select_count = @exercises.size # 全部页面,需返回 - @exercises = @exercises.distinct.order( "IF(ISNULL(publish_time),0,1), publish_time DESC,created_at DESC") #出现错误 + @exercises_select_count = @exercises.size # 全部页面,需返回 + @exercises = @exercises.distinct.order("IF(ISNULL(publish_time),0,1), publish_time DESC,created_at DESC") #出现错误 # 分页 - @page = params[:page] || 1 + @page = params[:page] || 1 @limit = params[:limit] || 15 @exercises = @exercises.page(@page).per(@limit) @exercises = @exercises&.includes(:published_settings) @@ -102,10 +102,10 @@ class ExercisesController < ApplicationController @exercises = [] end - @course_all_members_count = @course_all_members.size #当前课堂的学生数 - @exercises_count = @exercises_all.size # 全部页面,需返回 + @course_all_members_count = @course_all_members.size #当前课堂的学生数 + @exercises_count = @exercises_all.size # 全部页面,需返回 @exercises_unpublish_counts = @exercises_all.exercise_by_status(1).size #未发布的试卷数 - @exercises_published_counts = @exercises_count - @exercises_unpublish_counts # 已发布的试卷数,包含已截止的 + @exercises_published_counts = @exercises_count - @exercises_unpublish_counts # 已发布的试卷数,包含已截止的 rescue Exception => e uid_logger_error(e.message) @@ -128,108 +128,77 @@ class ExercisesController < ApplicationController def create ActiveRecord::Base.transaction do - begin - ex_name = params[:exercise_name] - ex_desc = params[:exercise_description] - exercise_options = { - :exercise_name => ex_name, - :exercise_description => ex_desc, - :user_id => current_user.id, - :course_id => @course.id, - :time => -1, - :exercise_status => 1 - } - @exercise = Exercise.create!(exercise_options) - rescue Exception => e - uid_logger_error(e.message) - tip_exception("试卷创建失败!") - raise ActiveRecord::Rollback - end + ex_name = params[:exercise_name] + ex_desc = params[:exercise_description] + exercise_options = { + :exercise_name => ex_name, + :exercise_description => ex_desc, + :user_id => current_user.id, + :course_id => @course.id, + :time => -1, + :exercise_status => 1 + } + @exercise = Exercise.create!(exercise_options) end end #试卷的内容,及试题/答案的内容编辑 def edit ActiveRecord::Base.transaction do - begin - @exercise_questions = @exercise.exercise_questions.order("question_number ASC") - rescue Exception => e - uid_logger_error(e.message) - tip_exception("试卷创建失败!") - raise ActiveRecord::Rollback - end + @exercise_questions = @exercise.exercise_questions.order("question_number ASC") end end def update ActiveRecord::Base.transaction do - begin - ex_name = params[:exercise_name] - ex_desc = params[:exercise_description] - exercise_options = { - :exercise_name => ex_name, - :exercise_description => ex_desc, - } - @exercise.update!(exercise_options) - normal_status(0,"试卷更新成功!") - rescue Exception => e - uid_logger_error(e.message) - tip_exception("试卷创建失败!") - raise ActiveRecord::Rollback - end + ex_name = params[:exercise_name] + ex_desc = params[:exercise_description] + exercise_options = { + :exercise_name => ex_name, + :exercise_description => ex_desc, + } + @exercise.update!(exercise_options) + normal_status(0, "试卷更新成功!") end end def show ActiveRecord::Base.transaction do - begin - if @user_course_identity < Course::STUDENT - @is_teacher_or = 1 #为老师/助教/管理员 - else - @is_teacher_or = 0 #为学生 - end - @exercise_questions = @exercise.exercise_questions&.includes(:exercise_choices,:exercise_shixun_challenges,:exercise_standard_answers).order("question_number ASC") - rescue Exception => e - uid_logger_error(e.message) - tip_exception("试卷创建失败!") - raise ActiveRecord::Rollback + if @user_course_identity < Course::STUDENT + @is_teacher_or = 1 #为老师/助教/管理员 + else + @is_teacher_or = 0 #为学生 end + @exercise_questions = @exercise.exercise_questions&.includes(:exercise_choices, :exercise_shixun_challenges, :exercise_standard_answers).order("question_number ASC") end end #试卷的公用头部 def common_header ActiveRecord::Base.transaction do - begin - @user_left_time = nil - if @user_course_identity > Course::ASSISTANT_PROFESSOR - @is_teacher_or = 0 - @user_exercise_answer = @exercise.check_user_answer_status(current_user) - @user_commit_counts = 0 - @user_left_time = get_exercise_left_time(@exercise,current_user) - else - @is_teacher_or = 1 - @user_exercise_answer = 3 #教师页面 - @user_commit_counts = @exercise.exercise_users.where(commit_status:1).size #已提交的用户数 - end - @ex_status = @exercise.get_exercise_status(current_user) + @user_left_time = nil + if @user_course_identity > Course::ASSISTANT_PROFESSOR + @is_teacher_or = 0 + @user_exercise_answer = @exercise.check_user_answer_status(current_user) + @user_commit_counts = 0 + @user_left_time = get_exercise_left_time(@exercise, current_user) + else + @is_teacher_or = 1 + @user_exercise_answer = 3 #教师页面 + @user_commit_counts = @exercise.exercise_users.where(commit_status: 1).size #已提交的用户数 + end + @ex_status = @exercise.get_exercise_status(current_user) - exercise_id_array = [@exercise.id] - @exercise_publish_count = get_user_permission_course(exercise_id_array,Exercise::PUBLISHED).size #是否存在已发布的 - @exercise_unpublish_count = get_user_permission_course(exercise_id_array,Exercise::UNPUBLISHED).size #是否存在未发布的 + exercise_id_array = [@exercise.id] + @exercise_publish_count = get_user_permission_course(exercise_id_array, Exercise::PUBLISHED).size #是否存在已发布的 + @exercise_unpublish_count = get_user_permission_course(exercise_id_array, Exercise::UNPUBLISHED).size #是否存在未发布的 - if (@exercise_publish_count == 0) && (@exercise_unpublish_count == 0) #即表示没有分班 - if @ex_status == Exercise::UNPUBLISHED - @exercise_unpublish_count = 1 #试卷未发布,且课堂没有分班的时候 - elsif @ex_status == Exercise::PUBLISHED - @exercise_publish_count = 1 #试卷未发布,且课堂没有分班的时候 - end + if (@exercise_publish_count == 0) && (@exercise_unpublish_count == 0) #即表示没有分班 + if @ex_status == Exercise::UNPUBLISHED + @exercise_unpublish_count = 1 #试卷未发布,且课堂没有分班的时候 + elsif @ex_status == Exercise::PUBLISHED + @exercise_publish_count = 1 #试卷未发布,且课堂没有分班的时候 end - - rescue Exception => e - uid_logger_error(e.message) - tip_exception("没有权限") - raise ActiveRecord::Rollback end end end @@ -237,381 +206,338 @@ class ExercisesController < ApplicationController #实训题目的选用 def choose_shixun ActiveRecord::Base.transaction do - begin - search = params[:search] - if @user_course_identity > Course::ADMIN #当不为管理员的时候 - user_school_id = current_user.school_id #当前用户的学校id - if user_school_id.present? - none_shixun_ids = ShixunSchool.where("school_id != #{user_school_id}").pluck(:shixun_id) - @publish_shixuns = Shixun.where.not(id: none_shixun_ids).unhidden - end - else - @publish_shixuns = Shixun.unhidden - end - if search.present? - @publish_shixuns = @publish_shixuns.search_by_name(search) + search = params[:search] + if @user_course_identity > Course::ADMIN #当不为管理员的时候 + user_school_id = current_user.school_id #当前用户的学校id + if user_school_id.present? + none_shixun_ids = ShixunSchool.where("school_id != #{user_school_id}").pluck(:shixun_id) + @publish_shixuns = Shixun.where.not(id: none_shixun_ids).unhidden end + else + @publish_shixuns = Shixun.unhidden + end + if search.present? + @publish_shixuns = @publish_shixuns.search_by_name(search) + end - @shixuns = @publish_shixuns.joins(:challenges).where("challenges.st != 0").distinct - # 全部页面,需返回 - @shixuns_count = @shixuns.count + @shixuns = @publish_shixuns.joins(:challenges).where("challenges.st != 0").distinct + # 全部页面,需返回 + @shixuns_count = @shixuns.count - # 分页 - @page = params[:page] || 1 - @limit = params[:limit] || 8 + # 分页 + @page = params[:page] || 1 + @limit = params[:limit] || 8 - @shixuns = @shixuns.page(@page).per(@limit) - rescue Exception => e - uid_logger_error(e.message) - tip_exception("实训选择失败!") - end + @shixuns = @shixuns.page(@page).per(@limit) end end #确认实训的选择 def commit_shixun ActiveRecord::Base.transaction do - begin - @shixun_challenges = @shixun.challenges - @shixun_challenges_count = @shixun_challenges.size - rescue Exception => e - uid_logger_error(e.message) - tip_exception("页面调用失败!") - raise ActiveRecord::Rollback - end + @shixun_challenges = @shixun.challenges + @shixun_challenges_count = @shixun_challenges.size end end # 首页批量或单独删除 def destroys ActiveRecord::Base.transaction do - begin - check_ids = Exercise.where(id: params[:check_ids]) - check_ids.destroy_all - normal_status(0, "试卷已删除成功!") - rescue Exception => e - uid_logger_error(e.message) - tip_exception("试卷删除失败!") - raise ActiveRecord::Rollback - end + check_ids = Exercise.where(id: params[:check_ids]) + check_ids.destroy_all + normal_status(0, "试卷已删除成功!") end end # 设为公开 def set_public ActiveRecord::Base.transaction do - begin - check_ids = Exercise.where(id: params[:check_ids]) - check_ids.each do |exercise| - exercise.update!(is_public: true) - end - normal_status(0, "试卷已设为公开!") - rescue Exception => e - uid_logger_error(e.message) - tip_exception("试卷设为公开失败!") - raise ActiveRecord::Rollback + check_ids = Exercise.where(id: params[:check_ids]) + check_ids.each do |exercise| + exercise.update!(is_public: true) end + normal_status(0, "试卷已设为公开!") end end ## 加入题库 def join_exercise_banks ActiveRecord::Base.transaction do - begin - check_ids = Exercise.where(id: params[:check_ids]) - check_ids.each do |exercise| - current_ex_bank = current_user.exercise_banks.find_by_container(exercise.id,"Exercise")&.first - if current_ex_bank.present? #当前用户的选择试卷是否已加入习题库,存在则更新习题库和问题库,否则新建习题库和问题库 - ex_params = { - :name => exercise.exercise_name, - :description => exercise.exercise_description, - :course_list_id => exercise.course.try(:course_list_id) - } - current_ex_bank.update!(ex_params) - # question_bank = QuestionBank.ques_by_container(current_ex_bank.id,current_ex_bank.container_type).first #该习题库是否存在于问题库里 - # ques_params = { - # :name => current_ex_bank.name, - # :course_list_id => current_ex_bank.course_list_id - # } - # question_bank.update_attributes(ques_params) if question_bank.present? - current_ex_bank.exercise_bank_questions.destroy_all # 更新后,习题库的问题全部删除,后续重新再建 - else - ex_params = { - :name => exercise.exercise_name, - :description => exercise.exercise_description, - :user_id => current_user.id, - :is_public => 0, - :course_list_id => exercise.course.try(:course_list_id), - :container_id => exercise.id, - :container_type => "Exercise", - :quotes => 1 - } - current_ex_bank= ExerciseBank.new ex_params - current_ex_bank.save! #如果习题库保存成功,则会创建问题库question_bank - # if current_ex_bank.save - # ques_params = { - # :name => current_ex_bank.name, - # :container_id => current_ex_bank.id, - # :container_type => current_ex_bank.container_type, - # :quotes => current_ex_bank.quotes, - # :user_id => current_ex_bank.user_id, - # :is_public => current_ex_bank.is_public, - # :course_list_id => current_ex_bank.course_list_id - # } - # question_bank = QuestionBank.new ques_params - # question_bank.save - # end - exercise.update!(exercise_bank_id: current_ex_bank.id) - end - # 试卷的问题的输入 - exercise.exercise_questions.each do |q| - option = { - :question_title => q.question_title, - :question_type => q.question_type, - :question_number => q.question_number, - :question_score => q.question_score, + check_ids = Exercise.where(id: params[:check_ids]) + check_ids.each do |exercise| + current_ex_bank = current_user.exercise_banks.find_by_container(exercise.id, "Exercise")&.first + if current_ex_bank.present? #当前用户的选择试卷是否已加入习题库,存在则更新习题库和问题库,否则新建习题库和问题库 + ex_params = { + :name => exercise.exercise_name, + :description => exercise.exercise_description, + :course_list_id => exercise.course.try(:course_list_id) + } + current_ex_bank.update!(ex_params) + # question_bank = QuestionBank.ques_by_container(current_ex_bank.id,current_ex_bank.container_type).first #该习题库是否存在于问题库里 + # ques_params = { + # :name => current_ex_bank.name, + # :course_list_id => current_ex_bank.course_list_id + # } + # question_bank.update_attributes(ques_params) if question_bank.present? + current_ex_bank.exercise_bank_questions.destroy_all # 更新后,习题库的问题全部删除,后续重新再建 + else + ex_params = { + :name => exercise.exercise_name, + :description => exercise.exercise_description, + :user_id => current_user.id, + :is_public => 0, + :course_list_id => exercise.course.try(:course_list_id), + :container_id => exercise.id, + :container_type => "Exercise", + :quotes => 1 + } + current_ex_bank = ExerciseBank.new ex_params + current_ex_bank.save! #如果习题库保存成功,则会创建问题库question_bank + # if current_ex_bank.save + # ques_params = { + # :name => current_ex_bank.name, + # :container_id => current_ex_bank.id, + # :container_type => current_ex_bank.container_type, + # :quotes => current_ex_bank.quotes, + # :user_id => current_ex_bank.user_id, + # :is_public => current_ex_bank.is_public, + # :course_list_id => current_ex_bank.course_list_id + # } + # question_bank = QuestionBank.new ques_params + # question_bank.save + # end + exercise.update!(exercise_bank_id: current_ex_bank.id) + end + # 试卷的问题的输入 + exercise.exercise_questions.each do |q| + option = { + :question_title => q.question_title, + :question_type => q.question_type, + :question_number => q.question_number, + :question_score => q.question_score, + :shixun_id => q.shixun_id, + :shixun_name => q.shixun_name + } + exercise_bank_question = current_ex_bank.exercise_bank_questions.new option + exercise_bank_question.save! + ## 试卷选项的输入 + if q.question_type != Exercise::PRACTICAL #不为实训题时,试卷选项加入试题答案库 + ex_choices = q.exercise_choices + ex_standard = q.exercise_standard_answers + ex_choices.each do |c| + choice_option = { + :choice_position => c.choice_position, + :choice_text => c.choice_text + } + ex_bank_choice = exercise_bank_question.exercise_bank_choices.new choice_option + ex_bank_choice.save! + end + ex_standard.each do |s| + ex_stand = { + :exercise_bank_choice_id => s.exercise_choice_id, + :answer_text => s.answer_text + } + ex_stand_bank = exercise_bank_question.exercise_bank_standard_answers.new ex_stand + ex_stand_bank.save! + end + else #当为实训题时 + shixun_challenges = q.exercise_shixun_challenges + shixun_challenges.each do |c| + challenge_option = { + :position => c.position, + :challenge_id => c.challenge_id, :shixun_id => q.shixun_id, - :shixun_name => q.shixun_name - } - exercise_bank_question = current_ex_bank.exercise_bank_questions.new option - exercise_bank_question.save! - ## 试卷选项的输入 - if q.question_type != Exercise::PRACTICAL #不为实训题时,试卷选项加入试题答案库 - ex_choices = q.exercise_choices - ex_standard = q.exercise_standard_answers - ex_choices.each do |c| - choice_option = { - :choice_position => c.choice_position, - :choice_text =>c.choice_text - } - ex_bank_choice = exercise_bank_question.exercise_bank_choices.new choice_option - ex_bank_choice.save! - end - ex_standard.each do |s| - ex_stand = { - :exercise_bank_choice_id => s.exercise_choice_id, - :answer_text => s.answer_text - } - ex_stand_bank = exercise_bank_question.exercise_bank_standard_answers.new ex_stand - ex_stand_bank.save! - end - else #当为实训题时 - shixun_challenges = q.exercise_shixun_challenges - shixun_challenges.each do |c| - challenge_option = { - :position => c.position, - :challenge_id => c.challenge_id, - :shixun_id => q.shixun_id, - :question_score => c.question_score - } - shixun_challenge_bank = exercise_bank_question.exercise_bank_shixun_challenges.new challenge_option - shixun_challenge_bank.save! - end + :question_score => c.question_score + } + shixun_challenge_bank = exercise_bank_question.exercise_bank_shixun_challenges.new challenge_option + shixun_challenge_bank.save! end end - current_ex_bank.save! end - normal_status(0, "题库更新成功!") - rescue Exception => e - uid_logger_error(e.message) - tip_exception("题库更新失败!") - raise ActiveRecord::Rollback + current_ex_bank.save! end + normal_status(0, "题库更新成功!") end end #试卷的设置页面 def exercise_setting ActiveRecord::Base.transaction do - begin - @user_permission = 2 - @user_course_groups = @course.teacher_group(current_user.id) #当前老师的分班 - @being_setting_course_ids = @exercise.common_published_ids(current_user.id) #当前用户已发布的班级的id - @user_published_setting = @exercise.exercise_group_settings - .find_in_exercise_group("course_group_id",@being_setting_course_ids) #当前用户已发布班级的试卷设置 - exercise_ids = [@exercise.id] - @exercise_publish_count = get_user_permission_course(exercise_ids,Exercise::PUBLISHED).count #判断当前用户是否有试卷已发布的分班,用于显示立即截止/撤销发布 - @exercise_unpublish_count = get_user_permission_course(exercise_ids,Exercise::UNPUBLISHED).count #判断当前用户是否有试卷未发布的分班,用户显示立即发布 - @exercise_users_count = @exercise.exercise_users.commit_exercise_by_status(1).count #判断当前试卷是否有已提交的 - # ## 需添加发送消息的接口,稍后添加 - rescue Exception => e - uid_logger_error(e.message) - tip_exception("页面调用失败!") - raise ActiveRecord::Rollback - end + @user_permission = 2 + @user_course_groups = @course.teacher_group(current_user.id) #当前老师的分班 + @being_setting_course_ids = @exercise.common_published_ids(current_user.id) #当前用户已发布的班级的id + @user_published_setting = @exercise.exercise_group_settings + .find_in_exercise_group("course_group_id", @being_setting_course_ids) #当前用户已发布班级的试卷设置 + exercise_ids = [@exercise.id] + @exercise_publish_count = get_user_permission_course(exercise_ids, Exercise::PUBLISHED).count #判断当前用户是否有试卷已发布的分班,用于显示立即截止/撤销发布 + @exercise_unpublish_count = get_user_permission_course(exercise_ids, Exercise::UNPUBLISHED).count #判断当前用户是否有试卷未发布的分班,用户显示立即发布 + @exercise_users_count = @exercise.exercise_users.commit_exercise_by_status(1).count #判断当前试卷是否有已提交的 + # ## 需添加发送消息的接口,稍后添加 end end #试卷的提交设置 def commit_setting ActiveRecord::Base.transaction do - begin - error_count = 0 # 判断循环里是否有已发布/已截止的,且时间更改了的分班。 - # course_group_ids = @course.teacher_course_group_ids(current_user.id) #当前老师的班级id数组 - course_group_ids = @course.charge_group_ids(current_user) #当前老师的班级id数组 + error_count = 0 # 判断循环里是否有已发布/已截止的,且时间更改了的分班。 + # course_group_ids = @course.teacher_course_group_ids(current_user.id) #当前老师的班级id数组 + course_group_ids = @course.charge_group_ids(current_user) #当前老师的班级id数组 - exercise_status = @exercise.get_exercise_status(current_user) + exercise_status = @exercise.get_exercise_status(current_user) - if exercise_status == Exercise::UNPUBLISHED && course_group_ids.size > 0 # 试卷未发布,且老师的分班大于1 ,才可以修改统一设置,否则按试卷默认的来处理 - unified_setting = params[:unified_setting] + if exercise_status == Exercise::UNPUBLISHED && course_group_ids.size > 0 # 试卷未发布,且老师的分班大于1 ,才可以修改统一设置,否则按试卷默认的来处理 + unified_setting = params[:unified_setting] + else + unified_setting = @exercise.unified_setting + end + + show_statistic = params[:show_statistic] ? true : false + exercise_time = params[:time].blank? ? -1 : params[:time] + question_random = params[:question_random] ? true : false #问题是否随机,0为不随机,1为随机 + choice_random = params[:choice_random] ? true : false + score_open = params[:score_open] ? true : false #分数是否公开 + answer_open = params[:answer_open] ? true : false #答案是否公开 + + # 统一设置或者分班为0,则更新试卷,并删除试卷分组 + if unified_setting || (course_group_ids.size == 0) + tip_exception("发布时间不能为空") if params[:publish_time].blank? + tip_exception("截止时间不能为空") if params[:end_time].blank? + tip_exception("截止时间不能早于发布时间") if params[:publish_time].to_time > params[:end_time].to_time + tip_exception("截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")})") if @course.end_date.present? && params[:end_time].to_time > @course.end_date.end_of_day + + params_publish_time = params[:publish_time].to_time + params_end_time = params[:end_time].to_time + + if (exercise_status != Exercise::UNPUBLISHED) && (@exercise.publish_time != params_publish_time) + normal_status(-1, "已发布/已截止,不允许修改发布时间") + elsif params_publish_time.present? && params_end_time.present? && params_end_time < params_publish_time + normal_status(-1, "截止时间不能小于发布时间") else - unified_setting = @exercise.unified_setting - end - - show_statistic = params[:show_statistic] ? true :false - exercise_time = params[:time].blank? ? -1 : params[:time] - question_random = params[:question_random] ? true :false #问题是否随机,0为不随机,1为随机 - choice_random = params[:choice_random] ? true :false - score_open = params[:score_open] ? true : false #分数是否公开 - answer_open = params[:answer_open] ? true : false #答案是否公开 - - # 统一设置或者分班为0,则更新试卷,并删除试卷分组 - if unified_setting || (course_group_ids.size == 0) - tip_exception("发布时间不能为空") if params[:publish_time].blank? - tip_exception("截止时间不能为空") if params[:end_time].blank? - tip_exception("截止时间不能早于发布时间") if params[:publish_time].to_time > params[:end_time].to_time - tip_exception("截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")})") if - @course.end_date.present? && params[:end_time].to_time > @course.end_date.end_of_day - - params_publish_time = params[:publish_time].to_time - params_end_time = params[:end_time].to_time - - if (exercise_status != Exercise::UNPUBLISHED) && (@exercise.publish_time != params_publish_time) - normal_status(-1,"已发布/已截止,不允许修改发布时间") - elsif params_publish_time.present? && params_end_time.present? && params_end_time < params_publish_time - normal_status(-1,"截止时间不能小于发布时间") - else - #发布时间小于当前时间,则试卷显示为未发布,当截止时间大于当前时间,则显示为已截止 - exercise_status_n = set_exercise_status(params_publish_time,params_end_time) - exercise_params = { - :unified_setting => unified_setting, - :show_statistic => show_statistic, - :time => exercise_time, - :question_random => question_random, - :choice_random => choice_random, - :score_open => score_open, - :answer_open => answer_open, - :exercise_status => exercise_status_n, - :publish_time => params_publish_time, - :end_time => params_end_time - } - @exercise.update!(exercise_params) - @exercise.exercise_group_settings.destroy_all - normal_status(0, "试卷设置成功!") + #发布时间小于当前时间,则试卷显示为未发布,当截止时间大于当前时间,则显示为已截止 + exercise_status_n = set_exercise_status(params_publish_time, params_end_time) + exercise_params = { + :unified_setting => unified_setting, + :show_statistic => show_statistic, + :time => exercise_time, + :question_random => question_random, + :choice_random => choice_random, + :score_open => score_open, + :answer_open => answer_open, + :exercise_status => exercise_status_n, + :publish_time => params_publish_time, + :end_time => params_end_time + } + @exercise.update!(exercise_params) + @exercise.exercise_group_settings.destroy_all + normal_status(0, "试卷设置成功!") + end + else + params_times = params[:publish_time_groups] #分班返回的json数组{"publish_time_groups":[{"course_group_id":"1","publish_time":"xx","end_time":"xxx"}]} + exercise_groups = @exercise.exercise_group_settings.find_in_exercise_group("course_id", @course.id) #试卷的全部分班信息 + exercise_groups_ids = exercise_groups.pluck(:course_group_id) #问卷的全部分班id + total_common = params_times.map {|k| k[:course_group_id]}.sum.uniq #传入的所有分组的分班id + total_common_group = exercise_groups_ids & total_common #传入的分班与问卷已存在的分班的交集 + old_exercise_groups = exercise_groups_ids - total_common_group #后来传入的分班里,没有了的班级,即需要删除 + + params_times.each do |t| + tip_exception("发布时间不能为空") if t[:publish_time].blank? + tip_exception("截止时间不能为空") if t[:end_time].blank? + tip_exception("截止时间不能早于发布时间") if t[:publish_time].to_time > t[:end_time].to_time + tip_exception("截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")})") if @course.end_date.present? && t[:end_time].to_time > @course.end_date.end_of_day + + course_id = t[:course_group_id] + exercise_publish_time = t[:publish_time].to_time + exercise_end_time = t[:end_time].to_time + + exercise_group = exercise_groups.find_in_exercise_group("course_group_id", course_id) #判断该分班是否存在 + if exercise_group.present? && (exercise_group.first.publish_time < Time.now) && (exercise_publish_time != exercise_group.first.publish_time) + error_count += 1 end - else - params_times = params[:publish_time_groups] #分班返回的json数组{"publish_time_groups":[{"course_group_id":"1","publish_time":"xx","end_time":"xxx"}]} - exercise_groups = @exercise.exercise_group_settings.find_in_exercise_group("course_id",@course.id) #试卷的全部分班信息 - exercise_groups_ids = exercise_groups.pluck(:course_group_id) #问卷的全部分班id - total_common = params_times.map{|k| k[:course_group_id]}.sum.uniq #传入的所有分组的分班id - total_common_group = exercise_groups_ids & total_common #传入的分班与问卷已存在的分班的交集 - old_exercise_groups = exercise_groups_ids - total_common_group #后来传入的分班里,没有了的班级,即需要删除 - - params_times.each do |t| - tip_exception("发布时间不能为空") if t[:publish_time].blank? - tip_exception("截止时间不能为空") if t[:end_time].blank? - tip_exception("截止时间不能早于发布时间") if t[:publish_time].to_time > t[:end_time].to_time - tip_exception("截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")})") if - @course.end_date.present? && t[:end_time].to_time > @course.end_date.end_of_day - - course_id = t[:course_group_id] - exercise_publish_time = t[:publish_time].to_time - exercise_end_time = t[:end_time].to_time - - exercise_group = exercise_groups.find_in_exercise_group("course_group_id",course_id) #判断该分班是否存在 - if exercise_group.present? && (exercise_group.first.publish_time < Time.now) && (exercise_publish_time != exercise_group.first.publish_time) - error_count += 1 - end - if exercise_group.present? && (exercise_group.first.publish_time < Time.now && exercise_group.first.end_time > Time.now) && (exercise_end_time < Time.now) - error_count += 1 - end - if error_count == 0 - common_group = exercise_groups_ids & course_id #传入的班级与问卷已存在的班级的交集,即表示已有分班的 - new_group_ids = course_id - common_group #新传入的班级id - if common_group.count > 0 #判断试卷的分班设置是否存在,存在则更新,负责则新建 - exercise_group_sets = exercise_groups.find_in_exercise_group("course_group_id",common_group) - exercise_group_sets.each do |the_group_setting| + if exercise_group.present? && (exercise_group.first.publish_time < Time.now && exercise_group.first.end_time > Time.now) && (exercise_end_time < Time.now) + error_count += 1 + end + if error_count == 0 + common_group = exercise_groups_ids & course_id #传入的班级与问卷已存在的班级的交集,即表示已有分班的 + new_group_ids = course_id - common_group #新传入的班级id + if common_group.count > 0 #判断试卷的分班设置是否存在,存在则更新,负责则新建 + exercise_group_sets = exercise_groups.find_in_exercise_group("course_group_id", common_group) + exercise_group_sets.each do |the_group_setting| + ex_group_params = { + :publish_time => exercise_publish_time, + :end_time => exercise_end_time + } + + the_group_setting_status = set_exercise_status(the_group_setting.publish_time, the_group_setting.end_time) + if the_group_setting_status == 2 + ex_group_params = { + :publish_time => the_group_setting.publish_time, + :end_time => exercise_end_time < Time.now ? the_group_setting.end_time : exercise_end_time + } + elsif the_group_setting_status == 3 ex_group_params = { - :publish_time => exercise_publish_time, + :publish_time => the_group_setting.publish_time, :end_time => exercise_end_time } - - the_group_setting_status = set_exercise_status(the_group_setting.publish_time,the_group_setting.end_time) - if the_group_setting_status == 2 - ex_group_params = { - :publish_time => the_group_setting.publish_time, - :end_time => exercise_end_time < Time.now ? the_group_setting.end_time : exercise_end_time - } - elsif the_group_setting_status == 3 - ex_group_params = { - :publish_time => the_group_setting.publish_time, - :end_time => exercise_end_time - } - end - the_group_setting.update!(ex_group_params) end + the_group_setting.update!(ex_group_params) end - if new_group_ids.size > 0 - new_group_ids.each do |c| - exercise_group_params = { - :exercise_id => @exercise.id, - :course_group_id => c, - :course_id => @course.id, - :publish_time => exercise_publish_time, - :end_time => exercise_end_time - } - new_exercise_group = ExerciseGroupSetting.new(exercise_group_params) - new_exercise_group.save! - end + end + if new_group_ids.size > 0 + new_group_ids.each do |c| + exercise_group_params = { + :exercise_id => @exercise.id, + :course_group_id => c, + :course_id => @course.id, + :publish_time => exercise_publish_time, + :end_time => exercise_end_time + } + new_exercise_group = ExerciseGroupSetting.new(exercise_group_params) + new_exercise_group.save! end end end + end - if error_count > 0 - error_count == 0 - normal_status(-1,"试卷发布/截止时间不能小于当前时间") - else - # 未发布的分班设置才能删除 - if old_exercise_groups.size > 0 - old_all_ex_groups = exercise_groups.find_in_exercise_group("course_group_id",old_exercise_groups).exercise_group_not_published - old_all_ex_groups.destroy_all - end - #试卷更新为exercise_group_setting的发布时间最小,截止时间最大 - e_time_present = exercise_groups.end_time_no_null.map(&:end_time) - p_time_present = exercise_groups.publish_time_no_null.map(&:publish_time) - e_time = e_time_present.size > 0 ? e_time_present.max : nil - p_time = p_time_present.size > 0 ? p_time_present.min : nil + if error_count > 0 + error_count == 0 + normal_status(-1, "试卷发布/截止时间不能小于当前时间") + else + # 未发布的分班设置才能删除 + if old_exercise_groups.size > 0 + old_all_ex_groups = exercise_groups.find_in_exercise_group("course_group_id", old_exercise_groups).exercise_group_not_published + old_all_ex_groups.destroy_all + end + #试卷更新为exercise_group_setting的发布时间最小,截止时间最大 + e_time_present = exercise_groups.end_time_no_null.map(&:end_time) + p_time_present = exercise_groups.publish_time_no_null.map(&:publish_time) + e_time = e_time_present.size > 0 ? e_time_present.max : nil + p_time = p_time_present.size > 0 ? p_time_present.min : nil + exercise_status = 1 + if p_time.nil? #发布时间为空,则表示问卷未发布 exercise_status = 1 - if p_time.nil? #发布时间为空,则表示问卷未发布 - exercise_status = 1 - elsif p_time.present? && e_time.present? - exercise_status = set_exercise_status(p_time,e_time) - end - exercise_params = { - :unified_setting => unified_setting, - :show_statistic => show_statistic, - :time => exercise_time, - :question_random => question_random, - :choice_random => choice_random, - :score_open => score_open, - :answer_open => answer_open, - :exercise_status => exercise_status, - :publish_time => p_time, - :end_time => e_time - } - @exercise.update!(exercise_params) - if @exercise.exercise_status == Exercise::PUBLISHED - if @exercise.course_acts.size == 0 - @exercise.course_acts << CourseActivity.new(:user_id => @exercise.user_id,:course_id => @exercise.course_id) - end + elsif p_time.present? && e_time.present? + exercise_status = set_exercise_status(p_time, e_time) + end + exercise_params = { + :unified_setting => unified_setting, + :show_statistic => show_statistic, + :time => exercise_time, + :question_random => question_random, + :choice_random => choice_random, + :score_open => score_open, + :answer_open => answer_open, + :exercise_status => exercise_status, + :publish_time => p_time, + :end_time => e_time + } + @exercise.update!(exercise_params) + if @exercise.exercise_status == Exercise::PUBLISHED + if @exercise.course_acts.size == 0 + @exercise.course_acts << CourseActivity.new(:user_id => @exercise.user_id, :course_id => @exercise.course_id) end - normal_status(0, "试卷设置成功!") end + normal_status(0, "试卷设置成功!") end - rescue Exception => e - uid_logger_error(e.message) - tip_exception(e.message) - raise ActiveRecord::Rollback end end end @@ -641,7 +567,7 @@ class ExercisesController < ApplicationController exercise_user.update!(score: score, subjective_score: subjective_score, objective_score: objective_score) else exercise_user.update!(start_at: start_at_time, end_at: Time.now, status: 1, commit_status: 1, score: score, - subjective_score: subjective_score, objective_score: objective_score, commit_method: 5) + subjective_score: subjective_score, objective_score: objective_score, commit_method: 5) end ExerciseUserScore.create!(exercise_id: @exercise.id, exercise_user_id: exercise_user.id, @@ -653,26 +579,20 @@ class ExercisesController < ApplicationController #我的题库 def my_exercises ActiveRecord::Base.transaction do - begin - ## 我的试卷题库 - @current_user_exercises = current_user.exercise_banks.find_by_c_type("Exercise") - if @current_user_exercises.present? + ## 我的试卷题库 + @current_user_exercises = current_user.exercise_banks.find_by_c_type("Exercise") + if @current_user_exercises.present? - if params[:search].present? - search_type = params[:search].to_s.strip - @current_user_exercises = @current_user_exercises.exercise_bank_search(search_type) - end - page = params[:page] || 1 - limit = params[:limit] || 15 - @my_exercises_count = @current_user_exercises.size - @current_user_exercises = @current_user_exercises.page(page).per(limit) - else - @current_user_exercises = [] + if params[:search].present? + search_type = params[:search].to_s.strip + @current_user_exercises = @current_user_exercises.exercise_bank_search(search_type) end - rescue Exception => e - uid_logger_error(e.message) - tip_exception("页面调用失败!") - raise ActiveRecord::Rollback + page = params[:page] || 1 + limit = params[:limit] || 15 + @my_exercises_count = @current_user_exercises.size + @current_user_exercises = @current_user_exercises.page(page).per(limit) + else + @current_user_exercises = [] end end end @@ -680,32 +600,26 @@ class ExercisesController < ApplicationController # 公共题库 def public_exercises ActiveRecord::Base.transaction do - begin - if current_user.is_certification_teacher - @user_certification = 1 #用户已通过认证 - @public_exercises = ExerciseBank.find_by_c_type("Exercise").public_exercises - if @public_exercises.present? - if params[:search].present? - search_type = params[:search].to_s.strip - @public_exercises = @public_exercises.exercise_bank_search(search_type) - end - page = params[:page] || 1 - limit = params[:limit] || 15 - @public_exercises_count = @public_exercises.size - @public_exercises = @public_exercises.page(page).per(limit) - else - @public_exercises_count = 0 - @public_exercises = [] + if current_user.is_certification_teacher + @user_certification = 1 #用户已通过认证 + @public_exercises = ExerciseBank.find_by_c_type("Exercise").public_exercises + if @public_exercises.present? + if params[:search].present? + search_type = params[:search].to_s.strip + @public_exercises = @public_exercises.exercise_bank_search(search_type) end + page = params[:page] || 1 + limit = params[:limit] || 15 + @public_exercises_count = @public_exercises.size + @public_exercises = @public_exercises.page(page).per(limit) else - @user_certification = 0 #用户未通过认证 @public_exercises_count = 0 @public_exercises = [] end - rescue Exception => e - uid_logger_error(e.message) - tip_exception("题库调用失败!") - raise ActiveRecord::Rollback + else + @user_certification = 0 #用户未通过认证 + @public_exercises_count = 0 + @public_exercises = [] end end end @@ -714,17 +628,11 @@ class ExercisesController < ApplicationController def publish_modal ActiveRecord::Base.transaction do - begin - exercise_ids = params[:check_ids] - if exercise_ids.count > 0 - @course_groups = get_user_permission_course(exercise_ids,1) - else - @course_groups = [] - end - rescue Exception => e - uid_logger_error(e.message) - tip_exception("没有权限") - raise ActiveRecord::Rollback + exercise_ids = params[:check_ids] + if exercise_ids.count > 0 + @course_groups = get_user_permission_course(exercise_ids, 1) + else + @course_groups = [] end end end @@ -744,109 +652,95 @@ class ExercisesController < ApplicationController if params[:detail].blank? tip_exception("缺少截止时间参数") if params[:end_time].blank? tip_exception("截止时间不能早于当前时间") if params[:end_time] <= strf_time(Time.now) - tip_exception("截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")})") if - @course.end_date.present? && params[:end_time] > strf_time(@course.end_date.end_of_day) + tip_exception("截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")})") if @course.end_date.present? && params[:end_time] > strf_time(@course.end_date.end_of_day) else - group_end_times = params[:group_end_times].reject(&:blank?).map{|time| time.to_time} + group_end_times = params[:group_end_times].reject(&:blank?).map {|time| time.to_time} tip_exception("缺少截止时间参数") if group_end_times.blank? tip_exception("截止时间和分班参数的个数不一致") if group_end_times.length != group_ids.length group_end_times.each do |time| tip_exception("分班截止时间不能早于当前时间") if time <= Time.now - tip_exception("分班截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")})") if - @course.end_date.present? && time > @course.end_date.end_of_day + tip_exception("分班截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")})") if @course.end_date.present? && time > @course.end_date.end_of_day end end ActiveRecord::Base.transaction do - begin - check_ids = Exercise.where(id: params[:check_ids]) - ex_end_time = params[:end_time].blank? ? Time.at(((1.month.since.to_i)/3600.0).ceil * 3600) : params[:end_time].to_time - check_ids.each do |exercise| - if exercise.present? - if exercise.unified_setting - ex_status = exercise.exercise_status #则为试卷的状态 + check_ids = Exercise.where(id: params[:check_ids]) + ex_end_time = params[:end_time].blank? ? Time.at(((1.month.since.to_i) / 3600.0).ceil * 3600) : params[:end_time].to_time + check_ids.each do |exercise| + if exercise.present? + if exercise.unified_setting + ex_status = exercise.exercise_status #则为试卷的状态 + else + ex_status = @course.course_groups.where(id: params[:group_ids]).size != + exercise.exercise_group_settings.where(course_group_id: params[:group_ids]).exercise_group_published.size ? 1 : 0 + end + if ex_status == 1 #如果试卷存在已发布的,或者是已截止的,那么则直接跳过 + g_course = group_ids #表示是否传入分班参数,如果传入分班的参数,那么试卷的统一设置需修改 + tiding_group_ids = g_course + if g_course + user_course_groups = @course.course_groups.pluck(:id) + if g_course.map(&:to_i).sort == user_course_groups.sort && + ((params[:detail] && group_end_times.min == group_end_times.max) || params[:detail].blank?) # 如果是设置为全部班级,则试卷不用分组,且试卷设定为统一设置,否则则分组设置 + exercise.exercise_group_settings.destroy_all + ex_unified = true + e_time = params[:detail] ? group_end_times.max : ex_end_time + tiding_group_ids = [] + else + ex_unified = false + g_course.each_with_index do |i, index| + exercise_group_setting = exercise.exercise_group_settings.find_in_exercise_group("course_group_id", i).first #根据课堂分班的id,寻找试卷所在的班级 + group_end_time = params[:detail] ? group_end_times[index] : ex_end_time + if exercise_group_setting.present? #如果该试卷分组存在,则更新,否则新建 + exercise_group_setting.update!(publish_time: Time.now, end_time: group_end_time) + else + p_course_group = { + :exercise_id => exercise.id, + :course_group_id => i, + :course_id => exercise.course.id, + :publish_time => Time.now, + :end_time => group_end_time, + } + new_exercise_group = exercise.exercise_group_settings.new p_course_group + new_exercise_group.save! + end + end + # group_ids = params[:group_ids] + e_time = exercise.exercise_group_settings.end_time_no_null.map(&:end_time).max + end else - ex_status = @course.course_groups.where(id: params[:group_ids]).size != - exercise.exercise_group_settings.where(course_group_id: params[:group_ids]).exercise_group_published.size ? 1 : 0 + exercise.exercise_group_settings.destroy_all + ex_unified = true + e_time = ex_end_time end - if ex_status == 1 #如果试卷存在已发布的,或者是已截止的,那么则直接跳过 - g_course = group_ids #表示是否传入分班参数,如果传入分班的参数,那么试卷的统一设置需修改 - tiding_group_ids = g_course - if g_course - user_course_groups = @course.course_groups.pluck(:id) - if g_course.map(&:to_i).sort == user_course_groups.sort && - ((params[:detail] && group_end_times.min == group_end_times.max) || params[:detail].blank?) # 如果是设置为全部班级,则试卷不用分组,且试卷设定为统一设置,否则则分组设置 - exercise.exercise_group_settings.destroy_all - ex_unified = true - e_time = params[:detail] ? group_end_times.max : ex_end_time - tiding_group_ids = [] - else - ex_unified = false - g_course.each_with_index do |i, index| - exercise_group_setting = exercise.exercise_group_settings.find_in_exercise_group("course_group_id",i).first #根据课堂分班的id,寻找试卷所在的班级 - group_end_time = params[:detail] ? group_end_times[index] : ex_end_time - if exercise_group_setting.present? #如果该试卷分组存在,则更新,否则新建 - exercise_group_setting.update!(publish_time: Time.now, end_time: group_end_time) - else - p_course_group = { - :exercise_id => exercise.id, - :course_group_id => i, - :course_id => exercise.course.id, - :publish_time => Time.now, - :end_time => group_end_time, - } - new_exercise_group = exercise.exercise_group_settings.new p_course_group - new_exercise_group.save! - end - end - # group_ids = params[:group_ids] - e_time = exercise.exercise_group_settings.end_time_no_null.map(&:end_time).max - end - else - exercise.exercise_group_settings.destroy_all - ex_unified = true - e_time = ex_end_time - end - ex_status = set_exercise_status(Time.now,e_time) - exercise_params = { - :publish_time => Time.now, - :end_time => e_time, - :exercise_status => ex_status, - :unified_setting => ex_unified - } - exercise.update!(exercise_params) + ex_status = set_exercise_status(Time.now, e_time) + exercise_params = { + :publish_time => Time.now, + :end_time => e_time, + :exercise_status => ex_status, + :unified_setting => ex_unified + } + exercise.update!(exercise_params) - if exercise.course_acts.size == 0 - exercise.course_acts << CourseActivity.new(:user_id => exercise.user_id,:course_id => exercise.course_id) - end - ExercisePublishNotifyJob.perform_later(exercise.id, tiding_group_ids) + if exercise.course_acts.size == 0 + exercise.course_acts << CourseActivity.new(:user_id => exercise.user_id, :course_id => exercise.course_id) end + ExercisePublishNotifyJob.perform_later(exercise.id, tiding_group_ids) end end - normal_status(0, "试卷发布成功!") - rescue Exception => e - uid_logger_error(e.message) - tip_exception("试卷发布失败") - raise ActiveRecord::Rollback end + normal_status(0, "试卷发布成功!") end end #立即截止的弹窗内容 def end_modal ActiveRecord::Base.transaction do - begin - exercise_ids = params[:check_ids] - if exercise_ids.count > 0 - @course_groups = get_user_permission_course(exercise_ids,3) - else - @course_groups = [] - end - rescue Exception => e - uid_logger_error(e.message) - tip_exception("没有权限") - raise ActiveRecord::Rollback + exercise_ids = params[:check_ids] + if exercise_ids.count > 0 + @course_groups = get_user_permission_course(exercise_ids, 3) + else + @course_groups = [] end end end @@ -855,128 +749,116 @@ class ExercisesController < ApplicationController def end_exercise ActiveRecord::Base.transaction do - begin - check_ids = Exercise.where(id:params[:check_ids]) - course_students = @course.students #课堂的全部学生数 - check_ids.each do |exercise| - exercise_status= exercise.get_exercise_status(current_user) - if exercise_status == Exercise::PUBLISHED #跳过已截止的或未发布的 - g_course = params[:group_ids] - if g_course.present? - teacher_course_group_ids = @course.charge_group_ids(current_user) - all_course_group_ids = @course.course_groups.pluck(:id) - if exercise.unified_setting && g_course.map(&:to_i).sort == all_course_group_ids.sort #开始为统一设置 - exercise.exercise_group_settings.destroy_all - new_ex_status = set_exercise_status(exercise.publish_time,Time.now) - exercise.update!(:end_time => Time.now,:exercise_status => new_ex_status) - exercise_users = exercise.exercise_users - else - course_members_ids = course_students.course_find_by_ids("course_group_id",g_course).pluck(:user_id).uniq #该班级的全部学生 - exercise_users = exercise.exercise_users.exercise_commit_users(course_members_ids) #参与答题的学生数 - ex_group_setting = exercise.exercise_group_settings - old_exercise_groups = ex_group_setting.find_in_exercise_group("course_group_id",g_course) #试卷的分组设置 - left_course_groups = teacher_course_group_ids - g_course - left_exercise_groups = ex_group_setting.find_in_exercise_group("course_group_id",left_course_groups) - if left_exercise_groups.blank? && exercise.unified_setting - if left_course_groups.size > 0 #开始为统一设置,但是立即截止为分班。则创建没有立即截止的班级的exercise_group_setting - left_course_groups.each do |g| - ex_group_options = { - :exercise_id => exercise.id, - :course_group_id => g, - :course_id => @course.id, - :publish_time => exercise.publish_time, - :end_time => exercise.end_time - } - ExerciseGroupSetting.create!(ex_group_options) - end - end - end - if old_exercise_groups.present? - old_exercise_groups.update_all(:end_time => Time.now) - else - g_course.each do |g| + check_ids = Exercise.where(id: params[:check_ids]) + course_students = @course.students #课堂的全部学生数 + check_ids.each do |exercise| + exercise_status = exercise.get_exercise_status(current_user) + if exercise_status == Exercise::PUBLISHED #跳过已截止的或未发布的 + g_course = params[:group_ids] + if g_course.present? + teacher_course_group_ids = @course.charge_group_ids(current_user) + all_course_group_ids = @course.course_groups.pluck(:id) + if exercise.unified_setting && g_course.map(&:to_i).sort == all_course_group_ids.sort #开始为统一设置 + exercise.exercise_group_settings.destroy_all + new_ex_status = set_exercise_status(exercise.publish_time, Time.now) + exercise.update!(:end_time => Time.now, :exercise_status => new_ex_status) + exercise_users = exercise.exercise_users + else + course_members_ids = course_students.course_find_by_ids("course_group_id", g_course).pluck(:user_id).uniq #该班级的全部学生 + exercise_users = exercise.exercise_users.exercise_commit_users(course_members_ids) #参与答题的学生数 + ex_group_setting = exercise.exercise_group_settings + old_exercise_groups = ex_group_setting.find_in_exercise_group("course_group_id", g_course) #试卷的分组设置 + left_course_groups = teacher_course_group_ids - g_course + left_exercise_groups = ex_group_setting.find_in_exercise_group("course_group_id", left_course_groups) + if left_exercise_groups.blank? && exercise.unified_setting + if left_course_groups.size > 0 #开始为统一设置,但是立即截止为分班。则创建没有立即截止的班级的exercise_group_setting + left_course_groups.each do |g| ex_group_options = { - :exercise_id => exercise.id, - :course_group_id => g, - :course_id => @course.id, - :publish_time => exercise.publish_time, - :end_time => Time.now + :exercise_id => exercise.id, + :course_group_id => g, + :course_id => @course.id, + :publish_time => exercise.publish_time, + :end_time => exercise.end_time } ExerciseGroupSetting.create!(ex_group_options) end end - new_end_time = exercise.exercise_group_settings.end_time_no_null.map(&:end_time) # 试卷结束时间不为空的 - new_end_time_s = new_end_time.count > 0 ? new_end_time.max : Time.now - new_ex_status = set_exercise_status(exercise.publish_time,new_end_time_s) - exercise.update!(:end_time => new_end_time_s,:exercise_status => new_ex_status,:unified_setting => false) end - else - exercise_users = exercise.exercise_users - exercise.update!(:exercise_status => 3, :end_time => Time.now,:unified_setting => true) + if old_exercise_groups.present? + old_exercise_groups.update_all(:end_time => Time.now) + else + g_course.each do |g| + ex_group_options = { + :exercise_id => exercise.id, + :course_group_id => g, + :course_id => @course.id, + :publish_time => exercise.publish_time, + :end_time => Time.now + } + ExerciseGroupSetting.create!(ex_group_options) + end + end + new_end_time = exercise.exercise_group_settings.end_time_no_null.map(&:end_time) # 试卷结束时间不为空的 + new_end_time_s = new_end_time.count > 0 ? new_end_time.max : Time.now + new_ex_status = set_exercise_status(exercise.publish_time, new_end_time_s) + exercise.update!(:end_time => new_end_time_s, :exercise_status => new_ex_status, :unified_setting => false) end - - ex_user_ids = exercise_users.pluck(:id) - - EndExerciseCalculateJob.perform_later(ex_user_ids,exercise,Time.now.to_s) - # exercise_users.each do |user| - # if user.commit_status == 0 && user.start_at.present? - # objective_score = calculate_student_score(exercise,user.user)[:total_score] - # user_sub_score = user.subjective_score - # subjective_score = user_sub_score < 0.0 ? 0.0 : user_sub_score - # total_score = objective_score + subjective_score - # commit_option = { - # :status => 1, - # :commit_status => 1, - # :end_at => Time.now, - # :objective_score => objective_score, - # :score => total_score, - # :subjective_score => user_sub_score - # } - # user.update_attributes(commit_option) - # end - # end + else + exercise_users = exercise.exercise_users + exercise.update!(:exercise_status => 3, :end_time => Time.now, :unified_setting => true) end + + ex_user_ids = exercise_users.pluck(:id) + + EndExerciseCalculateJob.perform_later(ex_user_ids, exercise, Time.now.to_s) + # exercise_users.each do |user| + # if user.commit_status == 0 && user.start_at.present? + # objective_score = calculate_student_score(exercise,user.user)[:total_score] + # user_sub_score = user.subjective_score + # subjective_score = user_sub_score < 0.0 ? 0.0 : user_sub_score + # total_score = objective_score + subjective_score + # commit_option = { + # :status => 1, + # :commit_status => 1, + # :end_at => Time.now, + # :objective_score => objective_score, + # :score => total_score, + # :subjective_score => user_sub_score + # } + # user.update_attributes(commit_option) + # end + # end end - normal_status(0, "试卷截止成功!") - rescue Exception => e - uid_logger_error(e.message) - tip_exception("立即截止失败!") - raise ActiveRecord::Rollback end + normal_status(0, "试卷截止成功!") end end #学生撤销回答 def cancel_exercise ActiveRecord::Base.transaction do - begin - ex_question_ids = @exercise.exercise_questions.pluck(:id) - exercise_user = @exercise.exercise_users.exercise_commit_users(current_user.id).first - if exercise_user.present? - if exercise_user.commit_status == 1 && @exercise.get_exercise_status(current_user) == Exercise::PUBLISHED #用户已提交且试卷提交中 - if @exercise.time == -1 || ((Time.now.to_i - exercise_user.start_at.to_i) < @exercise.time.to_i * 60) - exercise_user.update!(:score => nil, :end_at => nil, :status => nil, :commit_status => 0, - :objective_score => 0.0, :subjective_score => -1.0) - exercise_user.user.exercise_shixun_answers.search_shixun_answers("exercise_question_id",ex_question_ids).destroy_all - exercise_answers = exercise_user.user.exercise_answers.search_answer_users("exercise_question_id",ex_question_ids) - exercise_answers.update_all(:score => -1.0) - all_answer_comment = ExerciseAnswerComment.search_answer_comments("exercise_question_id",ex_question_ids) - .search_answer_comments("exercise_answer_id",exercise_answers.pluck(:id)) - all_answer_comment.destroy_all - normal_status(0,"撤销回答成功") - else - normal_status(-1,"用户答题时间已到") - end + ex_question_ids = @exercise.exercise_questions.pluck(:id) + exercise_user = @exercise.exercise_users.exercise_commit_users(current_user.id).first + if exercise_user.present? + if exercise_user.commit_status == 1 && @exercise.get_exercise_status(current_user) == Exercise::PUBLISHED #用户已提交且试卷提交中 + if @exercise.time == -1 || ((Time.now.to_i - exercise_user.start_at.to_i) < @exercise.time.to_i * 60) + exercise_user.update!(:score => nil, :end_at => nil, :status => nil, :commit_status => 0, + :objective_score => 0.0, :subjective_score => -1.0) + exercise_user.user.exercise_shixun_answers.search_shixun_answers("exercise_question_id", ex_question_ids).destroy_all + exercise_answers = exercise_user.user.exercise_answers.search_answer_users("exercise_question_id", ex_question_ids) + exercise_answers.update_all(:score => -1.0) + all_answer_comment = ExerciseAnswerComment.search_answer_comments("exercise_question_id", ex_question_ids) + .search_answer_comments("exercise_answer_id", exercise_answers.pluck(:id)) + all_answer_comment.destroy_all + normal_status(0, "撤销回答成功") else - normal_status(-1,"用户未提交/试卷不是提交中") + normal_status(-1, "用户答题时间已到") end else - normal_status(-1,"当前用户未答题") + normal_status(-1, "用户未提交/试卷不是提交中") end - rescue Exception => e - uid_logger_error(e.message) - tip_exception("页面调用失败") - raise ActiveRecord::Rollback + else + normal_status(-1, "当前用户未答题") end end end @@ -984,307 +866,1614 @@ class ExercisesController < ApplicationController #打回重做modal def redo_modal ActiveRecord::Base.transaction do - begin - #搜索 - if params[:realname].present? - search_name = params[:realname] - #搜索用户的nickname,如果存在则返回,否则继续查询用户的真实姓名或学生号 - @exercise_users = @exercise_users.includes(:user).where("LOWER(concat(users.lastname, users.firstname)) like ?", - "%#{search_name}%") - end - if params[:student_id].present? - search_st_id = params[:student_id].to_i - @exercise_users = @exercise_users.includes(user: [:user_extension]) - .where('user_extensions.student_id like ?',"%#{search_st_id}%") - end - sort = params[:sort] ? params[:sort] : "asc" - @exercise_users = @exercise_users.order("score #{sort}") - @exercise_users_size = @exercise_users.size - # 分页 - page = params[:page] || 1 - limit = params[:limit] || 15 - @exercise_users = @exercise_users.page(page).per(limit) - rescue Exception => e - uid_logger_error(e.message) - tip_exception("没有权限") - raise ActiveRecord::Rollback + #搜索 + if params[:realname].present? + search_name = params[:realname] + #搜索用户的nickname,如果存在则返回,否则继续查询用户的真实姓名或学生号 + @exercise_users = @exercise_users.includes(:user).where("LOWER(concat(users.lastname, users.firstname)) like ?", + "%#{search_name}%") end + if params[:student_id].present? + search_st_id = params[:student_id].to_i + @exercise_users = @exercise_users.includes(user: [:user_extension]) + .where('user_extensions.student_id like ?', "%#{search_st_id}%") + end + sort = params[:sort] ? params[:sort] : "asc" + @exercise_users = @exercise_users.order("score #{sort}") + @exercise_users_size = @exercise_users.size + # 分页 + page = params[:page] || 1 + limit = params[:limit] || 15 + @exercise_users = @exercise_users.page(page).per(limit) end end #打回重做确认 def redo_exercise ActiveRecord::Base.transaction do - begin - user_ids = params[:user_ids] - if user_ids.present? - redo_option = { - :score => 0.0, - :start_at => nil, - :end_at => nil, - :status => nil, - :commit_status => 0, - :objective_score => 0.0, - :subjective_score => -1.0, - :commit_method => 0 - } - redo_exercise_users = @exercise_users.exercise_commit_users(user_ids) - redo_exercise_users.update_all(redo_option) - exercise_question_ids = @exercise.exercise_questions.pluck(:id).uniq - ExerciseAnswer.search_answer_users("user_id",user_ids) - .search_answer_users("exercise_question_id",exercise_question_ids).destroy_all - ExerciseShixunAnswer.search_shixun_answers("user_id",user_ids) - .search_shixun_answers("exercise_question_id",exercise_question_ids).destroy_all - - normal_status(0,"已成功打回重做!") - else - normal_status(-1,"请选择学生!") - end - rescue Exception => e - uid_logger_error(e.message) - tip_exception("没有权限") - raise ActiveRecord::Rollback + user_ids = params[:user_ids] + if user_ids.present? + redo_option = { + :score => 0.0, + :start_at => nil, + :end_at => nil, + :status => nil, + :commit_status => 0, + :objective_score => 0.0, + :subjective_score => -1.0, + :commit_method => 0 + } + redo_exercise_users = @exercise_users.exercise_commit_users(user_ids) + redo_exercise_users.update_all(redo_option) + exercise_question_ids = @exercise.exercise_questions.pluck(:id).uniq + ExerciseAnswer.search_answer_users("user_id", user_ids) + .search_answer_users("exercise_question_id", exercise_question_ids).destroy_all + ExerciseShixunAnswer.search_shixun_answers("user_id", user_ids) + .search_shixun_answers("exercise_question_id", exercise_question_ids).destroy_all + + normal_status(0, "已成功打回重做!") + else + normal_status(-1, "请选择学生!") end end end #学生开始答题页面 def start_answer - begin - ex_users_current = ExerciseUser.where(user_id:@exercise_current_user_id,exercise_id:@exercise.id) #不能用@exercise.exercise_users,因为exercise_users删除时,只是状态改变,未删除 - @exercise_user_current = ex_users_current&.first - if ex_users_current.exists? - if @exercise_user_current.start_at.blank? - @exercise_user_current.update!(start_at: Time.now) + ex_users_current = ExerciseUser.where(user_id: @exercise_current_user_id, exercise_id: @exercise.id) #不能用@exercise.exercise_users,因为exercise_users删除时,只是状态改变,未删除 + @exercise_user_current = ex_users_current&.first + if ex_users_current.exists? + if @exercise_user_current.start_at.blank? + @exercise_user_current.update!(start_at: Time.now) + end + else + if @user_course_identity > Course::ASSISTANT_PROFESSOR #当为老师的时候,不创建exercise_user表,理论上老师是不能进入答题的 + exercise_user_params = { + :user_id => @exercise_current_user_id, + :exercise_id => @exercise.id, + :start_at => Time.now + } + exercise_user_current = ExerciseUser.new(exercise_user_params) + exercise_user_current.save! + end + end + @t_user_exercise_status = @exercise.get_exercise_status(current_user) + + @user_left_time = nil + if @user_course_identity < Course::STUDENT || (@t_user_exercise_status == 3) || + (ex_users_current.exists? && @exercise_user_current.commit_status == 1) + @user_exercise_status = 1 #当前用户为老师/试卷已截止/试卷已提交不可编辑 + else + @user_left_time = get_exercise_left_time(@exercise, current_user) + @user_exercise_status = 0 #可编辑 + end + + @exercise_questions = @exercise.exercise_questions + + if @exercise.question_random + @exercise_questions = @exercise_questions.order("RAND()") + else + @exercise_questions = @exercise_questions.order("question_number ASC") + end + # 判断问题是否已回答还是未回答 + @exercise_questions = @exercise_questions.includes(:exercise_shixun_challenges, + :exercise_shixun_answers, + :exercise_answers, + :exercise_standard_answers) + + if @t_user_exercise_status == Exercise::DEADLINE + get_each_student_exercise(@exercise.id, @exercise_questions, @exercise_current_user_id) + end + get_user_answer_status(@exercise_questions, @exercise_current_user_id, @exercise, @t_user_exercise_status) + + end + + #提交试卷前的弹窗 + def begin_commit + ActiveRecord::Base.transaction do + if @user_course_identity > Course::ASSISTANT_PROFESSOR #为学生时 + @exercise_questions = @exercise.exercise_questions + @shixun_undo = 0 + @ques_undo = 0 + ex_answer_time = @exercise.time.to_i + if ex_answer_time > 0 #有剩余时间的时候 + user_left_time = get_exercise_left_time(@exercise, current_user) + @ex_end_time = Time.now + user_left_time.to_i.seconds + else + @ex_end_time = @exercise.get_exercise_end_time(current_user.id) end - else - if @user_course_identity > Course::ASSISTANT_PROFESSOR #当为老师的时候,不创建exercise_user表,理论上老师是不能进入答题的 - exercise_user_params = { - :user_id => @exercise_current_user_id, - :exercise_id => @exercise.id, - :start_at => Time.now - } - exercise_user_current = ExerciseUser.new(exercise_user_params) - exercise_user_current.save! + # @ex_end_time = @exercise.get_exercise_end_time(current_user.id) + # if ex_answer_time > 0 + # left_answer_time = Time.now + ex_answer_time.minutes #判断试卷的倒计时和截止时间哪个先到 + # if left_answer_time < @ex_end_time + # exercise_end_time = @exercise.exercise_users.exercise_commit_users(current_user.id) + # if exercise_end_time.present? + # ex_end_times = exercise_end_time.first.start_at.nil? ? Time.now : exercise_end_time.first.start_at + # @ex_end_time = ex_end_times + ex_answer_time.minutes + # end + # end + # end + @exercise_questions.each do |q| + if q.question_type == Exercise::PRACTICAL #当为实训题时 + user_myshixun = q.shixun.myshixuns.search_myshixun_user(current_user.id) + if user_myshixun.blank? || user_myshixun.first.status != Exercise::UNPUBLISHED #当前用户的实训是否做完 + @shixun_undo += 1 + end + else + ques_vote = q.exercise_answers.search_exercise_answer("user_id", current_user.id) + if ques_vote.blank? + @ques_undo += 1 + end + end end end - @t_user_exercise_status = @exercise.get_exercise_status(current_user) + end + end - @user_left_time = nil - if @user_course_identity < Course::STUDENT || (@t_user_exercise_status == 3) || - (ex_users_current.exists? && @exercise_user_current.commit_status == 1) - @user_exercise_status = 1 #当前用户为老师/试卷已截止/试卷已提交不可编辑 + # 学生提交试卷 + def commit_exercise + tip_exception(0, "试卷截止时间已到,系统已自动提交") if @answer_committed_user.commit_status == 1 + ActiveRecord::Base.transaction do + can_commit_exercise = false + user_left_time = nil + if @user_course_identity > Course::ASSISTANT_PROFESSOR #为学生时 + if params[:commit_method].to_i == 2 #自动提交时 + user_left_time = get_exercise_left_time(@exercise, current_user) + Rails.logger.info("######__________auto_commit_user_left_time_________################{user_left_time}") + if user_left_time.to_i <= 0 + can_commit_exercise = true + end + else + can_commit_exercise = true + end + if can_commit_exercise + objective_score = calculate_student_score(@exercise, current_user, Time.now)[:total_score] + subjective_score = @answer_committed_user.subjective_score + total_score_subjective_score = subjective_score < 0.0 ? 0.0 : subjective_score + total_score = objective_score + total_score_subjective_score + commit_option = { + :status => 1, + :commit_status => 1, + :end_at => Time.now, + :objective_score => objective_score, + :score => total_score, + :subjective_score => subjective_score, + :commit_method => @answer_committed_user&.commit_method.to_i > 0 ? @answer_committed_user&.commit_method.to_i : params[:commit_method].to_i + } + @answer_committed_user.update!(commit_option) + CommitExercsieNotifyJobJob.perform_later(@exercise.id, current_user.id) + normal_status(0, "试卷提交成功!") + else + normal_status(-2, "#{user_left_time.to_i}") + end else - @user_left_time = get_exercise_left_time(@exercise,current_user) - @user_exercise_status = 0 #可编辑 + normal_status(-1, "提交失败,当前用户不为课堂学生!") + end + end + end + + #教师评阅试卷 及学生查看试卷 + def review_exercise + ActiveRecord::Base.transaction do + # 1 老师权限,0 学生权限 + @is_teacher_or = (@user_course_identity < Course::STUDENT) ? 1 : 0 + @student_status = 2 + @exercise_questions = @exercise.exercise_questions.includes(:exercise_shixun_challenges, :exercise_standard_answers, :exercise_answers, :exercise_shixun_answers, :exercise_answer_comments).order("question_number ASC") + @question_status = [] + get_exercise_status = @exercise.get_exercise_status(current_user) #当前用户的试卷状态 + @ex_answer_status = @exercise.get_exercise_status(@ex_user&.user) #当前试卷用户的试卷状态 + if @ex_user.present? && @is_teacher_or == 0 + if get_exercise_status == Exercise::PUBLISHED #当前用户已提交,且试卷未截止 + if @ex_user.commit_status == 0 #学生未提交,且当前为学生 + @student_status = 0 + else + @student_status = 1 + get_user_answer_status(@exercise_questions, @exercise_current_user_id, @exercise, get_exercise_status) + end + end + end + if @student_status == 2 + get_each_student_exercise(@exercise.id, @exercise_questions, @exercise_current_user_id) + end + end + end + + #答题列表 + def exercise_lists + @current_user_id = current_user.id + exercise_ids = [@exercise.id] + @exercise_status = @exercise.get_exercise_status(current_user) + @course_all_members = @course.students + @c_group_counts = @course.course_groups_count + question_types = @exercise.exercise_questions.pluck(:question_type).uniq + @exercise_publish_count = get_user_permission_course(exercise_ids, Exercise::PUBLISHED).count #判断是否有已发布的分班 + @exercise_unpublish_count = get_user_permission_course(exercise_ids, Exercise::UNPUBLISHED).count #判断是否有未发布的分班 + + if (question_types.size > 1) && question_types.include?(Exercise::SUBJECTIVE) #是否包含主观题,或者是否大于1 + @subjective_type = 1 + else + @subjective_type = 0 + end + + #初始化值 + @exercise_users_list = [] #答题用户列表 + @exercise_course_groups = [] #当前用户有权限的班级 + @exercise_unanswers = 0 # 未答用户数 + @exercise_answers = 0 #已答用户数 + @exercise_users_count = 0 #全部用户数 + @teacher_review_count = 0 #已评数 + @teacher_unreview_count = 0 #未评数 + + #试卷的答题列表页的显示用户 + if @user_course_identity < Course::STUDENT #当前为老师,而且老师只能查看自己班级的/课堂的试卷 + @exercise_current_user_status = 0 + unless @exercise_status == Exercise::UNPUBLISHED + ex_common_ids = @exercise.common_published_ids(current_user.id) + @exercise_course_groups = @course.get_ex_published_course(ex_common_ids) + @exercise_users_list = @exercise.all_exercise_users(current_user.id) #当前老师所在班级的全部学生 + get_exercise_answers(@exercise_users_list, @exercise_status) + end + else #当前为学生或者有过答题的 + @ex_user_end_time = @exercise.get_exercise_end_time(current_user.id) #当前用户所看到的剩余时间 + @exercise_all_users = @exercise.get_stu_exercise_users + get_exercise_answers(@exercise_all_users, @exercise_status) # 未答和已答的 + exercise_current_user = @exercise_all_users.exercise_commit_users(current_user.id) + if exercise_current_user.exists? #表示为课堂学生或已回答的 + @exercise_current_user_status = 1 + if @exercise.score_open && @exercise_status == Exercise::DEADLINE #勾选了成绩公开且试卷已截止的 + all_user_ids = @exercise_all_users.pluck(:user_id) + all_user_ids.delete(current_user.id) #删除了当前用户的ID + @exercise_users_list = @exercise_all_users.exercise_commit_users(all_user_ids).distinct + @current_user_ex_answers = exercise_current_user #当前用户的回答 + else + @exercise_users_list = exercise_current_user + end + else #表示为未回答的,或未非课堂成员的 + @exercise_current_user_status = 2 #当前用户非课堂成员 + end + end + + if @exercise_unanswers < 0 + @exercise_unanswers = 0 + end + + #筛选/分类,排序 + order = params[:order] + order_type = params[:order_type] || "desc" + + if @exercise_users_list.present? && @exercise_users_list.size > 0 + @exercise_users_count = @exercise_users_list.size #当前显示的全部成员数量 + teacher_reviews = @exercise_users_list.exercise_review + teacher_unreviews = @exercise_users_list.exercise_unreview + @teacher_review_count = teacher_reviews.size #已评阅 + @teacher_unreview_count = teacher_unreviews.size #未评阅 + + #是否评阅 + if params[:review].present? + review_type = params[:review].first.to_i #已评,则数据为1,未评,则数据为0,前端传过来的为数组 + if review_type == 1 + @exercise_users_list = teacher_reviews + else + @exercise_users_list = teacher_unreviews + end + end + + #答题状态的选择 + if params[:commit_status].present? + choose_type = params[:commit_status] + @exercise_users_list = @exercise_users_list.commit_exercise_by_status(choose_type) + end + + #班级的选择 + if params[:exercise_group_id].present? + group_id = params[:exercise_group_id] + exercise_students = @course_all_members.course_find_by_ids("course_group_id", group_id) #试卷所分班的全部人数 + user_ids = exercise_students.pluck(:user_id).reject(&:blank?) + @exercise_users_list = @exercise_users_list.exercise_commit_users(user_ids) + end + + #搜索 + if params[:search].present? + @exercise_users_list = @exercise_users_list.joins(user: :user_extension).where("CONCAT(lastname, firstname) like ? OR student_id like ?", "%#{params[:search]}%", "%#{params[:search]}%") end - @exercise_questions = @exercise.exercise_questions + exercise_user_joins = @exercise_users_list.joins(user: :user_extension) - if @exercise.question_random - @exercise_questions = @exercise_questions.order("RAND()") + if order == "student_id" + @exercise_users_list = exercise_user_joins.order("user_extensions.student_id #{order_type}") + elsif order == "score" + @exercise_users_list = exercise_user_joins.order("#{order} #{order_type}") else - @exercise_questions = @exercise_questions.order("question_number ASC") + @exercise_users_list = exercise_user_joins.order("end_at #{order_type}, start_at #{order_type}") end - # 判断问题是否已回答还是未回答 - @exercise_questions = @exercise_questions.includes(:exercise_shixun_challenges, - :exercise_shixun_answers, - :exercise_answers, - :exercise_standard_answers) - if @t_user_exercise_status == Exercise::DEADLINE - get_each_student_exercise(@exercise.id,@exercise_questions,@exercise_current_user_id) + @export_ex_users = @exercise_users_list + + @exercise_users_size = @exercise_users_list.size + + # 分页 + @page = params[:page] || 1 + @limit = params[:limit] || 20 + @exercise_users_list = @exercise_users_list.page(@page).per(@limit) + else + @exercise_users_list = [] + @export_ex_users = @exercise_users_list + @exercise_users_size = 0 + end + + if params[:format] == "xlsx" + if @user_course_identity > Course::ASSISTANT_PROFESSOR + tip_exception(403, "无权限操作") + elsif @exercise_status == Exercise::UNPUBLISHED + normal_status(-1, "试卷未发布") + elsif (@exercise_users_size == 0) || (@export_ex_users&.exercise_user_committed.size == 0) + normal_status(-1, "暂无用户提交") + elsif params[:export].present? && params[:export] + normal_status(0, "正在下载中") + else + respond_to do |format| + format.xlsx { + set_export_cookies + get_export_users(@exercise, @course, @export_ex_users) + exercise_export_name_ = + "#{current_user.real_name}_#{@course.name}_#{@exercise.exercise_name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}" + render xlsx: "#{exercise_export_name_.strip}", template: "exercises/exercise_lists.xlsx.axlsx", locals: {table_columns: @table_columns, exercise_users: @user_columns} + } + end end - get_user_answer_status(@exercise_questions,@exercise_current_user_id,@exercise,@t_user_exercise_status) + end + end - rescue Exception => e - uid_logger_error(e.message) - tip_exception(e.message) - raise ActiveRecord::Rollback + #导出空白试卷 + def export_exercise + @request_url = request.base_url + @exercise_questions = @exercise.exercise_questions.includes(:exercise_choices).order("question_number ASC") + filename_ = "#{@exercise.user.real_name}_#{@course.name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}.pdf" + stylesheets = "#{Rails.root}/app/templates/exercise_export/exercise_export.css" + if params[:export].present? && params[:export] + normal_status(0, "正在下载中") + else + set_export_cookies + render pdf: 'exercise_export/blank_exercise', filename: filename_, stylesheets: stylesheets, disposition: 'inline', type: "pdf_attachment.content_type", stream: false end end - #提交试卷前的弹窗 - def begin_commit - ActiveRecord::Base.transaction do - begin - if @user_course_identity > Course::ASSISTANT_PROFESSOR #为学生时 - @exercise_questions = @exercise.exercise_questions - @shixun_undo = 0 - @ques_undo = 0 - ex_answer_time = @exercise.time.to_i - if ex_answer_time > 0 #有剩余时间的时候 - user_left_time = get_exercise_left_time(@exercise,current_user) - @ex_end_time = Time.now + user_left_time.to_i.seconds - else - @ex_end_time = @exercise.get_exercise_end_time(current_user.id) - end - # @ex_end_time = @exercise.get_exercise_end_time(current_user.id) - # if ex_answer_time > 0 - # left_answer_time = Time.now + ex_answer_time.minutes #判断试卷的倒计时和截止时间哪个先到 - # if left_answer_time < @ex_end_time - # exercise_end_time = @exercise.exercise_users.exercise_commit_users(current_user.id) - # if exercise_end_time.present? - # ex_end_times = exercise_end_time.first.start_at.nil? ? Time.now : exercise_end_time.first.start_at - # @ex_end_time = ex_end_times + ex_answer_time.minutes - # end - # end - # end - @exercise_questions.each do |q| - if q.question_type == Exercise::PRACTICAL #当为实训题时 - user_myshixun = q.shixun.myshixuns.search_myshixun_user(current_user.id) - if user_myshixun.blank? || user_myshixun.first.status != Exercise::UNPUBLISHED #当前用户的实训是否做完 - @shixun_undo += 1 + #空白试卷预览页面,仅供测试使用,无其他任何用途 + # def blank_exercise + # ActiveRecord::Base.transaction do + # begin + # @exercise_questions = @exercise.exercise_questions.order("question_number ASC") + # challenge_ids = @exercise_questions.joins(:exercise_shixun_challenges).pluck("exercise_shixun_challenges.challenge_id") + # get_each_student_exercise(@exercise.id,@exercise_questions,31798) + # @games = @exercise_user.user.games.ch_games(challenge_ids) + # respond_to do |format| + # format.html + # end + # rescue Exception => e + # uid_logger_error(e.message) + # tip_exception("没有权限") + # raise ActiveRecord::Rollback + # end + # end + # end + + #学生的统计结果 + def exercise_result + exercise_ids = [@exercise.id] + @exercise_publish_count = get_user_permission_course(exercise_ids, Exercise::PUBLISHED).size #判断是否有已发布的分班 + @exercise_unpublish_count = get_user_permission_course(exercise_ids, Exercise::UNPUBLISHED).size #判断是否有未发布的分班 + @course_all_members = @course.students #课堂的全部学生 + @exercise_all_users = @exercise.exercise_users + ex_common_ids = @exercise.common_published_ids(current_user.id) + @exercise_course_groups = @course.get_ex_published_course(ex_common_ids) + + #班级的选择 + if params[:exercise_group_id].present? + group_id = params[:exercise_group_id] + exercise_students = @course_all_members.course_find_by_ids("course_group_id", group_id) # 试卷所分班的全部人数 + user_ids = exercise_students.pluck(:user_id).reject(&:blank?) + @exercise_all_users = @exercise.exercise_users.exercise_commit_users(user_ids) + @course_all_members_count = @exercise_all_users.size + else + @exercise_users_list = @exercise.all_exercise_users(current_user.id) + @course_all_members_count = @exercise_users_list.size + end + @exercise_commit_users = @exercise_all_users.commit_exercise_by_status(1) #试卷的已提交用户 + @exercise_commit_user_ids = @exercise_commit_users.pluck(:user_id).uniq #已提交试卷的全部用户id + @exercise_commit_user_counts = @exercise_commit_users.size #试卷的已提交用户人数 + @exercise_status = @exercise.get_exercise_status(current_user) + + #提交率 + if @course_all_members_count == 0 + commit_percent = 0.00 + min_score = 0.0 + max_score = 0.0 + average_score = 0.0 + fail_counts = 0 + pass_counts = 0 + good_counts = 0 + best_counts = 0 + else + commit_percent = (@exercise_commit_user_counts / @course_all_members_count.to_f).round(3) + exercise_scores = @exercise_commit_users.pluck(:score).reject(&:blank?) + min_score = exercise_scores.min.present? ? exercise_scores.min : 0.0 + max_score = exercise_scores.max.present? ? exercise_scores.max : 0.0 + total_score = exercise_scores.sum.present? ? exercise_scores.sum : 0.0 + average_score = @exercise_commit_user_counts > 0 ? (total_score.round(1) / @exercise_commit_user_counts).round(1) : 0.0 + question_scores = @exercise.question_scores + fail_score = question_scores * 0.6.round(2) + pass_score = question_scores * 0.7.round(2) + good_score = question_scores * 0.9.round(2) + + fail_counts = exercise_scores.count {|a| a < fail_score} + pass_counts = exercise_scores.count {|a| a < pass_score && a >= fail_score} + good_counts = exercise_scores.count {|a| a < good_score && a >= pass_score} + best_counts = exercise_scores.count {|a| a >= good_score && a <= question_scores} + end + @counts_array = { + :commit_percent => commit_percent, + :min_score => min_score.to_s, + :max_score => max_score.to_s, + :average_score => average_score.to_s, + :fail_counts => fail_counts, + :pass_counts => pass_counts, + :good_counts => good_counts, + :best_counts => best_counts, + } + + @exercise_questions = @exercise.exercise_questions&.includes(:exercise_choices, :exercise_answers, :exercise_standard_answers, :exercise_shixun_challenges, :exercise_shixun_answers) + + percent_sort = "desc" + + if params[:sort].present? + percent_sort = params[:sort] + end + # @paging_type = "percent" + # # 按题型排序 + # if params[:sort].present? + # @paging_type = params[:sort].to_s + # end + + ques_result_all = exercise_commit_result(@exercise_questions, @exercise_commit_user_ids) + + #默认降序排列 + if percent_sort == "desc" + @question_result_hash = ques_result_all.sort_by {|s| s[:percent]}.reverse + else + @question_result_hash = ques_result_all.sort_by {|s| s[:percent]} + end + class ExercisesController < ApplicationController + before_action :require_login, :check_auth, except: [:index] + before_action :find_course, only: [:index, :new, :create, :my_exercises, :public_exercises, :set_public, :destroys, + :join_exercise_banks, :publish_modal, :publish, :end_modal, :end_exercise] #需要有课堂id参数的 + before_action :get_exercise, except: [:index, :new, :create, :my_exercises, :public_exercises, :set_public, :destroys, + :join_exercise_banks, :publish_modal, :publish, :end_modal, :end_exercise] + before_action :user_course_identity + before_action :is_course_teacher, except: [:index, :start_answer, :exercise_setting, :commit_exercise, :exercise_lists, :review_exercise, + :exercise_result, :common_header, :cancel_exercise, :begin_commit] + before_action :get_left_banner_id, only: [:common_header, :start_answer, :review_exercise, :index, :new, :edit] + before_action :validates_exercise_params, only: [:create, :update] + before_action :get_exercise_question_counts, only: [:show, :edit, :start_answer, :review_exercise, :blank_exercise, :export_exercise] + before_action :validate_publish_time, only: [:commit_setting] #提交设置时,需判断时间是否符合 + before_action :check_course_public, only: [:set_public] + before_action :check_user_on_answer, only: [:show, :start_answer, :exercise_lists] #判断当前用户在试卷的权限/老师是否属于分班的权限 + before_action :only_student_in, only: [:start_answer] + before_action :check_user_id_start_answer, only: [:start_answer, :review_exercise] + # before_action :commit_user_exercise,only: [:start_answer,:exercise_lists,:review_exercise] #已有定时的任务 + before_action :check_exercise_time, only: [:commit_exercise] #提交试卷时,判断时间是否超过 + before_action :check_exercise_status, only: [:redo_modal, :redo_exercise] + before_action :check_exercise_is_end, only: [:review_exercise] + before_action :check_exercise_public, only: [:exercise_result] #试卷是否为公开 + before_action :commit_shixun_present, only: [:commit_shixun] + include ExportHelper + include ExercisesHelper + + # model validation error + rescue_from ActiveRecord::RecordInvalid do |ex| + render_error(ex.record.errors.full_messages.join(',')) + end + # form validation error + rescue_from ActiveModel::ValidationError do |ex| + render_error(ex.model.errors.full_messages.join(',')) + end + + def index + begin + # 按发布时间或创建时间排序 + @exercises_all = @course.exercises + member_show_exercises = @exercises_all.is_exercise_published #已发布的或已截止的试卷 + @current_user_ = current_user + + # 课堂的学生人数 + @course_all_members = @course.students #当前课堂的全部学生 + @current_student = @course_all_members.course_find_by_ids("user_id", current_user.id) #当前用户是否为课堂的学生 + + # exercises的不同用户群体的显示 + if @user_course_identity < Course::STUDENT # @is_teacher_or 1为老师/管理员/助教 + @is_teacher_or = 1 + @exercises = @exercises_all #老师能看到全部的试卷,不管是已发布的/未发布的/已截止的/统一设置的/私有设置的(看到内容不同) + elsif @user_course_identity == Course::STUDENT # 2为课堂成员,能看到统一设置的和自己班级的 + @is_teacher_or = 2 + @member_group_id = @current_student.first.try(:course_group_id).to_i # 成员的分班id,默认为0 + if @member_group_id == 0 #表示是课堂的未分班成员,只能查看统一设置的试卷(已发布的/已截止的) + @exercises = member_show_exercises.exists? ? member_show_exercises.unified_setting : [] + else #已分班级的成员,可以查看统一设置和单独设置(试卷是发布在该班级)试卷 + # 已发布 当前用户班级分组的 试卷id + publish_exercise_ids = @course.exercise_group_settings.exercise_group_published.where("course_group_id = #{@member_group_id}").pluck(:exercise_id) + @exercises = member_show_exercises.unified_setting.or(member_show_exercises.where(id: publish_exercise_ids)) + end + else #用户未登陆或不是该课堂成员,仅显示统一设置的(已发布的/已截止的),如有公开,则不显示锁,不公开,则显示锁 + @is_teacher_or = 0 + @exercises = member_show_exercises.unified_setting + end + + if @exercises.size > 0 + if params[:type].present? + choose_type = params[:type].to_i + ex_setting_ids = [] + if @is_teacher_or != 2 + @exercises = @exercises.where("exercise_status = #{choose_type}") + else + case choose_type + when 1 + ex_setting_ids = @course.exercise_group_settings.where("course_group_id = #{@member_group_id}").exercise_group_not_published.pluck(:exercise_id) + when 2 + ex_setting_ids = @course.exercise_group_settings.where("course_group_id = #{@member_group_id}") + .where("publish_time is not null and publish_time <= ? and end_time > ?", Time.now, Time.now).pluck(:exercise_id) + when 3 + ex_setting_ids = @course.exercise_group_settings.where("course_group_id = #{@member_group_id}").exercise_group_ended.pluck(:exercise_id) + end + unified_setting_ids = @exercises.unified_setting.where("exercise_status = #{choose_type}").pluck(:id) + ex_ids = (ex_setting_ids + unified_setting_ids).uniq + @exercises = @exercises.where(id: ex_ids) end + end + + if params[:search].present? + search_type = params[:search].to_s.strip + @exercises = @exercises.exercise_search(search_type) + end + + @exercises_select_count = @exercises.size # 全部页面,需返回 + @exercises = @exercises.distinct.order("IF(ISNULL(publish_time),0,1), publish_time DESC,created_at DESC") #出现错误 + + # 分页 + @page = params[:page] || 1 + @limit = params[:limit] || 15 + @exercises = @exercises.page(@page).per(@limit) + @exercises = @exercises&.includes(:published_settings) + else + @exercises = [] + end + + @course_all_members_count = @course_all_members.size #当前课堂的学生数 + @exercises_count = @exercises_all.size # 全部页面,需返回 + @exercises_unpublish_counts = @exercises_all.exercise_by_status(1).size #未发布的试卷数 + @exercises_published_counts = @exercises_count - @exercises_unpublish_counts # 已发布的试卷数,包含已截止的 + + rescue Exception => e + uid_logger_error(e.message) + tip_exception(e.message) + raise ActiveRecord::Rollback + end + end + + def new + ActiveRecord::Base.transaction do + begin + @exercise = Exercise.new + rescue Exception => e + uid_logger_error(e.message) + tip_exception("试卷创建失败!") + raise ActiveRecord::Rollback + end + end + end + + def create + ActiveRecord::Base.transaction do + ex_name = params[:exercise_name] + ex_desc = params[:exercise_description] + exercise_options = { + :exercise_name => ex_name, + :exercise_description => ex_desc, + :user_id => current_user.id, + :course_id => @course.id, + :time => -1, + :exercise_status => 1 + } + @exercise = Exercise.create!(exercise_options) + end + end + + #试卷的内容,及试题/答案的内容编辑 + def edit + ActiveRecord::Base.transaction do + @exercise_questions = @exercise.exercise_questions.order("question_number ASC") + end + end + + def update + ActiveRecord::Base.transaction do + ex_name = params[:exercise_name] + ex_desc = params[:exercise_description] + exercise_options = { + :exercise_name => ex_name, + :exercise_description => ex_desc, + } + @exercise.update!(exercise_options) + normal_status(0, "试卷更新成功!") + end + end + + def show + ActiveRecord::Base.transaction do + if @user_course_identity < Course::STUDENT + @is_teacher_or = 1 #为老师/助教/管理员 + else + @is_teacher_or = 0 #为学生 + end + @exercise_questions = @exercise.exercise_questions&.includes(:exercise_choices, :exercise_shixun_challenges, :exercise_standard_answers).order("question_number ASC") + end + end + + #试卷的公用头部 + def common_header + ActiveRecord::Base.transaction do + @user_left_time = nil + if @user_course_identity > Course::ASSISTANT_PROFESSOR + @is_teacher_or = 0 + @user_exercise_answer = @exercise.check_user_answer_status(current_user) + @user_commit_counts = 0 + @user_left_time = get_exercise_left_time(@exercise, current_user) + else + @is_teacher_or = 1 + @user_exercise_answer = 3 #教师页面 + @user_commit_counts = @exercise.exercise_users.where(commit_status: 1).size #已提交的用户数 + end + @ex_status = @exercise.get_exercise_status(current_user) + + exercise_id_array = [@exercise.id] + @exercise_publish_count = get_user_permission_course(exercise_id_array, Exercise::PUBLISHED).size #是否存在已发布的 + @exercise_unpublish_count = get_user_permission_course(exercise_id_array, Exercise::UNPUBLISHED).size #是否存在未发布的 + + if (@exercise_publish_count == 0) && (@exercise_unpublish_count == 0) #即表示没有分班 + if @ex_status == Exercise::UNPUBLISHED + @exercise_unpublish_count = 1 #试卷未发布,且课堂没有分班的时候 + elsif @ex_status == Exercise::PUBLISHED + @exercise_publish_count = 1 #试卷未发布,且课堂没有分班的时候 + end + end + end + end + + #实训题目的选用 + def choose_shixun + ActiveRecord::Base.transaction do + search = params[:search] + if @user_course_identity > Course::ADMIN #当不为管理员的时候 + user_school_id = current_user.school_id #当前用户的学校id + if user_school_id.present? + none_shixun_ids = ShixunSchool.where("school_id != #{user_school_id}").pluck(:shixun_id) + @publish_shixuns = Shixun.where.not(id: none_shixun_ids).unhidden + end + else + @publish_shixuns = Shixun.unhidden + end + if search.present? + @publish_shixuns = @publish_shixuns.search_by_name(search) + end + + @shixuns = @publish_shixuns.joins(:challenges).where("challenges.st != 0").distinct + # 全部页面,需返回 + @shixuns_count = @shixuns.count + + # 分页 + @page = params[:page] || 1 + @limit = params[:limit] || 8 + + @shixuns = @shixuns.page(@page).per(@limit) + end + end + + #确认实训的选择 + def commit_shixun + ActiveRecord::Base.transaction do + @shixun_challenges = @shixun.challenges + @shixun_challenges_count = @shixun_challenges.size + end + end + + # 首页批量或单独删除 + def destroys + ActiveRecord::Base.transaction do + check_ids = Exercise.where(id: params[:check_ids]) + check_ids.destroy_all + normal_status(0, "试卷已删除成功!") + end + end + + # 设为公开 + def set_public + ActiveRecord::Base.transaction do + check_ids = Exercise.where(id: params[:check_ids]) + check_ids.each do |exercise| + exercise.update!(is_public: true) + end + normal_status(0, "试卷已设为公开!") + end + end + + ## 加入题库 + def join_exercise_banks + ActiveRecord::Base.transaction do + check_ids = Exercise.where(id: params[:check_ids]) + check_ids.each do |exercise| + current_ex_bank = current_user.exercise_banks.find_by_container(exercise.id, "Exercise")&.first + if current_ex_bank.present? #当前用户的选择试卷是否已加入习题库,存在则更新习题库和问题库,否则新建习题库和问题库 + ex_params = { + :name => exercise.exercise_name, + :description => exercise.exercise_description, + :course_list_id => exercise.course.try(:course_list_id) + } + current_ex_bank.update!(ex_params) + # question_bank = QuestionBank.ques_by_container(current_ex_bank.id,current_ex_bank.container_type).first #该习题库是否存在于问题库里 + # ques_params = { + # :name => current_ex_bank.name, + # :course_list_id => current_ex_bank.course_list_id + # } + # question_bank.update_attributes(ques_params) if question_bank.present? + current_ex_bank.exercise_bank_questions.destroy_all # 更新后,习题库的问题全部删除,后续重新再建 + else + ex_params = { + :name => exercise.exercise_name, + :description => exercise.exercise_description, + :user_id => current_user.id, + :is_public => 0, + :course_list_id => exercise.course.try(:course_list_id), + :container_id => exercise.id, + :container_type => "Exercise", + :quotes => 1 + } + current_ex_bank = ExerciseBank.new ex_params + current_ex_bank.save! #如果习题库保存成功,则会创建问题库question_bank + # if current_ex_bank.save + # ques_params = { + # :name => current_ex_bank.name, + # :container_id => current_ex_bank.id, + # :container_type => current_ex_bank.container_type, + # :quotes => current_ex_bank.quotes, + # :user_id => current_ex_bank.user_id, + # :is_public => current_ex_bank.is_public, + # :course_list_id => current_ex_bank.course_list_id + # } + # question_bank = QuestionBank.new ques_params + # question_bank.save + # end + exercise.update!(exercise_bank_id: current_ex_bank.id) + end + # 试卷的问题的输入 + exercise.exercise_questions.each do |q| + option = { + :question_title => q.question_title, + :question_type => q.question_type, + :question_number => q.question_number, + :question_score => q.question_score, + :shixun_id => q.shixun_id, + :shixun_name => q.shixun_name + } + exercise_bank_question = current_ex_bank.exercise_bank_questions.new option + exercise_bank_question.save! + ## 试卷选项的输入 + if q.question_type != Exercise::PRACTICAL #不为实训题时,试卷选项加入试题答案库 + ex_choices = q.exercise_choices + ex_standard = q.exercise_standard_answers + ex_choices.each do |c| + choice_option = { + :choice_position => c.choice_position, + :choice_text => c.choice_text + } + ex_bank_choice = exercise_bank_question.exercise_bank_choices.new choice_option + ex_bank_choice.save! + end + ex_standard.each do |s| + ex_stand = { + :exercise_bank_choice_id => s.exercise_choice_id, + :answer_text => s.answer_text + } + ex_stand_bank = exercise_bank_question.exercise_bank_standard_answers.new ex_stand + ex_stand_bank.save! + end + else #当为实训题时 + shixun_challenges = q.exercise_shixun_challenges + shixun_challenges.each do |c| + challenge_option = { + :position => c.position, + :challenge_id => c.challenge_id, + :shixun_id => q.shixun_id, + :question_score => c.question_score + } + shixun_challenge_bank = exercise_bank_question.exercise_bank_shixun_challenges.new challenge_option + shixun_challenge_bank.save! + end + end + end + current_ex_bank.save! + end + normal_status(0, "题库更新成功!") + end + end + + #试卷的设置页面 + def exercise_setting + ActiveRecord::Base.transaction do + @user_permission = 2 + @user_course_groups = @course.teacher_group(current_user.id) #当前老师的分班 + @being_setting_course_ids = @exercise.common_published_ids(current_user.id) #当前用户已发布的班级的id + @user_published_setting = @exercise.exercise_group_settings + .find_in_exercise_group("course_group_id", @being_setting_course_ids) #当前用户已发布班级的试卷设置 + exercise_ids = [@exercise.id] + @exercise_publish_count = get_user_permission_course(exercise_ids, Exercise::PUBLISHED).count #判断当前用户是否有试卷已发布的分班,用于显示立即截止/撤销发布 + @exercise_unpublish_count = get_user_permission_course(exercise_ids, Exercise::UNPUBLISHED).count #判断当前用户是否有试卷未发布的分班,用户显示立即发布 + @exercise_users_count = @exercise.exercise_users.commit_exercise_by_status(1).count #判断当前试卷是否有已提交的 + # ## 需添加发送消息的接口,稍后添加 + end + end + + #试卷的提交设置 + def commit_setting + ActiveRecord::Base.transaction do + error_count = 0 # 判断循环里是否有已发布/已截止的,且时间更改了的分班。 + # course_group_ids = @course.teacher_course_group_ids(current_user.id) #当前老师的班级id数组 + course_group_ids = @course.charge_group_ids(current_user) #当前老师的班级id数组 + + exercise_status = @exercise.get_exercise_status(current_user) + + if exercise_status == Exercise::UNPUBLISHED && course_group_ids.size > 0 # 试卷未发布,且老师的分班大于1 ,才可以修改统一设置,否则按试卷默认的来处理 + unified_setting = params[:unified_setting] + else + unified_setting = @exercise.unified_setting + end + + show_statistic = params[:show_statistic] ? true : false + exercise_time = params[:time].blank? ? -1 : params[:time] + question_random = params[:question_random] ? true : false #问题是否随机,0为不随机,1为随机 + choice_random = params[:choice_random] ? true : false + score_open = params[:score_open] ? true : false #分数是否公开 + answer_open = params[:answer_open] ? true : false #答案是否公开 + + # 统一设置或者分班为0,则更新试卷,并删除试卷分组 + if unified_setting || (course_group_ids.size == 0) + tip_exception("发布时间不能为空") if params[:publish_time].blank? + tip_exception("截止时间不能为空") if params[:end_time].blank? + tip_exception("截止时间不能早于发布时间") if params[:publish_time].to_time > params[:end_time].to_time + tip_exception("截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")})") if @course.end_date.present? && params[:end_time].to_time > @course.end_date.end_of_day + + params_publish_time = params[:publish_time].to_time + params_end_time = params[:end_time].to_time + + if (exercise_status != Exercise::UNPUBLISHED) && (@exercise.publish_time != params_publish_time) + normal_status(-1, "已发布/已截止,不允许修改发布时间") + elsif params_publish_time.present? && params_end_time.present? && params_end_time < params_publish_time + normal_status(-1, "截止时间不能小于发布时间") + else + #发布时间小于当前时间,则试卷显示为未发布,当截止时间大于当前时间,则显示为已截止 + exercise_status_n = set_exercise_status(params_publish_time, params_end_time) + exercise_params = { + :unified_setting => unified_setting, + :show_statistic => show_statistic, + :time => exercise_time, + :question_random => question_random, + :choice_random => choice_random, + :score_open => score_open, + :answer_open => answer_open, + :exercise_status => exercise_status_n, + :publish_time => params_publish_time, + :end_time => params_end_time + } + @exercise.update!(exercise_params) + @exercise.exercise_group_settings.destroy_all + normal_status(0, "试卷设置成功!") + end + else + params_times = params[:publish_time_groups] #分班返回的json数组{"publish_time_groups":[{"course_group_id":"1","publish_time":"xx","end_time":"xxx"}]} + exercise_groups = @exercise.exercise_group_settings.find_in_exercise_group("course_id", @course.id) #试卷的全部分班信息 + exercise_groups_ids = exercise_groups.pluck(:course_group_id) #问卷的全部分班id + total_common = params_times.map {|k| k[:course_group_id]}.sum.uniq #传入的所有分组的分班id + total_common_group = exercise_groups_ids & total_common #传入的分班与问卷已存在的分班的交集 + old_exercise_groups = exercise_groups_ids - total_common_group #后来传入的分班里,没有了的班级,即需要删除 + + params_times.each do |t| + tip_exception("发布时间不能为空") if t[:publish_time].blank? + tip_exception("截止时间不能为空") if t[:end_time].blank? + tip_exception("截止时间不能早于发布时间") if t[:publish_time].to_time > t[:end_time].to_time + tip_exception("截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")})") if @course.end_date.present? && t[:end_time].to_time > @course.end_date.end_of_day + + course_id = t[:course_group_id] + exercise_publish_time = t[:publish_time].to_time + exercise_end_time = t[:end_time].to_time + + exercise_group = exercise_groups.find_in_exercise_group("course_group_id", course_id) #判断该分班是否存在 + if exercise_group.present? && (exercise_group.first.publish_time < Time.now) && (exercise_publish_time != exercise_group.first.publish_time) + error_count += 1 + end + if exercise_group.present? && (exercise_group.first.publish_time < Time.now && exercise_group.first.end_time > Time.now) && (exercise_end_time < Time.now) + error_count += 1 + end + if error_count == 0 + common_group = exercise_groups_ids & course_id #传入的班级与问卷已存在的班级的交集,即表示已有分班的 + new_group_ids = course_id - common_group #新传入的班级id + if common_group.count > 0 #判断试卷的分班设置是否存在,存在则更新,负责则新建 + exercise_group_sets = exercise_groups.find_in_exercise_group("course_group_id", common_group) + exercise_group_sets.each do |the_group_setting| + ex_group_params = { + :publish_time => exercise_publish_time, + :end_time => exercise_end_time + } + + the_group_setting_status = set_exercise_status(the_group_setting.publish_time, the_group_setting.end_time) + if the_group_setting_status == 2 + ex_group_params = { + :publish_time => the_group_setting.publish_time, + :end_time => exercise_end_time < Time.now ? the_group_setting.end_time : exercise_end_time + } + elsif the_group_setting_status == 3 + ex_group_params = { + :publish_time => the_group_setting.publish_time, + :end_time => exercise_end_time + } + end + the_group_setting.update!(ex_group_params) + end + end + if new_group_ids.size > 0 + new_group_ids.each do |c| + exercise_group_params = { + :exercise_id => @exercise.id, + :course_group_id => c, + :course_id => @course.id, + :publish_time => exercise_publish_time, + :end_time => exercise_end_time + } + new_exercise_group = ExerciseGroupSetting.new(exercise_group_params) + new_exercise_group.save! + end + end + end + end + + if error_count > 0 + error_count == 0 + normal_status(-1, "试卷发布/截止时间不能小于当前时间") + else + # 未发布的分班设置才能删除 + if old_exercise_groups.size > 0 + old_all_ex_groups = exercise_groups.find_in_exercise_group("course_group_id", old_exercise_groups).exercise_group_not_published + old_all_ex_groups.destroy_all + end + #试卷更新为exercise_group_setting的发布时间最小,截止时间最大 + e_time_present = exercise_groups.end_time_no_null.map(&:end_time) + p_time_present = exercise_groups.publish_time_no_null.map(&:publish_time) + e_time = e_time_present.size > 0 ? e_time_present.max : nil + p_time = p_time_present.size > 0 ? p_time_present.min : nil + exercise_status = 1 + if p_time.nil? #发布时间为空,则表示问卷未发布 + exercise_status = 1 + elsif p_time.present? && e_time.present? + exercise_status = set_exercise_status(p_time, e_time) + end + exercise_params = { + :unified_setting => unified_setting, + :show_statistic => show_statistic, + :time => exercise_time, + :question_random => question_random, + :choice_random => choice_random, + :score_open => score_open, + :answer_open => answer_open, + :exercise_status => exercise_status, + :publish_time => p_time, + :end_time => e_time + } + @exercise.update!(exercise_params) + if @exercise.exercise_status == Exercise::PUBLISHED + if @exercise.course_acts.size == 0 + @exercise.course_acts << CourseActivity.new(:user_id => @exercise.user_id, :course_id => @exercise.course_id) + end + end + normal_status(0, "试卷设置成功!") + end + end + end + end + + # 对未提交的用户进行调分 + def adjust_score + exercise_user = @exercise.exercise_users.find_by!(user_id: params[:user_id]) + tip_exception("已提交的作品请去评阅页进行调分") if exercise_user.commit_status == 1 && exercise_user.commit_method != 5 + if @exercise.subjective_score > 0 + tip_exception("主观题成绩不能为空") if params[:subjective_score].blank? + tip_exception("主观题成绩不能小于零") if params[:subjective_score].to_f < 0 + tip_exception("主观题成绩不能大于总分值:#{@exercise.subjective_score}分") if params[:subjective_score].to_f.round(1) > @exercise.subjective_score.round(1) + end + + if @exercise.objective_score > 0 + tip_exception("客观题成绩不能为空") if params[:objective_score].blank? + tip_exception("客观题成绩不能小于零") if params[:objective_score].to_f < 0 + tip_exception("客观题成绩不能大于总分值:#{@exercise.objective_score}分") if params[:objective_score].to_f.round(1) > @exercise.objective_score.round(1) + end + + ActiveRecord::Base.transaction do + start_at_time = exercise_user.start_at || Time.now + subjective_score = @exercise.subjective_score > 0 ? params[:subjective_score].to_f.round(2) : 0 + objective_score = @exercise.objective_score > 0 ? params[:objective_score].to_f.round(2) : 0 + score = subjective_score + objective_score + if exercise_user.commit_status == 1 + exercise_user.update!(score: score, subjective_score: subjective_score, objective_score: objective_score) + else + exercise_user.update!(start_at: start_at_time, end_at: Time.now, status: 1, commit_status: 1, score: score, + subjective_score: subjective_score, objective_score: objective_score, commit_method: 5) + end + + ExerciseUserScore.create!(exercise_id: @exercise.id, exercise_user_id: exercise_user.id, + subjective_score: subjective_score, objective_score: objective_score) + normal_status("操作成功") + end + end + + #我的题库 + def my_exercises + ActiveRecord::Base.transaction do + ## 我的试卷题库 + @current_user_exercises = current_user.exercise_banks.find_by_c_type("Exercise") + if @current_user_exercises.present? + + if params[:search].present? + search_type = params[:search].to_s.strip + @current_user_exercises = @current_user_exercises.exercise_bank_search(search_type) + end + page = params[:page] || 1 + limit = params[:limit] || 15 + @my_exercises_count = @current_user_exercises.size + @current_user_exercises = @current_user_exercises.page(page).per(limit) + else + @current_user_exercises = [] + end + end + end + + # 公共题库 + def public_exercises + ActiveRecord::Base.transaction do + if current_user.is_certification_teacher + @user_certification = 1 #用户已通过认证 + @public_exercises = ExerciseBank.find_by_c_type("Exercise").public_exercises + if @public_exercises.present? + if params[:search].present? + search_type = params[:search].to_s.strip + @public_exercises = @public_exercises.exercise_bank_search(search_type) + end + page = params[:page] || 1 + limit = params[:limit] || 15 + @public_exercises_count = @public_exercises.size + @public_exercises = @public_exercises.page(page).per(limit) + else + @public_exercises_count = 0 + @public_exercises = [] + end + else + @user_certification = 0 #用户未通过认证 + @public_exercises_count = 0 + @public_exercises = [] + end + end + end + + #立即发布的弹窗内容 + def publish_modal + + ActiveRecord::Base.transaction do + exercise_ids = params[:check_ids] + if exercise_ids.count > 0 + @course_groups = get_user_permission_course(exercise_ids, 1) + else + @course_groups = [] + end + end + end + + # 详情页的立即发布弹框 + def publish_groups + @current_user = current_user + # 可立即发布的分班:当前用户管理的分班去除已发布的分班 + group_ids = @course.charge_group_ids(@current_user) - @exercise.exercise_group_settings.exercise_group_published.pluck(:course_group_id) + @course_groups = @course.course_groups.where(id: group_ids) + @group_settings = @exercise.exercise_group_settings.where(course_group_id: group_ids) + end + + #首页批量或单独 立即发布,应是跳出弹窗,设置开始时间和截止时间。 + def publish + group_ids = params[:group_ids]&.reject(&:blank?) + if params[:detail].blank? + tip_exception("缺少截止时间参数") if params[:end_time].blank? + tip_exception("截止时间不能早于当前时间") if params[:end_time] <= strf_time(Time.now) + tip_exception("截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")})") if @course.end_date.present? && params[:end_time] > strf_time(@course.end_date.end_of_day) + else + group_end_times = params[:group_end_times].reject(&:blank?).map {|time| time.to_time} + tip_exception("缺少截止时间参数") if group_end_times.blank? + tip_exception("截止时间和分班参数的个数不一致") if group_end_times.length != group_ids.length + group_end_times.each do |time| + tip_exception("分班截止时间不能早于当前时间") if time <= Time.now + tip_exception("分班截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")})") if @course.end_date.present? && time > @course.end_date.end_of_day + end + end + + ActiveRecord::Base.transaction do + check_ids = Exercise.where(id: params[:check_ids]) + ex_end_time = params[:end_time].blank? ? Time.at(((1.month.since.to_i) / 3600.0).ceil * 3600) : params[:end_time].to_time + check_ids.each do |exercise| + if exercise.present? + if exercise.unified_setting + ex_status = exercise.exercise_status #则为试卷的状态 + else + ex_status = @course.course_groups.where(id: params[:group_ids]).size != + exercise.exercise_group_settings.where(course_group_id: params[:group_ids]).exercise_group_published.size ? 1 : 0 + end + if ex_status == 1 #如果试卷存在已发布的,或者是已截止的,那么则直接跳过 + g_course = group_ids #表示是否传入分班参数,如果传入分班的参数,那么试卷的统一设置需修改 + tiding_group_ids = g_course + if g_course + user_course_groups = @course.course_groups.pluck(:id) + if g_course.map(&:to_i).sort == user_course_groups.sort && + ((params[:detail] && group_end_times.min == group_end_times.max) || params[:detail].blank?) # 如果是设置为全部班级,则试卷不用分组,且试卷设定为统一设置,否则则分组设置 + exercise.exercise_group_settings.destroy_all + ex_unified = true + e_time = params[:detail] ? group_end_times.max : ex_end_time + tiding_group_ids = [] + else + ex_unified = false + g_course.each_with_index do |i, index| + exercise_group_setting = exercise.exercise_group_settings.find_in_exercise_group("course_group_id", i).first #根据课堂分班的id,寻找试卷所在的班级 + group_end_time = params[:detail] ? group_end_times[index] : ex_end_time + if exercise_group_setting.present? #如果该试卷分组存在,则更新,否则新建 + exercise_group_setting.update!(publish_time: Time.now, end_time: group_end_time) + else + p_course_group = { + :exercise_id => exercise.id, + :course_group_id => i, + :course_id => exercise.course.id, + :publish_time => Time.now, + :end_time => group_end_time, + } + new_exercise_group = exercise.exercise_group_settings.new p_course_group + new_exercise_group.save! + end + end + # group_ids = params[:group_ids] + e_time = exercise.exercise_group_settings.end_time_no_null.map(&:end_time).max + end + else + exercise.exercise_group_settings.destroy_all + ex_unified = true + e_time = ex_end_time + end + + ex_status = set_exercise_status(Time.now, e_time) + exercise_params = { + :publish_time => Time.now, + :end_time => e_time, + :exercise_status => ex_status, + :unified_setting => ex_unified + } + exercise.update!(exercise_params) + + if exercise.course_acts.size == 0 + exercise.course_acts << CourseActivity.new(:user_id => exercise.user_id, :course_id => exercise.course_id) + end + ExercisePublishNotifyJob.perform_later(exercise.id, tiding_group_ids) + end + end + end + normal_status(0, "试卷发布成功!") + end + end + + #立即截止的弹窗内容 + def end_modal + ActiveRecord::Base.transaction do + exercise_ids = params[:check_ids] + if exercise_ids.count > 0 + @course_groups = get_user_permission_course(exercise_ids, 3) + else + @course_groups = [] + end + end + end + + # 首页批量或单独 立即截止,截止时间为当前时间 + def end_exercise + + ActiveRecord::Base.transaction do + check_ids = Exercise.where(id: params[:check_ids]) + course_students = @course.students #课堂的全部学生数 + check_ids.each do |exercise| + exercise_status = exercise.get_exercise_status(current_user) + if exercise_status == Exercise::PUBLISHED #跳过已截止的或未发布的 + g_course = params[:group_ids] + if g_course.present? + teacher_course_group_ids = @course.charge_group_ids(current_user) + all_course_group_ids = @course.course_groups.pluck(:id) + if exercise.unified_setting && g_course.map(&:to_i).sort == all_course_group_ids.sort #开始为统一设置 + exercise.exercise_group_settings.destroy_all + new_ex_status = set_exercise_status(exercise.publish_time, Time.now) + exercise.update!(:end_time => Time.now, :exercise_status => new_ex_status) + exercise_users = exercise.exercise_users + else + course_members_ids = course_students.course_find_by_ids("course_group_id", g_course).pluck(:user_id).uniq #该班级的全部学生 + exercise_users = exercise.exercise_users.exercise_commit_users(course_members_ids) #参与答题的学生数 + ex_group_setting = exercise.exercise_group_settings + old_exercise_groups = ex_group_setting.find_in_exercise_group("course_group_id", g_course) #试卷的分组设置 + left_course_groups = teacher_course_group_ids - g_course + left_exercise_groups = ex_group_setting.find_in_exercise_group("course_group_id", left_course_groups) + if left_exercise_groups.blank? && exercise.unified_setting + if left_course_groups.size > 0 #开始为统一设置,但是立即截止为分班。则创建没有立即截止的班级的exercise_group_setting + left_course_groups.each do |g| + ex_group_options = { + :exercise_id => exercise.id, + :course_group_id => g, + :course_id => @course.id, + :publish_time => exercise.publish_time, + :end_time => exercise.end_time + } + ExerciseGroupSetting.create!(ex_group_options) + end + end + end + if old_exercise_groups.present? + old_exercise_groups.update_all(:end_time => Time.now) + else + g_course.each do |g| + ex_group_options = { + :exercise_id => exercise.id, + :course_group_id => g, + :course_id => @course.id, + :publish_time => exercise.publish_time, + :end_time => Time.now + } + ExerciseGroupSetting.create!(ex_group_options) + end + end + new_end_time = exercise.exercise_group_settings.end_time_no_null.map(&:end_time) # 试卷结束时间不为空的 + new_end_time_s = new_end_time.count > 0 ? new_end_time.max : Time.now + new_ex_status = set_exercise_status(exercise.publish_time, new_end_time_s) + exercise.update!(:end_time => new_end_time_s, :exercise_status => new_ex_status, :unified_setting => false) + end + else + exercise_users = exercise.exercise_users + exercise.update!(:exercise_status => 3, :end_time => Time.now, :unified_setting => true) + end + + ex_user_ids = exercise_users.pluck(:id) + + EndExerciseCalculateJob.perform_later(ex_user_ids, exercise, Time.now.to_s) + # exercise_users.each do |user| + # if user.commit_status == 0 && user.start_at.present? + # objective_score = calculate_student_score(exercise,user.user)[:total_score] + # user_sub_score = user.subjective_score + # subjective_score = user_sub_score < 0.0 ? 0.0 : user_sub_score + # total_score = objective_score + subjective_score + # commit_option = { + # :status => 1, + # :commit_status => 1, + # :end_at => Time.now, + # :objective_score => objective_score, + # :score => total_score, + # :subjective_score => user_sub_score + # } + # user.update_attributes(commit_option) + # end + # end + end + end + normal_status(0, "试卷截止成功!") + end + end + + #学生撤销回答 + def cancel_exercise + ActiveRecord::Base.transaction do + ex_question_ids = @exercise.exercise_questions.pluck(:id) + exercise_user = @exercise.exercise_users.exercise_commit_users(current_user.id).first + if exercise_user.present? + if exercise_user.commit_status == 1 && @exercise.get_exercise_status(current_user) == Exercise::PUBLISHED #用户已提交且试卷提交中 + if @exercise.time == -1 || ((Time.now.to_i - exercise_user.start_at.to_i) < @exercise.time.to_i * 60) + exercise_user.update!(:score => nil, :end_at => nil, :status => nil, :commit_status => 0, + :objective_score => 0.0, :subjective_score => -1.0) + exercise_user.user.exercise_shixun_answers.search_shixun_answers("exercise_question_id", ex_question_ids).destroy_all + exercise_answers = exercise_user.user.exercise_answers.search_answer_users("exercise_question_id", ex_question_ids) + exercise_answers.update_all(:score => -1.0) + all_answer_comment = ExerciseAnswerComment.search_answer_comments("exercise_question_id", ex_question_ids) + .search_answer_comments("exercise_answer_id", exercise_answers.pluck(:id)) + all_answer_comment.destroy_all + normal_status(0, "撤销回答成功") + else + normal_status(-1, "用户答题时间已到") + end + else + normal_status(-1, "用户未提交/试卷不是提交中") + end + else + normal_status(-1, "当前用户未答题") + end + end + end + + #打回重做modal + def redo_modal + ActiveRecord::Base.transaction do + #搜索 + if params[:realname].present? + search_name = params[:realname] + #搜索用户的nickname,如果存在则返回,否则继续查询用户的真实姓名或学生号 + @exercise_users = @exercise_users.includes(:user).where("LOWER(concat(users.lastname, users.firstname)) like ?", + "%#{search_name}%") + end + if params[:student_id].present? + search_st_id = params[:student_id].to_i + @exercise_users = @exercise_users.includes(user: [:user_extension]) + .where('user_extensions.student_id like ?', "%#{search_st_id}%") + end + sort = params[:sort] ? params[:sort] : "asc" + @exercise_users = @exercise_users.order("score #{sort}") + @exercise_users_size = @exercise_users.size + # 分页 + page = params[:page] || 1 + limit = params[:limit] || 15 + @exercise_users = @exercise_users.page(page).per(limit) + end + end + + #打回重做确认 + def redo_exercise + ActiveRecord::Base.transaction do + user_ids = params[:user_ids] + if user_ids.present? + redo_option = { + :score => 0.0, + :start_at => nil, + :end_at => nil, + :status => nil, + :commit_status => 0, + :objective_score => 0.0, + :subjective_score => -1.0, + :commit_method => 0 + } + redo_exercise_users = @exercise_users.exercise_commit_users(user_ids) + redo_exercise_users.update_all(redo_option) + exercise_question_ids = @exercise.exercise_questions.pluck(:id).uniq + ExerciseAnswer.search_answer_users("user_id", user_ids) + .search_answer_users("exercise_question_id", exercise_question_ids).destroy_all + ExerciseShixunAnswer.search_shixun_answers("user_id", user_ids) + .search_shixun_answers("exercise_question_id", exercise_question_ids).destroy_all + + normal_status(0, "已成功打回重做!") + else + normal_status(-1, "请选择学生!") + end + end + end + + #学生开始答题页面 + def start_answer + ex_users_current = ExerciseUser.where(user_id: @exercise_current_user_id, exercise_id: @exercise.id) #不能用@exercise.exercise_users,因为exercise_users删除时,只是状态改变,未删除 + @exercise_user_current = ex_users_current&.first + if ex_users_current.exists? + if @exercise_user_current.start_at.blank? + @exercise_user_current.update!(start_at: Time.now) + end + else + if @user_course_identity > Course::ASSISTANT_PROFESSOR #当为老师的时候,不创建exercise_user表,理论上老师是不能进入答题的 + exercise_user_params = { + :user_id => @exercise_current_user_id, + :exercise_id => @exercise.id, + :start_at => Time.now + } + exercise_user_current = ExerciseUser.new(exercise_user_params) + exercise_user_current.save! + end + end + @t_user_exercise_status = @exercise.get_exercise_status(current_user) + + @user_left_time = nil + if @user_course_identity < Course::STUDENT || (@t_user_exercise_status == 3) || + (ex_users_current.exists? && @exercise_user_current.commit_status == 1) + @user_exercise_status = 1 #当前用户为老师/试卷已截止/试卷已提交不可编辑 + else + @user_left_time = get_exercise_left_time(@exercise, current_user) + @user_exercise_status = 0 #可编辑 + end + + @exercise_questions = @exercise.exercise_questions + + if @exercise.question_random + @exercise_questions = @exercise_questions.order("RAND()") + else + @exercise_questions = @exercise_questions.order("question_number ASC") + end + # 判断问题是否已回答还是未回答 + @exercise_questions = @exercise_questions.includes(:exercise_shixun_challenges, + :exercise_shixun_answers, + :exercise_answers, + :exercise_standard_answers) + + if @t_user_exercise_status == Exercise::DEADLINE + get_each_student_exercise(@exercise.id, @exercise_questions, @exercise_current_user_id) + end + get_user_answer_status(@exercise_questions, @exercise_current_user_id, @exercise, @t_user_exercise_status) + + end + + #提交试卷前的弹窗 + def begin_commit + ActiveRecord::Base.transaction do + if @user_course_identity > Course::ASSISTANT_PROFESSOR #为学生时 + @exercise_questions = @exercise.exercise_questions + @shixun_undo = 0 + @ques_undo = 0 + ex_answer_time = @exercise.time.to_i + if ex_answer_time > 0 #有剩余时间的时候 + user_left_time = get_exercise_left_time(@exercise, current_user) + @ex_end_time = Time.now + user_left_time.to_i.seconds else - ques_vote = q.exercise_answers.search_exercise_answer("user_id",current_user.id) - if ques_vote.blank? - @ques_undo += 1 + @ex_end_time = @exercise.get_exercise_end_time(current_user.id) + end + # @ex_end_time = @exercise.get_exercise_end_time(current_user.id) + # if ex_answer_time > 0 + # left_answer_time = Time.now + ex_answer_time.minutes #判断试卷的倒计时和截止时间哪个先到 + # if left_answer_time < @ex_end_time + # exercise_end_time = @exercise.exercise_users.exercise_commit_users(current_user.id) + # if exercise_end_time.present? + # ex_end_times = exercise_end_time.first.start_at.nil? ? Time.now : exercise_end_time.first.start_at + # @ex_end_time = ex_end_times + ex_answer_time.minutes + # end + # end + # end + @exercise_questions.each do |q| + if q.question_type == Exercise::PRACTICAL #当为实训题时 + user_myshixun = q.shixun.myshixuns.search_myshixun_user(current_user.id) + if user_myshixun.blank? || user_myshixun.first.status != Exercise::UNPUBLISHED #当前用户的实训是否做完 + @shixun_undo += 1 + end + else + ques_vote = q.exercise_answers.search_exercise_answer("user_id", current_user.id) + if ques_vote.blank? + @ques_undo += 1 + end end end end end - rescue Exception => e - uid_logger_error(e.message) - tip_exception("试卷提交失败!") - raise ActiveRecord::Rollback end - end - end - # 学生提交试卷 - def commit_exercise - tip_exception(0, "试卷截止时间已到,系统已自动提交") if @answer_committed_user.commit_status == 1 - ActiveRecord::Base.transaction do - begin - can_commit_exercise = false - user_left_time = nil - if @user_course_identity > Course::ASSISTANT_PROFESSOR #为学生时 - if params[:commit_method].to_i == 2 #自动提交时 - user_left_time = get_exercise_left_time(@exercise,current_user) - Rails.logger.info("######__________auto_commit_user_left_time_________################{user_left_time}") - if user_left_time.to_i <= 0 + # 学生提交试卷 + def commit_exercise + tip_exception(0, "试卷截止时间已到,系统已自动提交") if @answer_committed_user.commit_status == 1 + ActiveRecord::Base.transaction do + can_commit_exercise = false + user_left_time = nil + if @user_course_identity > Course::ASSISTANT_PROFESSOR #为学生时 + if params[:commit_method].to_i == 2 #自动提交时 + user_left_time = get_exercise_left_time(@exercise, current_user) + Rails.logger.info("######__________auto_commit_user_left_time_________################{user_left_time}") + if user_left_time.to_i <= 0 + can_commit_exercise = true + end + else can_commit_exercise = true end + if can_commit_exercise + objective_score = calculate_student_score(@exercise, current_user, Time.now)[:total_score] + subjective_score = @answer_committed_user.subjective_score + total_score_subjective_score = subjective_score < 0.0 ? 0.0 : subjective_score + total_score = objective_score + total_score_subjective_score + commit_option = { + :status => 1, + :commit_status => 1, + :end_at => Time.now, + :objective_score => objective_score, + :score => total_score, + :subjective_score => subjective_score, + :commit_method => @answer_committed_user&.commit_method.to_i > 0 ? @answer_committed_user&.commit_method.to_i : params[:commit_method].to_i + } + @answer_committed_user.update!(commit_option) + CommitExercsieNotifyJobJob.perform_later(@exercise.id, current_user.id) + normal_status(0, "试卷提交成功!") + else + normal_status(-2, "#{user_left_time.to_i}") + end else - can_commit_exercise = true - end - if can_commit_exercise - objective_score = calculate_student_score(@exercise,current_user,Time.now)[:total_score] - subjective_score = @answer_committed_user.subjective_score - total_score_subjective_score = subjective_score < 0.0 ? 0.0 : subjective_score - total_score = objective_score + total_score_subjective_score - commit_option = { - :status => 1, - :commit_status => 1, - :end_at => Time.now, - :objective_score => objective_score, - :score => total_score, - :subjective_score => subjective_score, - :commit_method => @answer_committed_user&.commit_method.to_i > 0 ? @answer_committed_user&.commit_method.to_i : params[:commit_method].to_i - } - @answer_committed_user.update!(commit_option) - CommitExercsieNotifyJobJob.perform_later(@exercise.id, current_user.id) - normal_status(0,"试卷提交成功!") - else - normal_status(-2,"#{user_left_time.to_i}") + normal_status(-1, "提交失败,当前用户不为课堂学生!") end - else - normal_status(-1,"提交失败,当前用户不为课堂学生!") end - rescue Exception => e - uid_logger_error(e.message) - tip_exception("试卷提交失败!") - raise ActiveRecord::Rollback end - end - end - #教师评阅试卷 及学生查看试卷 - def review_exercise - ActiveRecord::Base.transaction do - begin - # 1 老师权限,0 学生权限 - @is_teacher_or = (@user_course_identity < Course::STUDENT) ? 1 : 0 - @student_status = 2 - @exercise_questions = @exercise.exercise_questions.includes(:exercise_shixun_challenges,:exercise_standard_answers,:exercise_answers,:exercise_shixun_answers,:exercise_answer_comments).order("question_number ASC") - @question_status = [] - get_exercise_status = @exercise.get_exercise_status(current_user) #当前用户的试卷状态 - @ex_answer_status = @exercise.get_exercise_status(@ex_user&.user) #当前试卷用户的试卷状态 - if @ex_user.present? && @is_teacher_or == 0 - if get_exercise_status == Exercise::PUBLISHED #当前用户已提交,且试卷未截止 - if @ex_user.commit_status == 0 #学生未提交,且当前为学生 - @student_status = 0 - else - @student_status = 1 - get_user_answer_status(@exercise_questions,@exercise_current_user_id,@exercise,get_exercise_status) + #教师评阅试卷 及学生查看试卷 + def review_exercise + ActiveRecord::Base.transaction do + # 1 老师权限,0 学生权限 + @is_teacher_or = (@user_course_identity < Course::STUDENT) ? 1 : 0 + @student_status = 2 + @exercise_questions = @exercise.exercise_questions.includes(:exercise_shixun_challenges, :exercise_standard_answers, :exercise_answers, :exercise_shixun_answers, :exercise_answer_comments).order("question_number ASC") + @question_status = [] + get_exercise_status = @exercise.get_exercise_status(current_user) #当前用户的试卷状态 + @ex_answer_status = @exercise.get_exercise_status(@ex_user&.user) #当前试卷用户的试卷状态 + if @ex_user.present? && @is_teacher_or == 0 + if get_exercise_status == Exercise::PUBLISHED #当前用户已提交,且试卷未截止 + if @ex_user.commit_status == 0 #学生未提交,且当前为学生 + @student_status = 0 + else + @student_status = 1 + get_user_answer_status(@exercise_questions, @exercise_current_user_id, @exercise, get_exercise_status) + end end end + if @student_status == 2 + get_each_student_exercise(@exercise.id, @exercise_questions, @exercise_current_user_id) + end end - if @student_status == 2 - get_each_student_exercise(@exercise.id,@exercise_questions,@exercise_current_user_id) - end - rescue Exception => e - uid_logger_error(e.message) - tip_exception("没有权限") - raise ActiveRecord::Rollback end - end - end - #答题列表 - def exercise_lists - begin + #答题列表 + def exercise_lists @current_user_id = current_user.id exercise_ids = [@exercise.id] @exercise_status = @exercise.get_exercise_status(current_user) @course_all_members = @course.students @c_group_counts = @course.course_groups_count question_types = @exercise.exercise_questions.pluck(:question_type).uniq - @exercise_publish_count = get_user_permission_course(exercise_ids,Exercise::PUBLISHED).count #判断是否有已发布的分班 - @exercise_unpublish_count = get_user_permission_course(exercise_ids,Exercise::UNPUBLISHED).count #判断是否有未发布的分班 + @exercise_publish_count = get_user_permission_course(exercise_ids, Exercise::PUBLISHED).count #判断是否有已发布的分班 + @exercise_unpublish_count = get_user_permission_course(exercise_ids, Exercise::UNPUBLISHED).count #判断是否有未发布的分班 - if (question_types.size > 1) && question_types.include?(Exercise::SUBJECTIVE) #是否包含主观题,或者是否大于1 + if (question_types.size > 1) && question_types.include?(Exercise::SUBJECTIVE) #是否包含主观题,或者是否大于1 @subjective_type = 1 else @subjective_type = 0 end #初始化值 - @exercise_users_list = [] #答题用户列表 - @exercise_course_groups = [] #当前用户有权限的班级 - @exercise_unanswers = 0 # 未答用户数 - @exercise_answers = 0 #已答用户数 - @exercise_users_count = 0 #全部用户数 - @teacher_review_count = 0 #已评数 - @teacher_unreview_count = 0 #未评数 + @exercise_users_list = [] #答题用户列表 + @exercise_course_groups = [] #当前用户有权限的班级 + @exercise_unanswers = 0 # 未答用户数 + @exercise_answers = 0 #已答用户数 + @exercise_users_count = 0 #全部用户数 + @teacher_review_count = 0 #已评数 + @teacher_unreview_count = 0 #未评数 #试卷的答题列表页的显示用户 - if @user_course_identity < Course::STUDENT #当前为老师,而且老师只能查看自己班级的/课堂的试卷 + if @user_course_identity < Course::STUDENT #当前为老师,而且老师只能查看自己班级的/课堂的试卷 @exercise_current_user_status = 0 unless @exercise_status == Exercise::UNPUBLISHED ex_common_ids = @exercise.common_published_ids(current_user.id) @exercise_course_groups = @course.get_ex_published_course(ex_common_ids) - @exercise_users_list = @exercise.all_exercise_users(current_user.id) #当前老师所在班级的全部学生 + @exercise_users_list = @exercise.all_exercise_users(current_user.id) #当前老师所在班级的全部学生 get_exercise_answers(@exercise_users_list, @exercise_status) end - else #当前为学生或者有过答题的 - @ex_user_end_time = @exercise.get_exercise_end_time(current_user.id) #当前用户所看到的剩余时间 + else #当前为学生或者有过答题的 + @ex_user_end_time = @exercise.get_exercise_end_time(current_user.id) #当前用户所看到的剩余时间 @exercise_all_users = @exercise.get_stu_exercise_users - get_exercise_answers(@exercise_all_users, @exercise_status) # 未答和已答的 + get_exercise_answers(@exercise_all_users, @exercise_status) # 未答和已答的 exercise_current_user = @exercise_all_users.exercise_commit_users(current_user.id) - if exercise_current_user.exists? #表示为课堂学生或已回答的 + if exercise_current_user.exists? #表示为课堂学生或已回答的 @exercise_current_user_status = 1 - if @exercise.score_open && @exercise_status == Exercise::DEADLINE #勾选了成绩公开且试卷已截止的 + if @exercise.score_open && @exercise_status == Exercise::DEADLINE #勾选了成绩公开且试卷已截止的 all_user_ids = @exercise_all_users.pluck(:user_id) - all_user_ids.delete(current_user.id) #删除了当前用户的ID + all_user_ids.delete(current_user.id) #删除了当前用户的ID @exercise_users_list = @exercise_all_users.exercise_commit_users(all_user_ids).distinct - @current_user_ex_answers = exercise_current_user #当前用户的回答 + @current_user_ex_answers = exercise_current_user #当前用户的回答 else @exercise_users_list = exercise_current_user end - else #表示为未回答的,或未非课堂成员的 - @exercise_current_user_status = 2 #当前用户非课堂成员 + else #表示为未回答的,或未非课堂成员的 + @exercise_current_user_status = 2 #当前用户非课堂成员 end end @@ -1297,230 +2486,545 @@ class ExercisesController < ApplicationController order_type = params[:order_type] || "desc" if @exercise_users_list.present? && @exercise_users_list.size > 0 - @exercise_users_count = @exercise_users_list.size #当前显示的全部成员数量 + @exercise_users_count = @exercise_users_list.size #当前显示的全部成员数量 teacher_reviews = @exercise_users_list.exercise_review teacher_unreviews = @exercise_users_list.exercise_unreview - @teacher_review_count = teacher_reviews.size #已评阅 - @teacher_unreview_count = teacher_unreviews.size #未评阅 + @teacher_review_count = teacher_reviews.size #已评阅 + @teacher_unreview_count = teacher_unreviews.size #未评阅 #是否评阅 if params[:review].present? - review_type = params[:review].first.to_i #已评,则数据为1,未评,则数据为0,前端传过来的为数组 + review_type = params[:review].first.to_i #已评,则数据为1,未评,则数据为0,前端传过来的为数组 if review_type == 1 - @exercise_users_list = teacher_reviews + @exercise_users_list = teacher_reviews + else + @exercise_users_list = teacher_unreviews + end + end + + #答题状态的选择 + if params[:commit_status].present? + choose_type = params[:commit_status] + @exercise_users_list = @exercise_users_list.commit_exercise_by_status(choose_type) + end + + #班级的选择 + if params[:exercise_group_id].present? + group_id = params[:exercise_group_id] + exercise_students = @course_all_members.course_find_by_ids("course_group_id", group_id) #试卷所分班的全部人数 + user_ids = exercise_students.pluck(:user_id).reject(&:blank?) + @exercise_users_list = @exercise_users_list.exercise_commit_users(user_ids) + end + + #搜索 + if params[:search].present? + @exercise_users_list = @exercise_users_list.joins(user: :user_extension).where("CONCAT(lastname, firstname) like ? OR student_id like ?", "%#{params[:search]}%", "%#{params[:search]}%") + end + + exercise_user_joins = @exercise_users_list.joins(user: :user_extension) + + if order == "student_id" + @exercise_users_list = exercise_user_joins.order("user_extensions.student_id #{order_type}") + elsif order == "score" + @exercise_users_list = exercise_user_joins.order("#{order} #{order_type}") + else + @exercise_users_list = exercise_user_joins.order("end_at #{order_type}, start_at #{order_type}") + end + + @export_ex_users = @exercise_users_list + + @exercise_users_size = @exercise_users_list.size + + # 分页 + @page = params[:page] || 1 + @limit = params[:limit] || 20 + @exercise_users_list = @exercise_users_list.page(@page).per(@limit) + else + @exercise_users_list = [] + @export_ex_users = @exercise_users_list + @exercise_users_size = 0 + end + + if params[:format] == "xlsx" + if @user_course_identity > Course::ASSISTANT_PROFESSOR + tip_exception(403, "无权限操作") + elsif @exercise_status == Exercise::UNPUBLISHED + normal_status(-1, "试卷未发布") + elsif (@exercise_users_size == 0) || (@export_ex_users&.exercise_user_committed.size == 0) + normal_status(-1, "暂无用户提交") + elsif params[:export].present? && params[:export] + normal_status(0, "正在下载中") else - @exercise_users_list = teacher_unreviews + respond_to do |format| + format.xlsx { + set_export_cookies + get_export_users(@exercise, @course, @export_ex_users) + exercise_export_name_ = + "#{current_user.real_name}_#{@course.name}_#{@exercise.exercise_name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}" + render xlsx: "#{exercise_export_name_.strip}", template: "exercises/exercise_lists.xlsx.axlsx", locals: {table_columns: @table_columns, exercise_users: @user_columns} + } + end end end + end - #答题状态的选择 - if params[:commit_status].present? - choose_type = params[:commit_status] - @exercise_users_list = @exercise_users_list.commit_exercise_by_status(choose_type) + #导出空白试卷 + def export_exercise + @request_url = request.base_url + @exercise_questions = @exercise.exercise_questions.includes(:exercise_choices).order("question_number ASC") + filename_ = "#{@exercise.user.real_name}_#{@course.name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}.pdf" + stylesheets = "#{Rails.root}/app/templates/exercise_export/exercise_export.css" + if params[:export].present? && params[:export] + normal_status(0, "正在下载中") + else + set_export_cookies + render pdf: 'exercise_export/blank_exercise', filename: filename_, stylesheets: stylesheets, disposition: 'inline', type: "pdf_attachment.content_type", stream: false end + end + + #空白试卷预览页面,仅供测试使用,无其他任何用途 + # def blank_exercise + # ActiveRecord::Base.transaction do + # begin + # @exercise_questions = @exercise.exercise_questions.order("question_number ASC") + # challenge_ids = @exercise_questions.joins(:exercise_shixun_challenges).pluck("exercise_shixun_challenges.challenge_id") + # get_each_student_exercise(@exercise.id,@exercise_questions,31798) + # @games = @exercise_user.user.games.ch_games(challenge_ids) + # respond_to do |format| + # format.html + # end + # rescue Exception => e + # uid_logger_error(e.message) + # tip_exception("没有权限") + # raise ActiveRecord::Rollback + # end + # end + # end + + #学生的统计结果 + def exercise_result + exercise_ids = [@exercise.id] + @exercise_publish_count = get_user_permission_course(exercise_ids, Exercise::PUBLISHED).size #判断是否有已发布的分班 + @exercise_unpublish_count = get_user_permission_course(exercise_ids, Exercise::UNPUBLISHED).size #判断是否有未发布的分班 + @course_all_members = @course.students #课堂的全部学生 + @exercise_all_users = @exercise.exercise_users + ex_common_ids = @exercise.common_published_ids(current_user.id) + @exercise_course_groups = @course.get_ex_published_course(ex_common_ids) #班级的选择 if params[:exercise_group_id].present? group_id = params[:exercise_group_id] - exercise_students = @course_all_members.course_find_by_ids("course_group_id",group_id) #试卷所分班的全部人数 + exercise_students = @course_all_members.course_find_by_ids("course_group_id", group_id) # 试卷所分班的全部人数 user_ids = exercise_students.pluck(:user_id).reject(&:blank?) - @exercise_users_list = @exercise_users_list.exercise_commit_users(user_ids) + @exercise_all_users = @exercise.exercise_users.exercise_commit_users(user_ids) + @course_all_members_count = @exercise_all_users.size + else + @exercise_users_list = @exercise.all_exercise_users(current_user.id) + @course_all_members_count = @exercise_users_list.size end + @exercise_commit_users = @exercise_all_users.commit_exercise_by_status(1) #试卷的已提交用户 + @exercise_commit_user_ids = @exercise_commit_users.pluck(:user_id).uniq #已提交试卷的全部用户id + @exercise_commit_user_counts = @exercise_commit_users.size #试卷的已提交用户人数 + @exercise_status = @exercise.get_exercise_status(current_user) - #搜索 - if params[:search].present? - @exercise_users_list = @exercise_users_list.joins(user: :user_extension).where("CONCAT(lastname, firstname) like ? OR student_id like ?", "%#{params[:search]}%", "%#{params[:search]}%") + #提交率 + if @course_all_members_count == 0 + commit_percent = 0.00 + min_score = 0.0 + max_score = 0.0 + average_score = 0.0 + fail_counts = 0 + pass_counts = 0 + good_counts = 0 + best_counts = 0 + else + commit_percent = (@exercise_commit_user_counts / @course_all_members_count.to_f).round(3) + exercise_scores = @exercise_commit_users.pluck(:score).reject(&:blank?) + min_score = exercise_scores.min.present? ? exercise_scores.min : 0.0 + max_score = exercise_scores.max.present? ? exercise_scores.max : 0.0 + total_score = exercise_scores.sum.present? ? exercise_scores.sum : 0.0 + average_score = @exercise_commit_user_counts > 0 ? (total_score.round(1) / @exercise_commit_user_counts).round(1) : 0.0 + question_scores = @exercise.question_scores + fail_score = question_scores * 0.6.round(2) + pass_score = question_scores * 0.7.round(2) + good_score = question_scores * 0.9.round(2) + + fail_counts = exercise_scores.count {|a| a < fail_score} + pass_counts = exercise_scores.count {|a| a < pass_score && a >= fail_score} + good_counts = exercise_scores.count {|a| a < good_score && a >= pass_score} + best_counts = exercise_scores.count {|a| a >= good_score && a <= question_scores} + end + @counts_array = { + :commit_percent => commit_percent, + :min_score => min_score.to_s, + :max_score => max_score.to_s, + :average_score => average_score.to_s, + :fail_counts => fail_counts, + :pass_counts => pass_counts, + :good_counts => good_counts, + :best_counts => best_counts, + } + + @exercise_questions = @exercise.exercise_questions&.includes(:exercise_choices, :exercise_answers, :exercise_standard_answers, :exercise_shixun_challenges, :exercise_shixun_answers) + + percent_sort = "desc" + + if params[:sort].present? + percent_sort = params[:sort] end + # @paging_type = "percent" + # # 按题型排序 + # if params[:sort].present? + # @paging_type = params[:sort].to_s + # end - exercise_user_joins = @exercise_users_list.joins(user: :user_extension) + ques_result_all = exercise_commit_result(@exercise_questions, @exercise_commit_user_ids) - if order == "student_id" - @exercise_users_list = exercise_user_joins.order("user_extensions.student_id #{order_type}") - elsif order == "score" - @exercise_users_list = exercise_user_joins.order("#{order} #{order_type}") + #默认降序排列 + if percent_sort == "desc" + @question_result_hash = ques_result_all.sort_by {|s| s[:percent]}.reverse else - @exercise_users_list = exercise_user_joins.order("end_at #{order_type}, start_at #{order_type}") + @question_result_hash = ques_result_all.sort_by {|s| s[:percent]} end - @export_ex_users = @exercise_users_list + @exercise_questions_count = @exercise_questions.size + @page = params[:page] || 1 + @limit = params[:limit] || 10 + @question_result_hash = Kaminari.paginate_array(@question_result_hash).page(@page).per(@limit) + end - @exercise_users_size = @exercise_users_list.size + private - # 分页 - @page = params[:page] || 1 - @limit = params[:limit] || 20 - @exercise_users_list = @exercise_users_list.page(@page).per(@limit) - else - @exercise_users_list = [] - @export_ex_users = @exercise_users_list - @exercise_users_size = 0 + def exercise_params + params.require(:exercise).permit(:exercise_name, :exercise_description, :course_id, :exercise_status, :user_id, :time, + :publish_time, :end_time, :show_result, :question_random, :choice_random, :is_public, + :score_open, :answer_open, :exercise_bank_id, :unified_setting, :show_statistic) end - if params[:format] == "xlsx" - if @user_course_identity > Course::ASSISTANT_PROFESSOR - tip_exception(403,"无权限操作") - elsif @exercise_status == Exercise::UNPUBLISHED - normal_status(-1,"试卷未发布") - elsif (@exercise_users_size == 0) || ( @export_ex_users&.exercise_user_committed.size == 0) - normal_status(-1,"暂无用户提交") - elsif params[:export].present? && params[:export] - normal_status(0,"正在下载中") + def is_course_teacher + unless @user_course_identity < Course::STUDENT #为老师/助教/管理员 + normal_status(403, "...") + end + end + + #检查传入的参数内容是否符合 + def validates_exercise_params + normal_status(-1, "试卷标题不能为空!") if params[:exercise_name].blank? + normal_status(-1, "试卷标题不能超过60个字符") if (params[:exercise_name].length > 60) + normal_status(-1, "试卷须知不能超过100个字符") if (params[:exercise_description].present? && + params[:exercise_description].length > 100) + end + + #判断设置的时间是否合理 + def validate_publish_time + # 截止时间存在,且截止时间必须大于当前时间或发布时间 + unified_setting = params[:unified_setting] + publish_course = params[:publish_time_groups] + if @course.is_end + normal_status(-1, "课堂已结束不能再修改") + elsif unified_setting + ex_group_settings = @exercise.exercise_group_settings + if ex_group_settings.present? + p_time_present = ex_group_settings.publish_time_no_null.map(&:publish_time).min + if p_time_present && p_time_present < Time.now + normal_status(-1, "设置失败,存在已发布的分班") + end + elsif params[:publish_time].blank? + normal_status(-1, "发布时间不允许为空") + end + elsif unified_setting.present? && !unified_setting #非统一设置,分班不能为空 + if publish_course.present? + course_ids = publish_course.map {|a| a[:course_group_id]}.sum + publish_t = publish_course.map {|a| a[:publish_time]} + if course_ids.include?(nil) || course_ids.count == 0 + normal_status(-1, "请选择分班") + elsif publish_t.include?(nil) || publish_t.count == 0 + normal_status(-1, "发布时间不允许为空") + end + else + normal_status(-1, "请选择分班") + end + end + end + + def get_exercise + @exercise = Exercise.find_by(id: params[:id]) + if @exercise.blank? + normal_status(404, "试卷不存在") else - respond_to do |format| - format.xlsx{ - set_export_cookies - get_export_users(@exercise,@course,@export_ex_users) - exercise_export_name_ = - "#{current_user.real_name}_#{@course.name}_#{@exercise.exercise_name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}" - render xlsx: "#{exercise_export_name_.strip}",template: "exercises/exercise_lists.xlsx.axlsx",locals: {table_columns:@table_columns,exercise_users:@user_columns} - } + @course = @exercise.course + normal_status(404, "课堂不存在") if @course.blank? + end + end + + def get_exercise_question_counts #获取试卷的问题数及总分数 + exercise_questions = @exercise.exercise_questions + @exercise_ques_count = exercise_questions.size # 全部的题目数 + @exercise_ques_scores = exercise_questions.pluck(:question_score).sum + + #单选题的数量及分数 + exercise_single_ques = exercise_questions.find_by_custom("question_type", Exercise::SINGLE) + @exercise_single_ques_count = exercise_single_ques.size + @exercise_single_ques_scores = exercise_single_ques.pluck(:question_score).sum + + #多选题的数量及分数 + exercise_double_ques = exercise_questions.find_by_custom("question_type", Exercise::MULTIPLE) + @exercise_double_ques_count = exercise_double_ques.size + @exercise_double_ques_scores = exercise_double_ques.pluck(:question_score).sum + + # 判断题数量及分数 + exercise_ques_judge = exercise_questions.find_by_custom("question_type", Exercise::JUDGMENT) + @exercise_ques_judge_count = exercise_ques_judge.size + @exercise_ques_judge_scores = exercise_ques_judge.pluck(:question_score).sum + + #填空题数量及分数 + exercise_ques_null = exercise_questions.find_by_custom("question_type", Exercise::COMPLETION) + @exercise_ques_null_count = exercise_ques_null.size + @exercise_ques_null_scores = exercise_ques_null.pluck(:question_score).sum + + #简答题数量及分数 + exercise_ques_main = exercise_questions.find_by_custom("question_type", Exercise::SUBJECTIVE) + @exercise_ques_main_count = exercise_ques_main.size + @exercise_ques_main_scores = exercise_ques_main.pluck(:question_score).sum + + #实训题数量及分数 + exercise_ques_shixun = exercise_questions.find_by_custom("question_type", Exercise::PRACTICAL) + @exercise_ques_shixun_count = exercise_ques_shixun.size + @exercise_ques_shixun_scores = exercise_ques_shixun.pluck(:question_score).sum + + @exercise_questions = @exercise_questions&.includes(:exercise_choices, :exercise_shixun_challenges, :exercise_answers, :exercise_shixun_answers, :exercise_answer_comments, :exercise_standard_answers) + + end + + #获取用户有权限的分班 + def get_user_permission_course(exercise_ids, status) + exercise_status = status.to_i #传入的试卷发布状态 + unpublish_group = [] + course_groups = [] + user_groups_id = @course.charge_group_ids(current_user) + exercises_all = Exercise.includes(:exercise_group_settings).where(id: exercise_ids) + exercises_all.each do |exercise| + if exercise.present? + if exercise.unified_setting #统一设置只有两种情况,全部发布,全部截止 + exercise_user_status = exercise.get_exercise_status(current_user) #当前用户的能看到的试卷 + if (exercise_user_status == exercise_status) || exercise_status == Exercise::DEADLINE #未发布的情况 + unpublish_group = unpublish_group + user_groups_id + end + else + ex_all_group_settings = exercise.exercise_group_settings + ex_group_settings = ex_all_group_settings.exercise_group_published.pluck(:course_group_id).uniq #问卷设置的班级 + if exercise_status == Exercise::UNPUBLISHED + unpublish_group = user_groups_id - ex_group_settings + elsif exercise_status == Exercise::DEADLINE + ex_ended_groups = ex_all_group_settings.exercise_group_ended.pluck(:course_group_id).uniq + ex_and_user = user_groups_id & ex_group_settings #用户已设置的分班 + unpublish_group = unpublish_group + ex_and_user - ex_ended_groups #已发布的全部班级减去截止的全部班级 + else + ex_ended_groups = ex_all_group_settings.exercise_group_ended.pluck(:course_group_id).uniq + ex_and_user = user_groups_id & ex_group_settings #用户已设置的分班 + unpublish_group = unpublish_group + ex_and_user - ex_ended_groups + end + end end end + Rails.logger.info("#####____________unpublish_group_______#######{unpublish_group}") + unpublish_group = unpublish_group.uniq + if unpublish_group.count > 0 + course_groups = CourseGroup.by_group_ids(unpublish_group) + end + course_groups end - rescue Exception => e - uid_logger_error(e.message) - tip_exception(e.message) - raise ActiveRecord::Rollback - end - end - #导出空白试卷 - def export_exercise - @request_url = request.base_url - @exercise_questions = @exercise.exercise_questions.includes(:exercise_choices).order("question_number ASC") - filename_ = "#{@exercise.user.real_name}_#{@course.name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}.pdf" - stylesheets = "#{Rails.root}/app/templates/exercise_export/exercise_export.css" - if params[:export].present? && params[:export] - normal_status(0,"正在下载中") - else - set_export_cookies - render pdf: 'exercise_export/blank_exercise', filename: filename_, stylesheets: stylesheets, disposition: 'inline', type:"pdf_attachment.content_type",stream:false - end - end + def set_exercise_status(publish_time, end_time) + time_now_i = Time.now + if publish_time.present? && (publish_time <= time_now_i) && (end_time > time_now_i) + 2 + elsif publish_time.nil? || (publish_time.present? && publish_time > time_now_i) + 1 + elsif end_time.present? && (end_time <= time_now_i) + 3 + elsif end_time.present? && publish_time.present? && (end_time < publish_time) + normal_status(-1, "时间设置错误!") + else + 1 + end + end - #空白试卷预览页面,仅供测试使用,无其他任何用途 - # def blank_exercise - # ActiveRecord::Base.transaction do - # begin - # @exercise_questions = @exercise.exercise_questions.order("question_number ASC") - # challenge_ids = @exercise_questions.joins(:exercise_shixun_challenges).pluck("exercise_shixun_challenges.challenge_id") - # get_each_student_exercise(@exercise.id,@exercise_questions,31798) - # @games = @exercise_user.user.games.ch_games(challenge_ids) - # respond_to do |format| - # format.html - # end - # rescue Exception => e - # uid_logger_error(e.message) - # tip_exception("没有权限") - # raise ActiveRecord::Rollback - # end - # end - # end + def check_course_public + unless @course.is_public == 1 # 0为私有,1为公开 + normal_status(403, "...") + end + end - #学生的统计结果 - def exercise_result - begin - exercise_ids = [@exercise.id] - @exercise_publish_count = get_user_permission_course(exercise_ids,Exercise::PUBLISHED).size #判断是否有已发布的分班 - @exercise_unpublish_count = get_user_permission_course(exercise_ids,Exercise::UNPUBLISHED).size #判断是否有未发布的分班 - @course_all_members = @course.students #课堂的全部学生 - @exercise_all_users = @exercise.exercise_users - ex_common_ids = @exercise.common_published_ids(current_user.id) - @exercise_course_groups = @course.get_ex_published_course(ex_common_ids) + def check_user_id_start_answer #判断用户在开始答题时,是否有用户id传入,如果为老师,则id必需,否则为当前用户的id + user_login = params[:login] + if user_login.blank? && @user_course_identity < Course::STUDENT #id不存在,且当前为老师/管理员等 + normal_status(-1, "请输入学生登陆名!") + else + if @user_course_identity < Course::STUDENT || @exercise.score_open + @ex_answerer = user_login.blank? ? current_user : User.find_by(login: user_login) + else + @ex_answerer = current_user + end - #班级的选择 - if params[:exercise_group_id].present? - group_id = params[:exercise_group_id] - exercise_students = @course_all_members.course_find_by_ids("course_group_id",group_id) # 试卷所分班的全部人数 - user_ids = exercise_students.pluck(:user_id).reject(&:blank?) - @exercise_all_users = @exercise.exercise_users.exercise_commit_users(user_ids) - @course_all_members_count = @exercise_all_users.size - else - @exercise_users_list = @exercise.all_exercise_users(current_user.id) - @course_all_members_count = @exercise_users_list.size - end - @exercise_commit_users = @exercise_all_users.commit_exercise_by_status(1) #试卷的已提交用户 - @exercise_commit_user_ids = @exercise_commit_users.pluck(:user_id).uniq #已提交试卷的全部用户id - @exercise_commit_user_counts = @exercise_commit_users.size #试卷的已提交用户人数 - @exercise_status = @exercise.get_exercise_status(current_user) - - #提交率 - if @course_all_members_count == 0 - commit_percent = 0.00 - min_score = 0.0 - max_score = 0.0 - average_score = 0.0 - fail_counts = 0 - pass_counts = 0 - good_counts = 0 - best_counts = 0 - else - commit_percent = (@exercise_commit_user_counts / @course_all_members_count.to_f).round(3) - exercise_scores = @exercise_commit_users.pluck(:score).reject(&:blank?) - min_score = exercise_scores.min.present? ? exercise_scores.min : 0.0 - max_score = exercise_scores.max.present? ? exercise_scores.max : 0.0 - total_score = exercise_scores.sum.present? ? exercise_scores.sum : 0.0 - average_score = @exercise_commit_user_counts > 0 ? (total_score.round(1) / @exercise_commit_user_counts).round(1) : 0.0 - question_scores = @exercise.question_scores - fail_score = question_scores * 0.6.round(2) - pass_score = question_scores * 0.7.round(2) - good_score = question_scores * 0.9.round(2) - - fail_counts = exercise_scores.count{|a| a < fail_score} - pass_counts = exercise_scores.count{|a| a < pass_score && a >= fail_score} - good_counts = exercise_scores.count{|a| a < good_score && a >= pass_score} - best_counts = exercise_scores.count{|a| a >= good_score && a <= question_scores} - end - @counts_array = { - :commit_percent => commit_percent, - :min_score => min_score.to_s, - :max_score => max_score.to_s, - :average_score => average_score.to_s, - :fail_counts => fail_counts, - :pass_counts => pass_counts, - :good_counts => good_counts, - :best_counts => best_counts, - } + if @ex_answerer.blank? + normal_status(404, "答题用户不存在") + elsif @user_course_identity > Course::STUDENT && !@exercise.is_public + normal_status(403, "非公开试卷") + else + # @exercise_current_user_id = @ex_answerer.id || current_user.id + @exercise_current_user_id = @ex_answerer.id + end + end + end - @exercise_questions = @exercise.exercise_questions&.includes(:exercise_choices,:exercise_answers,:exercise_standard_answers,:exercise_shixun_challenges,:exercise_shixun_answers) + ## 判断开始答题页面的用户权限 + def check_user_on_answer + if @user_course_identity == Course::STUDENT && @exercise.get_exercise_status(current_user) == Exercise::UNPUBLISHED #试卷未发布,且当前用户不为老师/管理员 + normal_status(-1, "未发布试卷!") + elsif @user_course_identity > Course::STUDENT && (!@exercise.is_public || (@exercise.is_public && !@exercise.unified_setting)) ##不为课堂成员,且试卷不为公开的,或试卷公开,但不是统一设置的 + normal_status(-1, "试卷暂未公开!") + end + end - percent_sort = "desc" + def check_exercise_time + @answer_committed_user = @exercise.exercise_users.exercise_commit_users(current_user.id)&.first + if @answer_committed_user.blank? + normal_status(404, "答题用户不存在") + end + end - if params[:sort].present? - percent_sort = params[:sort] + #打回重做时的初步判断 + def check_exercise_status + @exercise_users = @exercise.all_exercise_users(current_user.id).commit_exercise_by_status(1) #当前教师所在分班的全部已提交的学生数 + if @exercise.get_exercise_status(current_user) != Exercise::PUBLISHED + normal_status(-1, "非提交中的试卷不允许打回重做!") + elsif @exercise_users.count < 1 + normal_status(-1, "暂无人提交试卷!") + end end - # @paging_type = "percent" - # # 按题型排序 - # if params[:sort].present? - # @paging_type = params[:sort].to_s - # end - ques_result_all = exercise_commit_result(@exercise_questions,@exercise_commit_user_ids) - #默认降序排列 - if percent_sort == "desc" - @question_result_hash = ques_result_all.sort_by{|s| s[:percent]}.reverse - else - @question_result_hash = ques_result_all.sort_by{|s| s[:percent]} + #查看试题页面,当为学生时,除非试卷已截止,或已提交才可以查看 + def check_exercise_is_end + ex_status = @exercise.get_exercise_status(current_user) + @ex_user = @exercise.exercise_users.find_by(user_id: @exercise_current_user_id) #该试卷的回答者 + if @user_course_identity > Course::ASSISTANT_PROFESSOR + if ex_status == Exercise::UNPUBLISHED + normal_status(-1, "试卷未发布") + elsif @ex_user.present? && @ex_user.commit_status == 0 + normal_status(-1, "试卷未提交") + elsif params[:user_id].present? && current_user.id != params[:user_id] + normal_status(-1, "不能查看他人的试卷") + end + end + end + + #查看试卷是否选择为公开统计 + def check_exercise_public + if @user_course_identity > Course::ASSISTANT_PROFESSOR #当前为学生,试卷公开统计,且已截止,且已提交 + ex_user = @exercise.exercise_users.exercise_commit_users(current_user.id).first + unless @exercise.get_exercise_status(current_user) == Exercise::DEADLINE && ex_user.present? && ex_user.commit_status == 1 && + @exercise.show_statistic + normal_status(-1, "学生暂不能查看") + end + end + end + + def get_left_banner_id + left_banner_content = @course.course_modules.search_by_module_type("exercise") + if left_banner_content.present? + @left_banner_id = left_banner_content.first.id + @left_banner_name = left_banner_content.first.module_name + else + normal_status(404, "左侧导航不存在") + end + end + + def get_user_answer_status(exercise_questions, user_id, exercise, exercise_user_status) + @question_status = [] + @exercise_all_questions = [] + ex_question_random = exercise.question_random + question_answered = 0 + exercise_questions.each_with_index do |q, index| + if ex_question_random && exercise_user_status != Exercise::DEADLINE + ques_number = index + 1 + else + ques_number = q.question_number + end + ques_status = 0 + if q.question_type != Exercise::PRACTICAL + ques_vote = q.exercise_answers.select {|answer| answer.user_id == user_id} + + if ques_vote.present? + #其他题目,需回答的有内容,才会为已答,否则如内容为空,视为未答 + vote_answer_id = ques_vote.pluck(:exercise_choice_id).reject(&:blank?) + vote_text_count = ques_vote.pluck(:answer_text).reject(&:blank?).size + if q.question_type <= Exercise::JUDGMENT #选择题和判断题的时候,需要有选项,才算回答 + if vote_answer_id.size > 0 + ques_status = 1 + question_answered += 1 + end + else + if vote_text_count > 0 #主观题,必选有内容,才算回答 + ques_status = 1 + question_answered += 1 + end + end + end + else + if Myshixun.exists?(user_id: user_id, shixun_id: q.shixun_id) + ques_status = 1 + question_answered += 1 + end + end + question_status = { + :ques_id => q.id, + :ques_number => ques_number, #仅问题的显示位置变化,但是问题的question_number 不会变化,与之相关的choice/standard_answer/answer不会变化 + :ques_status => ques_status, + } + question_options = { + :question => q, + :ques_number => ques_number, + } + @question_status = @question_status.push(question_status).sort_by {|k| k[:ques_number]} + @exercise_all_questions = @exercise_all_questions.push(question_options).sort_by {|k| k[:ques_number]} + end + end + + #下一步也有check_on_users再进行判断 + def only_student_in + if @user_course_identity < Course::STUDENT + normal_status(-1, "老师身份不允许进入") + end + end + + #判断实训是否已选择 + def commit_shixun_present + question_shixun_ids = @exercise.exercise_questions.pluck(:shixun_id).reject(&:blank?) + shixun_id = params[:shixun_id] + @shixun = Shixun.find_by(id: shixun_id) + if shixun_id.present? && question_shixun_ids.include?(shixun_id) + normal_status(-1, "该实训已选择!") + elsif @shixun.blank? + normal_status(-1, "该实训不存在!") + end end - @exercise_questions_count = @exercise_questions.size - @page = params[:page] || 1 - @limit = params[:limit] || 10 - @question_result_hash = Kaminari.paginate_array(@question_result_hash).page(@page).per(@limit) - rescue Exception => e - uid_logger_error(e.message) - tip_exception("没有权限") - raise ActiveRecord::Rollback end + + @exercise_questions_count = @exercise_questions.size + @page = params[:page] || 1 + @limit = params[:limit] || 10 + @question_result_hash = Kaminari.paginate_array(@question_result_hash).page(@page).per(@limit) end private def exercise_params params.require(:exercise).permit(:exercise_name, :exercise_description, :course_id, :exercise_status, :user_id, :time, - :publish_time, :end_time, :show_result, :question_random, :choice_random, :is_public, - :score_open, :answer_open, :exercise_bank_id, :unified_setting, :show_statistic) + :publish_time, :end_time, :show_result, :question_random, :choice_random, :is_public, + :score_open, :answer_open, :exercise_bank_id, :unified_setting, :show_statistic) end def is_course_teacher @@ -1534,7 +3038,7 @@ class ExercisesController < ApplicationController normal_status(-1, "试卷标题不能为空!") if params[:exercise_name].blank? normal_status(-1, "试卷标题不能超过60个字符") if (params[:exercise_name].length > 60) normal_status(-1, "试卷须知不能超过100个字符") if (params[:exercise_description].present? && - params[:exercise_description].length > 100) + params[:exercise_description].length > 100) end #判断设置的时间是否合理 @@ -1543,39 +3047,39 @@ class ExercisesController < ApplicationController unified_setting = params[:unified_setting] publish_course = params[:publish_time_groups] if @course.is_end - normal_status(-1,"课堂已结束不能再修改") + normal_status(-1, "课堂已结束不能再修改") elsif unified_setting ex_group_settings = @exercise.exercise_group_settings if ex_group_settings.present? p_time_present = ex_group_settings.publish_time_no_null.map(&:publish_time).min if p_time_present && p_time_present < Time.now - normal_status(-1,"设置失败,存在已发布的分班") + normal_status(-1, "设置失败,存在已发布的分班") end elsif params[:publish_time].blank? - normal_status(-1,"发布时间不允许为空") + normal_status(-1, "发布时间不允许为空") end - elsif unified_setting.present? && !unified_setting #非统一设置,分班不能为空 + elsif unified_setting.present? && !unified_setting #非统一设置,分班不能为空 if publish_course.present? - course_ids = publish_course.map{|a| a[:course_group_id]}.sum - publish_t = publish_course.map{|a| a[:publish_time]} + course_ids = publish_course.map {|a| a[:course_group_id]}.sum + publish_t = publish_course.map {|a| a[:publish_time]} if course_ids.include?(nil) || course_ids.count == 0 - normal_status(-1,"请选择分班") + normal_status(-1, "请选择分班") elsif publish_t.include?(nil) || publish_t.count == 0 - normal_status(-1,"发布时间不允许为空") + normal_status(-1, "发布时间不允许为空") end else - normal_status(-1,"请选择分班") + normal_status(-1, "请选择分班") end end end def get_exercise - @exercise = Exercise.find_by(id:params[:id]) + @exercise = Exercise.find_by(id: params[:id]) if @exercise.blank? - normal_status(404,"试卷不存在") + normal_status(404, "试卷不存在") else @course = @exercise.course - normal_status(404,"课堂不存在") if @course.blank? + normal_status(404, "课堂不存在") if @course.blank? end end @@ -1585,65 +3089,65 @@ class ExercisesController < ApplicationController @exercise_ques_scores = exercise_questions.pluck(:question_score).sum #单选题的数量及分数 - exercise_single_ques = exercise_questions.find_by_custom("question_type",Exercise::SINGLE) + exercise_single_ques = exercise_questions.find_by_custom("question_type", Exercise::SINGLE) @exercise_single_ques_count = exercise_single_ques.size @exercise_single_ques_scores = exercise_single_ques.pluck(:question_score).sum #多选题的数量及分数 - exercise_double_ques = exercise_questions.find_by_custom("question_type",Exercise::MULTIPLE) + exercise_double_ques = exercise_questions.find_by_custom("question_type", Exercise::MULTIPLE) @exercise_double_ques_count = exercise_double_ques.size @exercise_double_ques_scores = exercise_double_ques.pluck(:question_score).sum # 判断题数量及分数 - exercise_ques_judge = exercise_questions.find_by_custom("question_type",Exercise::JUDGMENT) + exercise_ques_judge = exercise_questions.find_by_custom("question_type", Exercise::JUDGMENT) @exercise_ques_judge_count = exercise_ques_judge.size @exercise_ques_judge_scores = exercise_ques_judge.pluck(:question_score).sum #填空题数量及分数 - exercise_ques_null = exercise_questions.find_by_custom("question_type",Exercise::COMPLETION) + exercise_ques_null = exercise_questions.find_by_custom("question_type", Exercise::COMPLETION) @exercise_ques_null_count = exercise_ques_null.size @exercise_ques_null_scores = exercise_ques_null.pluck(:question_score).sum #简答题数量及分数 - exercise_ques_main = exercise_questions.find_by_custom("question_type",Exercise::SUBJECTIVE) + exercise_ques_main = exercise_questions.find_by_custom("question_type", Exercise::SUBJECTIVE) @exercise_ques_main_count = exercise_ques_main.size @exercise_ques_main_scores = exercise_ques_main.pluck(:question_score).sum #实训题数量及分数 - exercise_ques_shixun = exercise_questions.find_by_custom("question_type",Exercise::PRACTICAL) + exercise_ques_shixun = exercise_questions.find_by_custom("question_type", Exercise::PRACTICAL) @exercise_ques_shixun_count = exercise_ques_shixun.size @exercise_ques_shixun_scores = exercise_ques_shixun.pluck(:question_score).sum - @exercise_questions = @exercise_questions&.includes(:exercise_choices,:exercise_shixun_challenges,:exercise_answers,:exercise_shixun_answers,:exercise_answer_comments,:exercise_standard_answers) + @exercise_questions = @exercise_questions&.includes(:exercise_choices, :exercise_shixun_challenges, :exercise_answers, :exercise_shixun_answers, :exercise_answer_comments, :exercise_standard_answers) end #获取用户有权限的分班 - def get_user_permission_course(exercise_ids,status) + def get_user_permission_course(exercise_ids, status) exercise_status = status.to_i #传入的试卷发布状态 unpublish_group = [] course_groups = [] user_groups_id = @course.charge_group_ids(current_user) - exercises_all = Exercise.includes(:exercise_group_settings).where(id:exercise_ids) + exercises_all = Exercise.includes(:exercise_group_settings).where(id: exercise_ids) exercises_all.each do |exercise| if exercise.present? - if exercise.unified_setting #统一设置只有两种情况,全部发布,全部截止 - exercise_user_status = exercise.get_exercise_status(current_user) #当前用户的能看到的试卷 + if exercise.unified_setting #统一设置只有两种情况,全部发布,全部截止 + exercise_user_status = exercise.get_exercise_status(current_user) #当前用户的能看到的试卷 if (exercise_user_status == exercise_status) || exercise_status == Exercise::DEADLINE #未发布的情况 unpublish_group = unpublish_group + user_groups_id end else ex_all_group_settings = exercise.exercise_group_settings - ex_group_settings = ex_all_group_settings.exercise_group_published.pluck(:course_group_id).uniq #问卷设置的班级 + ex_group_settings = ex_all_group_settings.exercise_group_published.pluck(:course_group_id).uniq #问卷设置的班级 if exercise_status == Exercise::UNPUBLISHED - unpublish_group = user_groups_id - ex_group_settings + unpublish_group = user_groups_id - ex_group_settings elsif exercise_status == Exercise::DEADLINE ex_ended_groups = ex_all_group_settings.exercise_group_ended.pluck(:course_group_id).uniq - ex_and_user = user_groups_id & ex_group_settings #用户已设置的分班 - unpublish_group = unpublish_group + ex_and_user - ex_ended_groups #已发布的全部班级减去截止的全部班级 + ex_and_user = user_groups_id & ex_group_settings #用户已设置的分班 + unpublish_group = unpublish_group + ex_and_user - ex_ended_groups #已发布的全部班级减去截止的全部班级 else ex_ended_groups = ex_all_group_settings.exercise_group_ended.pluck(:course_group_id).uniq - ex_and_user = user_groups_id & ex_group_settings #用户已设置的分班 + ex_and_user = user_groups_id & ex_group_settings #用户已设置的分班 unpublish_group = unpublish_group + ex_and_user - ex_ended_groups end end @@ -1657,7 +3161,7 @@ class ExercisesController < ApplicationController course_groups end - def set_exercise_status(publish_time,end_time) + def set_exercise_status(publish_time, end_time) time_now_i = Time.now if publish_time.present? && (publish_time <= time_now_i) && (end_time > time_now_i) 2 @@ -1666,22 +3170,22 @@ class ExercisesController < ApplicationController elsif end_time.present? && (end_time <= time_now_i) 3 elsif end_time.present? && publish_time.present? && (end_time < publish_time) - normal_status(-1,"时间设置错误!") + normal_status(-1, "时间设置错误!") else 1 end end def check_course_public - unless @course.is_public == 1 # 0为私有,1为公开 - normal_status(403,"...") + unless @course.is_public == 1 # 0为私有,1为公开 + normal_status(403, "...") end end def check_user_id_start_answer #判断用户在开始答题时,是否有用户id传入,如果为老师,则id必需,否则为当前用户的id user_login = params[:login] - if user_login.blank? && @user_course_identity < Course::STUDENT #id不存在,且当前为老师/管理员等 - normal_status(-1,"请输入学生登陆名!") + if user_login.blank? && @user_course_identity < Course::STUDENT #id不存在,且当前为老师/管理员等 + normal_status(-1, "请输入学生登陆名!") else if @user_course_identity < Course::STUDENT || @exercise.score_open @ex_answerer = user_login.blank? ? current_user : User.find_by(login: user_login) @@ -1690,9 +3194,9 @@ class ExercisesController < ApplicationController end if @ex_answerer.blank? - normal_status(404,"答题用户不存在") + normal_status(404, "答题用户不存在") elsif @user_course_identity > Course::STUDENT && !@exercise.is_public - normal_status(403,"非公开试卷") + normal_status(403, "非公开试卷") else # @exercise_current_user_id = @ex_answerer.id || current_user.id @exercise_current_user_id = @ex_answerer.id @@ -1702,9 +3206,9 @@ class ExercisesController < ApplicationController ## 判断开始答题页面的用户权限 def check_user_on_answer - if @user_course_identity == Course::STUDENT && @exercise.get_exercise_status(current_user) == Exercise::UNPUBLISHED #试卷未发布,且当前用户不为老师/管理员 + if @user_course_identity == Course::STUDENT && @exercise.get_exercise_status(current_user) == Exercise::UNPUBLISHED #试卷未发布,且当前用户不为老师/管理员 normal_status(-1, "未发布试卷!") - elsif @user_course_identity > Course::STUDENT && (!@exercise.is_public || (@exercise.is_public && !@exercise.unified_setting)) ##不为课堂成员,且试卷不为公开的,或试卷公开,但不是统一设置的 + elsif @user_course_identity > Course::STUDENT && (!@exercise.is_public || (@exercise.is_public && !@exercise.unified_setting)) ##不为课堂成员,且试卷不为公开的,或试卷公开,但不是统一设置的 normal_status(-1, "试卷暂未公开!") end end @@ -1712,7 +3216,7 @@ class ExercisesController < ApplicationController def check_exercise_time @answer_committed_user = @exercise.exercise_users.exercise_commit_users(current_user.id)&.first if @answer_committed_user.blank? - normal_status(404,"答题用户不存在") + normal_status(404, "答题用户不存在") end end @@ -1720,9 +3224,9 @@ class ExercisesController < ApplicationController def check_exercise_status @exercise_users = @exercise.all_exercise_users(current_user.id).commit_exercise_by_status(1) #当前教师所在分班的全部已提交的学生数 if @exercise.get_exercise_status(current_user) != Exercise::PUBLISHED - normal_status(-1,"非提交中的试卷不允许打回重做!") + normal_status(-1, "非提交中的试卷不允许打回重做!") elsif @exercise_users.count < 1 - normal_status(-1,"暂无人提交试卷!") + normal_status(-1, "暂无人提交试卷!") end end @@ -1730,25 +3234,25 @@ class ExercisesController < ApplicationController #查看试题页面,当为学生时,除非试卷已截止,或已提交才可以查看 def check_exercise_is_end ex_status = @exercise.get_exercise_status(current_user) - @ex_user = @exercise.exercise_users.find_by(user_id:@exercise_current_user_id) #该试卷的回答者 + @ex_user = @exercise.exercise_users.find_by(user_id: @exercise_current_user_id) #该试卷的回答者 if @user_course_identity > Course::ASSISTANT_PROFESSOR if ex_status == Exercise::UNPUBLISHED - normal_status(-1,"试卷未发布") + normal_status(-1, "试卷未发布") elsif @ex_user.present? && @ex_user.commit_status == 0 - normal_status(-1,"试卷未提交") + normal_status(-1, "试卷未提交") elsif params[:user_id].present? && current_user.id != params[:user_id] - normal_status(-1,"不能查看他人的试卷") + normal_status(-1, "不能查看他人的试卷") end end end #查看试卷是否选择为公开统计 def check_exercise_public - if @user_course_identity > Course::ASSISTANT_PROFESSOR #当前为学生,试卷公开统计,且已截止,且已提交 + if @user_course_identity > Course::ASSISTANT_PROFESSOR #当前为学生,试卷公开统计,且已截止,且已提交 ex_user = @exercise.exercise_users.exercise_commit_users(current_user.id).first unless @exercise.get_exercise_status(current_user) == Exercise::DEADLINE && ex_user.present? && ex_user.commit_status == 1 && - @exercise.show_statistic - normal_status(-1,"学生暂不能查看") + @exercise.show_statistic + normal_status(-1, "学生暂不能查看") end end end @@ -1759,16 +3263,16 @@ class ExercisesController < ApplicationController @left_banner_id = left_banner_content.first.id @left_banner_name = left_banner_content.first.module_name else - normal_status(404,"左侧导航不存在") + normal_status(404, "左侧导航不存在") end end - def get_user_answer_status(exercise_questions,user_id,exercise,exercise_user_status) + def get_user_answer_status(exercise_questions, user_id, exercise, exercise_user_status) @question_status = [] @exercise_all_questions = [] ex_question_random = exercise.question_random question_answered = 0 - exercise_questions.each_with_index do |q,index| + exercise_questions.each_with_index do |q, index| if ex_question_random && exercise_user_status != Exercise::DEADLINE ques_number = index + 1 else @@ -1776,19 +3280,19 @@ class ExercisesController < ApplicationController end ques_status = 0 if q.question_type != Exercise::PRACTICAL - ques_vote = q.exercise_answers.select{|answer| answer.user_id == user_id} + ques_vote = q.exercise_answers.select {|answer| answer.user_id == user_id} if ques_vote.present? #其他题目,需回答的有内容,才会为已答,否则如内容为空,视为未答 vote_answer_id = ques_vote.pluck(:exercise_choice_id).reject(&:blank?) vote_text_count = ques_vote.pluck(:answer_text).reject(&:blank?).size - if q.question_type <= Exercise::JUDGMENT #选择题和判断题的时候,需要有选项,才算回答 + if q.question_type <= Exercise::JUDGMENT #选择题和判断题的时候,需要有选项,才算回答 if vote_answer_id.size > 0 ques_status = 1 question_answered += 1 end else - if vote_text_count > 0 #主观题,必选有内容,才算回答 + if vote_text_count > 0 #主观题,必选有内容,才算回答 ques_status = 1 question_answered += 1 end @@ -1801,22 +3305,23 @@ class ExercisesController < ApplicationController end end question_status = { - :ques_id => q.id, - :ques_number => ques_number, #仅问题的显示位置变化,但是问题的question_number 不会变化,与之相关的choice/standard_answer/answer不会变化 - :ques_status => ques_status, + :ques_id => q.id, + :ques_number => ques_number, #仅问题的显示位置变化,但是问题的question_number 不会变化,与之相关的choice/standard_answer/answer不会变化 + :ques_status => ques_status, } question_options = { - :question => q, - :ques_number => ques_number, + :question => q, + :ques_number => ques_number, } @question_status = @question_status.push(question_status).sort_by {|k| k[:ques_number]} @exercise_all_questions = @exercise_all_questions.push(question_options).sort_by {|k| k[:ques_number]} end end + #下一步也有check_on_users再进行判断 def only_student_in if @user_course_identity < Course::STUDENT - normal_status(-1,"老师身份不允许进入") + normal_status(-1, "老师身份不允许进入") end end @@ -1826,9 +3331,9 @@ class ExercisesController < ApplicationController shixun_id = params[:shixun_id] @shixun = Shixun.find_by(id: shixun_id) if shixun_id.present? && question_shixun_ids.include?(shixun_id) - normal_status(-1,"该实训已选择!") + normal_status(-1, "该实训已选择!") elsif @shixun.blank? - normal_status(-1,"该实训不存在!") + normal_status(-1, "该实训不存在!") end end From ba2249767258fb254e32e1cbb2dd69a266d577a6 Mon Sep 17 00:00:00 2001 From: daiao <358551898@qq.com> Date: Sat, 11 Jan 2020 17:25:53 +0800 Subject: [PATCH 118/156] 1 --- app/controllers/subjects_controller.rb | 2 +- app/helpers/subjects_helper.rb | 4 ++-- app/views/subjects/show.json.jbuilder | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/controllers/subjects_controller.rb b/app/controllers/subjects_controller.rb index 1ceece56f..d58c4a9c3 100644 --- a/app/controllers/subjects_controller.rb +++ b/app/controllers/subjects_controller.rb @@ -92,7 +92,7 @@ class SubjectsController < ApplicationController @is_creator = current_user.creator_of_subject?(@subject) @is_manager = @user.manager_of_subject?(@subject) # 合作团队 - @shixuns = @subject.shixuns.published.pluck(:id) + # @shixuns = @subject.shixuns.published.pluck(:id) @courses = @subject.courses if @subject.excellent @members = @subject.subject_members.includes(:user) diff --git a/app/helpers/subjects_helper.rb b/app/helpers/subjects_helper.rb index 75ae9f041..72154b0a8 100644 --- a/app/helpers/subjects_helper.rb +++ b/app/helpers/subjects_helper.rb @@ -1,10 +1,10 @@ module SubjectsHelper # 实训路径的发布状态 - def publish_status subject, is_manager, user, shixuns + def publish_status subject, is_manager, user status = -1 if is_manager - status = 0 if subject.status == 0 && shixuns.count > 0 + status = 0 if subject.status == 0 status = 1 if subject.status == 1 status = 2 if subject.status == 2 && user.admin? end diff --git a/app/views/subjects/show.json.jbuilder b/app/views/subjects/show.json.jbuilder index 870d33d40..49ad55517 100644 --- a/app/views/subjects/show.json.jbuilder +++ b/app/views/subjects/show.json.jbuilder @@ -6,7 +6,7 @@ json.subject_score @subject.all_score json.member_count @subject.member_count json.allow_delete (@subject.status != 2 && @is_creator) || @user.admin? -json.publish_status publish_status(@subject, @is_manager, @user, @shixuns) +json.publish_status publish_status(@subject, @is_manager, @user) json.allow_statistics @is_manager json.allow_send @user.logged? json.allow_visit @subject.status > 1 || @is_manager From 5058b7973611f847afb17c46c0e38d7cba8b5a40 Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Sat, 11 Jan 2020 17:26:22 +0800 Subject: [PATCH 119/156] =?UTF-8?q?=E8=AF=84=E9=98=85=E5=92=8C=E5=9B=9E?= =?UTF-8?q?=E5=A4=8D=E7=9A=84=E5=AD=97=E7=AC=A6=E9=99=90=E5=88=B6=E6=94=B9?= =?UTF-8?q?=E4=B8=BA2000?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/memos_controller.rb | 2 +- app/controllers/messages_controller.rb | 2 +- app/models/discuss.rb | 2 +- app/models/graduation_work_score.rb | 2 +- app/models/hack_set.rb | 4 ++-- app/models/journals_for_message.rb | 2 +- app/models/student_works_score.rb | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/controllers/memos_controller.rb b/app/controllers/memos_controller.rb index a4d72371c..b80bfed32 100644 --- a/app/controllers/memos_controller.rb +++ b/app/controllers/memos_controller.rb @@ -144,7 +144,7 @@ class MemosController < ApplicationController def reply tip_exception("parent_id不能为空") if params[:parent_id].blank? tip_exception("content不能为空") if params[:content].blank? - tip_exception("内容不能超过1000字符") if params[:content].length > 1000 + tip_exception("内容不能超过2000字符") if params[:content].length > 2000 ActiveRecord::Base.transaction do begin diff --git a/app/controllers/messages_controller.rb b/app/controllers/messages_controller.rb index 7b096f1ec..2b9d9d69f 100644 --- a/app/controllers/messages_controller.rb +++ b/app/controllers/messages_controller.rb @@ -63,7 +63,7 @@ class MessagesController < ApplicationController def reply return normal_status(2, "回复内容不能为空") if params[:content].blank? - return normal_status(2, "回复内容不能超过1000字符") if params[:content].length > 1000 + return normal_status(2, "回复内容不能超过2000字符") if params[:content].length > 2000 @reply = Message.create!(board: @message.board, root_id: @message.root_id || @message.id, author: current_user, parent: @message, message_detail_attributes: { diff --git a/app/models/discuss.rb b/app/models/discuss.rb index b563a6295..a4c833b55 100644 --- a/app/models/discuss.rb +++ b/app/models/discuss.rb @@ -13,7 +13,7 @@ class Discuss < ApplicationRecord belongs_to :challenge, optional: true validate :validate_sensitive_string - validates :content, length: { maximum: 1000, too_long: "不能超过1000个字符" } + validates :content, length: { maximum: 2000, too_long: "不能超过2000个字符" } after_create :send_tiding diff --git a/app/models/graduation_work_score.rb b/app/models/graduation_work_score.rb index 5c2627c88..78c2727fc 100644 --- a/app/models/graduation_work_score.rb +++ b/app/models/graduation_work_score.rb @@ -5,5 +5,5 @@ class GraduationWorkScore < ApplicationRecord belongs_to :graduation_task has_many :attachments, as: :container, dependent: :destroy - validates :comment, length: { maximum: 1000, too_long: "不能超过1000个字符" } + validates :comment, length: { maximum: 2000, too_long: "不能超过2000个字符" } end diff --git a/app/models/hack_set.rb b/app/models/hack_set.rb index e2ca60549..2c21c3c22 100644 --- a/app/models/hack_set.rb +++ b/app/models/hack_set.rb @@ -1,6 +1,6 @@ class HackSet < ApplicationRecord - validates_length_of :input, maximum: 1000, message: "不能超过5000个字符" - validates_length_of :output, maximum: 1000, message: "不能超过5000个字符" + validates_length_of :input, maximum: 1000, message: "不能超过1000个字符" + validates_length_of :output, maximum: 1000, message: "不能超过1000个字符" validates :input, presence: { message: "测试集输入不能为空" } validates :output, presence: { message: "测试集输出不能为空" } validates_uniqueness_of :input, scope: [:hack_id, :input], message: "多个测试集的输入不能相同" diff --git a/app/models/journals_for_message.rb b/app/models/journals_for_message.rb index 190fa4351..3d0189c91 100644 --- a/app/models/journals_for_message.rb +++ b/app/models/journals_for_message.rb @@ -26,7 +26,7 @@ class JournalsForMessage < ApplicationRecord # "is_comprehensive_evaluation", # 1 教师评论、2 匿评、3 留言 # "hidden", 隐藏、 - validates :notes, length: { maximum: 1000, too_long: "不能超过1000个字符" } + validates :notes, length: { maximum: 2000, too_long: "不能超过2000个字符" } after_create :send_tiding diff --git a/app/models/student_works_score.rb b/app/models/student_works_score.rb index dec4512a8..a193d4e77 100644 --- a/app/models/student_works_score.rb +++ b/app/models/student_works_score.rb @@ -7,7 +7,7 @@ class StudentWorksScore < ApplicationRecord has_many :tidings, as: :container, dependent: :destroy has_many :attachments, as: :container, dependent: :destroy - validates :comment, length: { maximum: 1000, too_long: "不能超过1000个字符" } + validates :comment, length: { maximum: 2000, too_long: "不能超过2000个字符" } scope :shixun_comment, lambda { where(is_ultimate: 0) } From 12746914e1b853d9bae67c34e6f8949d00a50475 Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Sat, 11 Jan 2020 17:31:15 +0800 Subject: [PATCH 120/156] =?UTF-8?q?=E8=AF=95=E5=8D=B7=E7=9A=84=E9=AA=8C?= =?UTF-8?q?=E8=AF=81=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/exercises_controller.rb | 1670 ----------------------- 1 file changed, 1670 deletions(-) diff --git a/app/controllers/exercises_controller.rb b/app/controllers/exercises_controller.rb index 408f95945..5b555cf4c 100644 --- a/app/controllers/exercises_controller.rb +++ b/app/controllers/exercises_controller.rb @@ -1342,1676 +1342,6 @@ class ExercisesController < ApplicationController else @question_result_hash = ques_result_all.sort_by {|s| s[:percent]} end - class ExercisesController < ApplicationController - before_action :require_login, :check_auth, except: [:index] - before_action :find_course, only: [:index, :new, :create, :my_exercises, :public_exercises, :set_public, :destroys, - :join_exercise_banks, :publish_modal, :publish, :end_modal, :end_exercise] #需要有课堂id参数的 - before_action :get_exercise, except: [:index, :new, :create, :my_exercises, :public_exercises, :set_public, :destroys, - :join_exercise_banks, :publish_modal, :publish, :end_modal, :end_exercise] - before_action :user_course_identity - before_action :is_course_teacher, except: [:index, :start_answer, :exercise_setting, :commit_exercise, :exercise_lists, :review_exercise, - :exercise_result, :common_header, :cancel_exercise, :begin_commit] - before_action :get_left_banner_id, only: [:common_header, :start_answer, :review_exercise, :index, :new, :edit] - before_action :validates_exercise_params, only: [:create, :update] - before_action :get_exercise_question_counts, only: [:show, :edit, :start_answer, :review_exercise, :blank_exercise, :export_exercise] - before_action :validate_publish_time, only: [:commit_setting] #提交设置时,需判断时间是否符合 - before_action :check_course_public, only: [:set_public] - before_action :check_user_on_answer, only: [:show, :start_answer, :exercise_lists] #判断当前用户在试卷的权限/老师是否属于分班的权限 - before_action :only_student_in, only: [:start_answer] - before_action :check_user_id_start_answer, only: [:start_answer, :review_exercise] - # before_action :commit_user_exercise,only: [:start_answer,:exercise_lists,:review_exercise] #已有定时的任务 - before_action :check_exercise_time, only: [:commit_exercise] #提交试卷时,判断时间是否超过 - before_action :check_exercise_status, only: [:redo_modal, :redo_exercise] - before_action :check_exercise_is_end, only: [:review_exercise] - before_action :check_exercise_public, only: [:exercise_result] #试卷是否为公开 - before_action :commit_shixun_present, only: [:commit_shixun] - include ExportHelper - include ExercisesHelper - - # model validation error - rescue_from ActiveRecord::RecordInvalid do |ex| - render_error(ex.record.errors.full_messages.join(',')) - end - # form validation error - rescue_from ActiveModel::ValidationError do |ex| - render_error(ex.model.errors.full_messages.join(',')) - end - - def index - begin - # 按发布时间或创建时间排序 - @exercises_all = @course.exercises - member_show_exercises = @exercises_all.is_exercise_published #已发布的或已截止的试卷 - @current_user_ = current_user - - # 课堂的学生人数 - @course_all_members = @course.students #当前课堂的全部学生 - @current_student = @course_all_members.course_find_by_ids("user_id", current_user.id) #当前用户是否为课堂的学生 - - # exercises的不同用户群体的显示 - if @user_course_identity < Course::STUDENT # @is_teacher_or 1为老师/管理员/助教 - @is_teacher_or = 1 - @exercises = @exercises_all #老师能看到全部的试卷,不管是已发布的/未发布的/已截止的/统一设置的/私有设置的(看到内容不同) - elsif @user_course_identity == Course::STUDENT # 2为课堂成员,能看到统一设置的和自己班级的 - @is_teacher_or = 2 - @member_group_id = @current_student.first.try(:course_group_id).to_i # 成员的分班id,默认为0 - if @member_group_id == 0 #表示是课堂的未分班成员,只能查看统一设置的试卷(已发布的/已截止的) - @exercises = member_show_exercises.exists? ? member_show_exercises.unified_setting : [] - else #已分班级的成员,可以查看统一设置和单独设置(试卷是发布在该班级)试卷 - # 已发布 当前用户班级分组的 试卷id - publish_exercise_ids = @course.exercise_group_settings.exercise_group_published.where("course_group_id = #{@member_group_id}").pluck(:exercise_id) - @exercises = member_show_exercises.unified_setting.or(member_show_exercises.where(id: publish_exercise_ids)) - end - else #用户未登陆或不是该课堂成员,仅显示统一设置的(已发布的/已截止的),如有公开,则不显示锁,不公开,则显示锁 - @is_teacher_or = 0 - @exercises = member_show_exercises.unified_setting - end - - if @exercises.size > 0 - if params[:type].present? - choose_type = params[:type].to_i - ex_setting_ids = [] - if @is_teacher_or != 2 - @exercises = @exercises.where("exercise_status = #{choose_type}") - else - case choose_type - when 1 - ex_setting_ids = @course.exercise_group_settings.where("course_group_id = #{@member_group_id}").exercise_group_not_published.pluck(:exercise_id) - when 2 - ex_setting_ids = @course.exercise_group_settings.where("course_group_id = #{@member_group_id}") - .where("publish_time is not null and publish_time <= ? and end_time > ?", Time.now, Time.now).pluck(:exercise_id) - when 3 - ex_setting_ids = @course.exercise_group_settings.where("course_group_id = #{@member_group_id}").exercise_group_ended.pluck(:exercise_id) - end - unified_setting_ids = @exercises.unified_setting.where("exercise_status = #{choose_type}").pluck(:id) - ex_ids = (ex_setting_ids + unified_setting_ids).uniq - @exercises = @exercises.where(id: ex_ids) - end - end - - if params[:search].present? - search_type = params[:search].to_s.strip - @exercises = @exercises.exercise_search(search_type) - end - - @exercises_select_count = @exercises.size # 全部页面,需返回 - @exercises = @exercises.distinct.order("IF(ISNULL(publish_time),0,1), publish_time DESC,created_at DESC") #出现错误 - - # 分页 - @page = params[:page] || 1 - @limit = params[:limit] || 15 - @exercises = @exercises.page(@page).per(@limit) - @exercises = @exercises&.includes(:published_settings) - else - @exercises = [] - end - - @course_all_members_count = @course_all_members.size #当前课堂的学生数 - @exercises_count = @exercises_all.size # 全部页面,需返回 - @exercises_unpublish_counts = @exercises_all.exercise_by_status(1).size #未发布的试卷数 - @exercises_published_counts = @exercises_count - @exercises_unpublish_counts # 已发布的试卷数,包含已截止的 - - rescue Exception => e - uid_logger_error(e.message) - tip_exception(e.message) - raise ActiveRecord::Rollback - end - end - - def new - ActiveRecord::Base.transaction do - begin - @exercise = Exercise.new - rescue Exception => e - uid_logger_error(e.message) - tip_exception("试卷创建失败!") - raise ActiveRecord::Rollback - end - end - end - - def create - ActiveRecord::Base.transaction do - ex_name = params[:exercise_name] - ex_desc = params[:exercise_description] - exercise_options = { - :exercise_name => ex_name, - :exercise_description => ex_desc, - :user_id => current_user.id, - :course_id => @course.id, - :time => -1, - :exercise_status => 1 - } - @exercise = Exercise.create!(exercise_options) - end - end - - #试卷的内容,及试题/答案的内容编辑 - def edit - ActiveRecord::Base.transaction do - @exercise_questions = @exercise.exercise_questions.order("question_number ASC") - end - end - - def update - ActiveRecord::Base.transaction do - ex_name = params[:exercise_name] - ex_desc = params[:exercise_description] - exercise_options = { - :exercise_name => ex_name, - :exercise_description => ex_desc, - } - @exercise.update!(exercise_options) - normal_status(0, "试卷更新成功!") - end - end - - def show - ActiveRecord::Base.transaction do - if @user_course_identity < Course::STUDENT - @is_teacher_or = 1 #为老师/助教/管理员 - else - @is_teacher_or = 0 #为学生 - end - @exercise_questions = @exercise.exercise_questions&.includes(:exercise_choices, :exercise_shixun_challenges, :exercise_standard_answers).order("question_number ASC") - end - end - - #试卷的公用头部 - def common_header - ActiveRecord::Base.transaction do - @user_left_time = nil - if @user_course_identity > Course::ASSISTANT_PROFESSOR - @is_teacher_or = 0 - @user_exercise_answer = @exercise.check_user_answer_status(current_user) - @user_commit_counts = 0 - @user_left_time = get_exercise_left_time(@exercise, current_user) - else - @is_teacher_or = 1 - @user_exercise_answer = 3 #教师页面 - @user_commit_counts = @exercise.exercise_users.where(commit_status: 1).size #已提交的用户数 - end - @ex_status = @exercise.get_exercise_status(current_user) - - exercise_id_array = [@exercise.id] - @exercise_publish_count = get_user_permission_course(exercise_id_array, Exercise::PUBLISHED).size #是否存在已发布的 - @exercise_unpublish_count = get_user_permission_course(exercise_id_array, Exercise::UNPUBLISHED).size #是否存在未发布的 - - if (@exercise_publish_count == 0) && (@exercise_unpublish_count == 0) #即表示没有分班 - if @ex_status == Exercise::UNPUBLISHED - @exercise_unpublish_count = 1 #试卷未发布,且课堂没有分班的时候 - elsif @ex_status == Exercise::PUBLISHED - @exercise_publish_count = 1 #试卷未发布,且课堂没有分班的时候 - end - end - end - end - - #实训题目的选用 - def choose_shixun - ActiveRecord::Base.transaction do - search = params[:search] - if @user_course_identity > Course::ADMIN #当不为管理员的时候 - user_school_id = current_user.school_id #当前用户的学校id - if user_school_id.present? - none_shixun_ids = ShixunSchool.where("school_id != #{user_school_id}").pluck(:shixun_id) - @publish_shixuns = Shixun.where.not(id: none_shixun_ids).unhidden - end - else - @publish_shixuns = Shixun.unhidden - end - if search.present? - @publish_shixuns = @publish_shixuns.search_by_name(search) - end - - @shixuns = @publish_shixuns.joins(:challenges).where("challenges.st != 0").distinct - # 全部页面,需返回 - @shixuns_count = @shixuns.count - - # 分页 - @page = params[:page] || 1 - @limit = params[:limit] || 8 - - @shixuns = @shixuns.page(@page).per(@limit) - end - end - - #确认实训的选择 - def commit_shixun - ActiveRecord::Base.transaction do - @shixun_challenges = @shixun.challenges - @shixun_challenges_count = @shixun_challenges.size - end - end - - # 首页批量或单独删除 - def destroys - ActiveRecord::Base.transaction do - check_ids = Exercise.where(id: params[:check_ids]) - check_ids.destroy_all - normal_status(0, "试卷已删除成功!") - end - end - - # 设为公开 - def set_public - ActiveRecord::Base.transaction do - check_ids = Exercise.where(id: params[:check_ids]) - check_ids.each do |exercise| - exercise.update!(is_public: true) - end - normal_status(0, "试卷已设为公开!") - end - end - - ## 加入题库 - def join_exercise_banks - ActiveRecord::Base.transaction do - check_ids = Exercise.where(id: params[:check_ids]) - check_ids.each do |exercise| - current_ex_bank = current_user.exercise_banks.find_by_container(exercise.id, "Exercise")&.first - if current_ex_bank.present? #当前用户的选择试卷是否已加入习题库,存在则更新习题库和问题库,否则新建习题库和问题库 - ex_params = { - :name => exercise.exercise_name, - :description => exercise.exercise_description, - :course_list_id => exercise.course.try(:course_list_id) - } - current_ex_bank.update!(ex_params) - # question_bank = QuestionBank.ques_by_container(current_ex_bank.id,current_ex_bank.container_type).first #该习题库是否存在于问题库里 - # ques_params = { - # :name => current_ex_bank.name, - # :course_list_id => current_ex_bank.course_list_id - # } - # question_bank.update_attributes(ques_params) if question_bank.present? - current_ex_bank.exercise_bank_questions.destroy_all # 更新后,习题库的问题全部删除,后续重新再建 - else - ex_params = { - :name => exercise.exercise_name, - :description => exercise.exercise_description, - :user_id => current_user.id, - :is_public => 0, - :course_list_id => exercise.course.try(:course_list_id), - :container_id => exercise.id, - :container_type => "Exercise", - :quotes => 1 - } - current_ex_bank = ExerciseBank.new ex_params - current_ex_bank.save! #如果习题库保存成功,则会创建问题库question_bank - # if current_ex_bank.save - # ques_params = { - # :name => current_ex_bank.name, - # :container_id => current_ex_bank.id, - # :container_type => current_ex_bank.container_type, - # :quotes => current_ex_bank.quotes, - # :user_id => current_ex_bank.user_id, - # :is_public => current_ex_bank.is_public, - # :course_list_id => current_ex_bank.course_list_id - # } - # question_bank = QuestionBank.new ques_params - # question_bank.save - # end - exercise.update!(exercise_bank_id: current_ex_bank.id) - end - # 试卷的问题的输入 - exercise.exercise_questions.each do |q| - option = { - :question_title => q.question_title, - :question_type => q.question_type, - :question_number => q.question_number, - :question_score => q.question_score, - :shixun_id => q.shixun_id, - :shixun_name => q.shixun_name - } - exercise_bank_question = current_ex_bank.exercise_bank_questions.new option - exercise_bank_question.save! - ## 试卷选项的输入 - if q.question_type != Exercise::PRACTICAL #不为实训题时,试卷选项加入试题答案库 - ex_choices = q.exercise_choices - ex_standard = q.exercise_standard_answers - ex_choices.each do |c| - choice_option = { - :choice_position => c.choice_position, - :choice_text => c.choice_text - } - ex_bank_choice = exercise_bank_question.exercise_bank_choices.new choice_option - ex_bank_choice.save! - end - ex_standard.each do |s| - ex_stand = { - :exercise_bank_choice_id => s.exercise_choice_id, - :answer_text => s.answer_text - } - ex_stand_bank = exercise_bank_question.exercise_bank_standard_answers.new ex_stand - ex_stand_bank.save! - end - else #当为实训题时 - shixun_challenges = q.exercise_shixun_challenges - shixun_challenges.each do |c| - challenge_option = { - :position => c.position, - :challenge_id => c.challenge_id, - :shixun_id => q.shixun_id, - :question_score => c.question_score - } - shixun_challenge_bank = exercise_bank_question.exercise_bank_shixun_challenges.new challenge_option - shixun_challenge_bank.save! - end - end - end - current_ex_bank.save! - end - normal_status(0, "题库更新成功!") - end - end - - #试卷的设置页面 - def exercise_setting - ActiveRecord::Base.transaction do - @user_permission = 2 - @user_course_groups = @course.teacher_group(current_user.id) #当前老师的分班 - @being_setting_course_ids = @exercise.common_published_ids(current_user.id) #当前用户已发布的班级的id - @user_published_setting = @exercise.exercise_group_settings - .find_in_exercise_group("course_group_id", @being_setting_course_ids) #当前用户已发布班级的试卷设置 - exercise_ids = [@exercise.id] - @exercise_publish_count = get_user_permission_course(exercise_ids, Exercise::PUBLISHED).count #判断当前用户是否有试卷已发布的分班,用于显示立即截止/撤销发布 - @exercise_unpublish_count = get_user_permission_course(exercise_ids, Exercise::UNPUBLISHED).count #判断当前用户是否有试卷未发布的分班,用户显示立即发布 - @exercise_users_count = @exercise.exercise_users.commit_exercise_by_status(1).count #判断当前试卷是否有已提交的 - # ## 需添加发送消息的接口,稍后添加 - end - end - - #试卷的提交设置 - def commit_setting - ActiveRecord::Base.transaction do - error_count = 0 # 判断循环里是否有已发布/已截止的,且时间更改了的分班。 - # course_group_ids = @course.teacher_course_group_ids(current_user.id) #当前老师的班级id数组 - course_group_ids = @course.charge_group_ids(current_user) #当前老师的班级id数组 - - exercise_status = @exercise.get_exercise_status(current_user) - - if exercise_status == Exercise::UNPUBLISHED && course_group_ids.size > 0 # 试卷未发布,且老师的分班大于1 ,才可以修改统一设置,否则按试卷默认的来处理 - unified_setting = params[:unified_setting] - else - unified_setting = @exercise.unified_setting - end - - show_statistic = params[:show_statistic] ? true : false - exercise_time = params[:time].blank? ? -1 : params[:time] - question_random = params[:question_random] ? true : false #问题是否随机,0为不随机,1为随机 - choice_random = params[:choice_random] ? true : false - score_open = params[:score_open] ? true : false #分数是否公开 - answer_open = params[:answer_open] ? true : false #答案是否公开 - - # 统一设置或者分班为0,则更新试卷,并删除试卷分组 - if unified_setting || (course_group_ids.size == 0) - tip_exception("发布时间不能为空") if params[:publish_time].blank? - tip_exception("截止时间不能为空") if params[:end_time].blank? - tip_exception("截止时间不能早于发布时间") if params[:publish_time].to_time > params[:end_time].to_time - tip_exception("截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")})") if @course.end_date.present? && params[:end_time].to_time > @course.end_date.end_of_day - - params_publish_time = params[:publish_time].to_time - params_end_time = params[:end_time].to_time - - if (exercise_status != Exercise::UNPUBLISHED) && (@exercise.publish_time != params_publish_time) - normal_status(-1, "已发布/已截止,不允许修改发布时间") - elsif params_publish_time.present? && params_end_time.present? && params_end_time < params_publish_time - normal_status(-1, "截止时间不能小于发布时间") - else - #发布时间小于当前时间,则试卷显示为未发布,当截止时间大于当前时间,则显示为已截止 - exercise_status_n = set_exercise_status(params_publish_time, params_end_time) - exercise_params = { - :unified_setting => unified_setting, - :show_statistic => show_statistic, - :time => exercise_time, - :question_random => question_random, - :choice_random => choice_random, - :score_open => score_open, - :answer_open => answer_open, - :exercise_status => exercise_status_n, - :publish_time => params_publish_time, - :end_time => params_end_time - } - @exercise.update!(exercise_params) - @exercise.exercise_group_settings.destroy_all - normal_status(0, "试卷设置成功!") - end - else - params_times = params[:publish_time_groups] #分班返回的json数组{"publish_time_groups":[{"course_group_id":"1","publish_time":"xx","end_time":"xxx"}]} - exercise_groups = @exercise.exercise_group_settings.find_in_exercise_group("course_id", @course.id) #试卷的全部分班信息 - exercise_groups_ids = exercise_groups.pluck(:course_group_id) #问卷的全部分班id - total_common = params_times.map {|k| k[:course_group_id]}.sum.uniq #传入的所有分组的分班id - total_common_group = exercise_groups_ids & total_common #传入的分班与问卷已存在的分班的交集 - old_exercise_groups = exercise_groups_ids - total_common_group #后来传入的分班里,没有了的班级,即需要删除 - - params_times.each do |t| - tip_exception("发布时间不能为空") if t[:publish_time].blank? - tip_exception("截止时间不能为空") if t[:end_time].blank? - tip_exception("截止时间不能早于发布时间") if t[:publish_time].to_time > t[:end_time].to_time - tip_exception("截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")})") if @course.end_date.present? && t[:end_time].to_time > @course.end_date.end_of_day - - course_id = t[:course_group_id] - exercise_publish_time = t[:publish_time].to_time - exercise_end_time = t[:end_time].to_time - - exercise_group = exercise_groups.find_in_exercise_group("course_group_id", course_id) #判断该分班是否存在 - if exercise_group.present? && (exercise_group.first.publish_time < Time.now) && (exercise_publish_time != exercise_group.first.publish_time) - error_count += 1 - end - if exercise_group.present? && (exercise_group.first.publish_time < Time.now && exercise_group.first.end_time > Time.now) && (exercise_end_time < Time.now) - error_count += 1 - end - if error_count == 0 - common_group = exercise_groups_ids & course_id #传入的班级与问卷已存在的班级的交集,即表示已有分班的 - new_group_ids = course_id - common_group #新传入的班级id - if common_group.count > 0 #判断试卷的分班设置是否存在,存在则更新,负责则新建 - exercise_group_sets = exercise_groups.find_in_exercise_group("course_group_id", common_group) - exercise_group_sets.each do |the_group_setting| - ex_group_params = { - :publish_time => exercise_publish_time, - :end_time => exercise_end_time - } - - the_group_setting_status = set_exercise_status(the_group_setting.publish_time, the_group_setting.end_time) - if the_group_setting_status == 2 - ex_group_params = { - :publish_time => the_group_setting.publish_time, - :end_time => exercise_end_time < Time.now ? the_group_setting.end_time : exercise_end_time - } - elsif the_group_setting_status == 3 - ex_group_params = { - :publish_time => the_group_setting.publish_time, - :end_time => exercise_end_time - } - end - the_group_setting.update!(ex_group_params) - end - end - if new_group_ids.size > 0 - new_group_ids.each do |c| - exercise_group_params = { - :exercise_id => @exercise.id, - :course_group_id => c, - :course_id => @course.id, - :publish_time => exercise_publish_time, - :end_time => exercise_end_time - } - new_exercise_group = ExerciseGroupSetting.new(exercise_group_params) - new_exercise_group.save! - end - end - end - end - - if error_count > 0 - error_count == 0 - normal_status(-1, "试卷发布/截止时间不能小于当前时间") - else - # 未发布的分班设置才能删除 - if old_exercise_groups.size > 0 - old_all_ex_groups = exercise_groups.find_in_exercise_group("course_group_id", old_exercise_groups).exercise_group_not_published - old_all_ex_groups.destroy_all - end - #试卷更新为exercise_group_setting的发布时间最小,截止时间最大 - e_time_present = exercise_groups.end_time_no_null.map(&:end_time) - p_time_present = exercise_groups.publish_time_no_null.map(&:publish_time) - e_time = e_time_present.size > 0 ? e_time_present.max : nil - p_time = p_time_present.size > 0 ? p_time_present.min : nil - exercise_status = 1 - if p_time.nil? #发布时间为空,则表示问卷未发布 - exercise_status = 1 - elsif p_time.present? && e_time.present? - exercise_status = set_exercise_status(p_time, e_time) - end - exercise_params = { - :unified_setting => unified_setting, - :show_statistic => show_statistic, - :time => exercise_time, - :question_random => question_random, - :choice_random => choice_random, - :score_open => score_open, - :answer_open => answer_open, - :exercise_status => exercise_status, - :publish_time => p_time, - :end_time => e_time - } - @exercise.update!(exercise_params) - if @exercise.exercise_status == Exercise::PUBLISHED - if @exercise.course_acts.size == 0 - @exercise.course_acts << CourseActivity.new(:user_id => @exercise.user_id, :course_id => @exercise.course_id) - end - end - normal_status(0, "试卷设置成功!") - end - end - end - end - - # 对未提交的用户进行调分 - def adjust_score - exercise_user = @exercise.exercise_users.find_by!(user_id: params[:user_id]) - tip_exception("已提交的作品请去评阅页进行调分") if exercise_user.commit_status == 1 && exercise_user.commit_method != 5 - if @exercise.subjective_score > 0 - tip_exception("主观题成绩不能为空") if params[:subjective_score].blank? - tip_exception("主观题成绩不能小于零") if params[:subjective_score].to_f < 0 - tip_exception("主观题成绩不能大于总分值:#{@exercise.subjective_score}分") if params[:subjective_score].to_f.round(1) > @exercise.subjective_score.round(1) - end - - if @exercise.objective_score > 0 - tip_exception("客观题成绩不能为空") if params[:objective_score].blank? - tip_exception("客观题成绩不能小于零") if params[:objective_score].to_f < 0 - tip_exception("客观题成绩不能大于总分值:#{@exercise.objective_score}分") if params[:objective_score].to_f.round(1) > @exercise.objective_score.round(1) - end - - ActiveRecord::Base.transaction do - start_at_time = exercise_user.start_at || Time.now - subjective_score = @exercise.subjective_score > 0 ? params[:subjective_score].to_f.round(2) : 0 - objective_score = @exercise.objective_score > 0 ? params[:objective_score].to_f.round(2) : 0 - score = subjective_score + objective_score - if exercise_user.commit_status == 1 - exercise_user.update!(score: score, subjective_score: subjective_score, objective_score: objective_score) - else - exercise_user.update!(start_at: start_at_time, end_at: Time.now, status: 1, commit_status: 1, score: score, - subjective_score: subjective_score, objective_score: objective_score, commit_method: 5) - end - - ExerciseUserScore.create!(exercise_id: @exercise.id, exercise_user_id: exercise_user.id, - subjective_score: subjective_score, objective_score: objective_score) - normal_status("操作成功") - end - end - - #我的题库 - def my_exercises - ActiveRecord::Base.transaction do - ## 我的试卷题库 - @current_user_exercises = current_user.exercise_banks.find_by_c_type("Exercise") - if @current_user_exercises.present? - - if params[:search].present? - search_type = params[:search].to_s.strip - @current_user_exercises = @current_user_exercises.exercise_bank_search(search_type) - end - page = params[:page] || 1 - limit = params[:limit] || 15 - @my_exercises_count = @current_user_exercises.size - @current_user_exercises = @current_user_exercises.page(page).per(limit) - else - @current_user_exercises = [] - end - end - end - - # 公共题库 - def public_exercises - ActiveRecord::Base.transaction do - if current_user.is_certification_teacher - @user_certification = 1 #用户已通过认证 - @public_exercises = ExerciseBank.find_by_c_type("Exercise").public_exercises - if @public_exercises.present? - if params[:search].present? - search_type = params[:search].to_s.strip - @public_exercises = @public_exercises.exercise_bank_search(search_type) - end - page = params[:page] || 1 - limit = params[:limit] || 15 - @public_exercises_count = @public_exercises.size - @public_exercises = @public_exercises.page(page).per(limit) - else - @public_exercises_count = 0 - @public_exercises = [] - end - else - @user_certification = 0 #用户未通过认证 - @public_exercises_count = 0 - @public_exercises = [] - end - end - end - - #立即发布的弹窗内容 - def publish_modal - - ActiveRecord::Base.transaction do - exercise_ids = params[:check_ids] - if exercise_ids.count > 0 - @course_groups = get_user_permission_course(exercise_ids, 1) - else - @course_groups = [] - end - end - end - - # 详情页的立即发布弹框 - def publish_groups - @current_user = current_user - # 可立即发布的分班:当前用户管理的分班去除已发布的分班 - group_ids = @course.charge_group_ids(@current_user) - @exercise.exercise_group_settings.exercise_group_published.pluck(:course_group_id) - @course_groups = @course.course_groups.where(id: group_ids) - @group_settings = @exercise.exercise_group_settings.where(course_group_id: group_ids) - end - - #首页批量或单独 立即发布,应是跳出弹窗,设置开始时间和截止时间。 - def publish - group_ids = params[:group_ids]&.reject(&:blank?) - if params[:detail].blank? - tip_exception("缺少截止时间参数") if params[:end_time].blank? - tip_exception("截止时间不能早于当前时间") if params[:end_time] <= strf_time(Time.now) - tip_exception("截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")})") if @course.end_date.present? && params[:end_time] > strf_time(@course.end_date.end_of_day) - else - group_end_times = params[:group_end_times].reject(&:blank?).map {|time| time.to_time} - tip_exception("缺少截止时间参数") if group_end_times.blank? - tip_exception("截止时间和分班参数的个数不一致") if group_end_times.length != group_ids.length - group_end_times.each do |time| - tip_exception("分班截止时间不能早于当前时间") if time <= Time.now - tip_exception("分班截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")})") if @course.end_date.present? && time > @course.end_date.end_of_day - end - end - - ActiveRecord::Base.transaction do - check_ids = Exercise.where(id: params[:check_ids]) - ex_end_time = params[:end_time].blank? ? Time.at(((1.month.since.to_i) / 3600.0).ceil * 3600) : params[:end_time].to_time - check_ids.each do |exercise| - if exercise.present? - if exercise.unified_setting - ex_status = exercise.exercise_status #则为试卷的状态 - else - ex_status = @course.course_groups.where(id: params[:group_ids]).size != - exercise.exercise_group_settings.where(course_group_id: params[:group_ids]).exercise_group_published.size ? 1 : 0 - end - if ex_status == 1 #如果试卷存在已发布的,或者是已截止的,那么则直接跳过 - g_course = group_ids #表示是否传入分班参数,如果传入分班的参数,那么试卷的统一设置需修改 - tiding_group_ids = g_course - if g_course - user_course_groups = @course.course_groups.pluck(:id) - if g_course.map(&:to_i).sort == user_course_groups.sort && - ((params[:detail] && group_end_times.min == group_end_times.max) || params[:detail].blank?) # 如果是设置为全部班级,则试卷不用分组,且试卷设定为统一设置,否则则分组设置 - exercise.exercise_group_settings.destroy_all - ex_unified = true - e_time = params[:detail] ? group_end_times.max : ex_end_time - tiding_group_ids = [] - else - ex_unified = false - g_course.each_with_index do |i, index| - exercise_group_setting = exercise.exercise_group_settings.find_in_exercise_group("course_group_id", i).first #根据课堂分班的id,寻找试卷所在的班级 - group_end_time = params[:detail] ? group_end_times[index] : ex_end_time - if exercise_group_setting.present? #如果该试卷分组存在,则更新,否则新建 - exercise_group_setting.update!(publish_time: Time.now, end_time: group_end_time) - else - p_course_group = { - :exercise_id => exercise.id, - :course_group_id => i, - :course_id => exercise.course.id, - :publish_time => Time.now, - :end_time => group_end_time, - } - new_exercise_group = exercise.exercise_group_settings.new p_course_group - new_exercise_group.save! - end - end - # group_ids = params[:group_ids] - e_time = exercise.exercise_group_settings.end_time_no_null.map(&:end_time).max - end - else - exercise.exercise_group_settings.destroy_all - ex_unified = true - e_time = ex_end_time - end - - ex_status = set_exercise_status(Time.now, e_time) - exercise_params = { - :publish_time => Time.now, - :end_time => e_time, - :exercise_status => ex_status, - :unified_setting => ex_unified - } - exercise.update!(exercise_params) - - if exercise.course_acts.size == 0 - exercise.course_acts << CourseActivity.new(:user_id => exercise.user_id, :course_id => exercise.course_id) - end - ExercisePublishNotifyJob.perform_later(exercise.id, tiding_group_ids) - end - end - end - normal_status(0, "试卷发布成功!") - end - end - - #立即截止的弹窗内容 - def end_modal - ActiveRecord::Base.transaction do - exercise_ids = params[:check_ids] - if exercise_ids.count > 0 - @course_groups = get_user_permission_course(exercise_ids, 3) - else - @course_groups = [] - end - end - end - - # 首页批量或单独 立即截止,截止时间为当前时间 - def end_exercise - - ActiveRecord::Base.transaction do - check_ids = Exercise.where(id: params[:check_ids]) - course_students = @course.students #课堂的全部学生数 - check_ids.each do |exercise| - exercise_status = exercise.get_exercise_status(current_user) - if exercise_status == Exercise::PUBLISHED #跳过已截止的或未发布的 - g_course = params[:group_ids] - if g_course.present? - teacher_course_group_ids = @course.charge_group_ids(current_user) - all_course_group_ids = @course.course_groups.pluck(:id) - if exercise.unified_setting && g_course.map(&:to_i).sort == all_course_group_ids.sort #开始为统一设置 - exercise.exercise_group_settings.destroy_all - new_ex_status = set_exercise_status(exercise.publish_time, Time.now) - exercise.update!(:end_time => Time.now, :exercise_status => new_ex_status) - exercise_users = exercise.exercise_users - else - course_members_ids = course_students.course_find_by_ids("course_group_id", g_course).pluck(:user_id).uniq #该班级的全部学生 - exercise_users = exercise.exercise_users.exercise_commit_users(course_members_ids) #参与答题的学生数 - ex_group_setting = exercise.exercise_group_settings - old_exercise_groups = ex_group_setting.find_in_exercise_group("course_group_id", g_course) #试卷的分组设置 - left_course_groups = teacher_course_group_ids - g_course - left_exercise_groups = ex_group_setting.find_in_exercise_group("course_group_id", left_course_groups) - if left_exercise_groups.blank? && exercise.unified_setting - if left_course_groups.size > 0 #开始为统一设置,但是立即截止为分班。则创建没有立即截止的班级的exercise_group_setting - left_course_groups.each do |g| - ex_group_options = { - :exercise_id => exercise.id, - :course_group_id => g, - :course_id => @course.id, - :publish_time => exercise.publish_time, - :end_time => exercise.end_time - } - ExerciseGroupSetting.create!(ex_group_options) - end - end - end - if old_exercise_groups.present? - old_exercise_groups.update_all(:end_time => Time.now) - else - g_course.each do |g| - ex_group_options = { - :exercise_id => exercise.id, - :course_group_id => g, - :course_id => @course.id, - :publish_time => exercise.publish_time, - :end_time => Time.now - } - ExerciseGroupSetting.create!(ex_group_options) - end - end - new_end_time = exercise.exercise_group_settings.end_time_no_null.map(&:end_time) # 试卷结束时间不为空的 - new_end_time_s = new_end_time.count > 0 ? new_end_time.max : Time.now - new_ex_status = set_exercise_status(exercise.publish_time, new_end_time_s) - exercise.update!(:end_time => new_end_time_s, :exercise_status => new_ex_status, :unified_setting => false) - end - else - exercise_users = exercise.exercise_users - exercise.update!(:exercise_status => 3, :end_time => Time.now, :unified_setting => true) - end - - ex_user_ids = exercise_users.pluck(:id) - - EndExerciseCalculateJob.perform_later(ex_user_ids, exercise, Time.now.to_s) - # exercise_users.each do |user| - # if user.commit_status == 0 && user.start_at.present? - # objective_score = calculate_student_score(exercise,user.user)[:total_score] - # user_sub_score = user.subjective_score - # subjective_score = user_sub_score < 0.0 ? 0.0 : user_sub_score - # total_score = objective_score + subjective_score - # commit_option = { - # :status => 1, - # :commit_status => 1, - # :end_at => Time.now, - # :objective_score => objective_score, - # :score => total_score, - # :subjective_score => user_sub_score - # } - # user.update_attributes(commit_option) - # end - # end - end - end - normal_status(0, "试卷截止成功!") - end - end - - #学生撤销回答 - def cancel_exercise - ActiveRecord::Base.transaction do - ex_question_ids = @exercise.exercise_questions.pluck(:id) - exercise_user = @exercise.exercise_users.exercise_commit_users(current_user.id).first - if exercise_user.present? - if exercise_user.commit_status == 1 && @exercise.get_exercise_status(current_user) == Exercise::PUBLISHED #用户已提交且试卷提交中 - if @exercise.time == -1 || ((Time.now.to_i - exercise_user.start_at.to_i) < @exercise.time.to_i * 60) - exercise_user.update!(:score => nil, :end_at => nil, :status => nil, :commit_status => 0, - :objective_score => 0.0, :subjective_score => -1.0) - exercise_user.user.exercise_shixun_answers.search_shixun_answers("exercise_question_id", ex_question_ids).destroy_all - exercise_answers = exercise_user.user.exercise_answers.search_answer_users("exercise_question_id", ex_question_ids) - exercise_answers.update_all(:score => -1.0) - all_answer_comment = ExerciseAnswerComment.search_answer_comments("exercise_question_id", ex_question_ids) - .search_answer_comments("exercise_answer_id", exercise_answers.pluck(:id)) - all_answer_comment.destroy_all - normal_status(0, "撤销回答成功") - else - normal_status(-1, "用户答题时间已到") - end - else - normal_status(-1, "用户未提交/试卷不是提交中") - end - else - normal_status(-1, "当前用户未答题") - end - end - end - - #打回重做modal - def redo_modal - ActiveRecord::Base.transaction do - #搜索 - if params[:realname].present? - search_name = params[:realname] - #搜索用户的nickname,如果存在则返回,否则继续查询用户的真实姓名或学生号 - @exercise_users = @exercise_users.includes(:user).where("LOWER(concat(users.lastname, users.firstname)) like ?", - "%#{search_name}%") - end - if params[:student_id].present? - search_st_id = params[:student_id].to_i - @exercise_users = @exercise_users.includes(user: [:user_extension]) - .where('user_extensions.student_id like ?', "%#{search_st_id}%") - end - sort = params[:sort] ? params[:sort] : "asc" - @exercise_users = @exercise_users.order("score #{sort}") - @exercise_users_size = @exercise_users.size - # 分页 - page = params[:page] || 1 - limit = params[:limit] || 15 - @exercise_users = @exercise_users.page(page).per(limit) - end - end - - #打回重做确认 - def redo_exercise - ActiveRecord::Base.transaction do - user_ids = params[:user_ids] - if user_ids.present? - redo_option = { - :score => 0.0, - :start_at => nil, - :end_at => nil, - :status => nil, - :commit_status => 0, - :objective_score => 0.0, - :subjective_score => -1.0, - :commit_method => 0 - } - redo_exercise_users = @exercise_users.exercise_commit_users(user_ids) - redo_exercise_users.update_all(redo_option) - exercise_question_ids = @exercise.exercise_questions.pluck(:id).uniq - ExerciseAnswer.search_answer_users("user_id", user_ids) - .search_answer_users("exercise_question_id", exercise_question_ids).destroy_all - ExerciseShixunAnswer.search_shixun_answers("user_id", user_ids) - .search_shixun_answers("exercise_question_id", exercise_question_ids).destroy_all - - normal_status(0, "已成功打回重做!") - else - normal_status(-1, "请选择学生!") - end - end - end - - #学生开始答题页面 - def start_answer - ex_users_current = ExerciseUser.where(user_id: @exercise_current_user_id, exercise_id: @exercise.id) #不能用@exercise.exercise_users,因为exercise_users删除时,只是状态改变,未删除 - @exercise_user_current = ex_users_current&.first - if ex_users_current.exists? - if @exercise_user_current.start_at.blank? - @exercise_user_current.update!(start_at: Time.now) - end - else - if @user_course_identity > Course::ASSISTANT_PROFESSOR #当为老师的时候,不创建exercise_user表,理论上老师是不能进入答题的 - exercise_user_params = { - :user_id => @exercise_current_user_id, - :exercise_id => @exercise.id, - :start_at => Time.now - } - exercise_user_current = ExerciseUser.new(exercise_user_params) - exercise_user_current.save! - end - end - @t_user_exercise_status = @exercise.get_exercise_status(current_user) - - @user_left_time = nil - if @user_course_identity < Course::STUDENT || (@t_user_exercise_status == 3) || - (ex_users_current.exists? && @exercise_user_current.commit_status == 1) - @user_exercise_status = 1 #当前用户为老师/试卷已截止/试卷已提交不可编辑 - else - @user_left_time = get_exercise_left_time(@exercise, current_user) - @user_exercise_status = 0 #可编辑 - end - - @exercise_questions = @exercise.exercise_questions - - if @exercise.question_random - @exercise_questions = @exercise_questions.order("RAND()") - else - @exercise_questions = @exercise_questions.order("question_number ASC") - end - # 判断问题是否已回答还是未回答 - @exercise_questions = @exercise_questions.includes(:exercise_shixun_challenges, - :exercise_shixun_answers, - :exercise_answers, - :exercise_standard_answers) - - if @t_user_exercise_status == Exercise::DEADLINE - get_each_student_exercise(@exercise.id, @exercise_questions, @exercise_current_user_id) - end - get_user_answer_status(@exercise_questions, @exercise_current_user_id, @exercise, @t_user_exercise_status) - - end - - #提交试卷前的弹窗 - def begin_commit - ActiveRecord::Base.transaction do - if @user_course_identity > Course::ASSISTANT_PROFESSOR #为学生时 - @exercise_questions = @exercise.exercise_questions - @shixun_undo = 0 - @ques_undo = 0 - ex_answer_time = @exercise.time.to_i - if ex_answer_time > 0 #有剩余时间的时候 - user_left_time = get_exercise_left_time(@exercise, current_user) - @ex_end_time = Time.now + user_left_time.to_i.seconds - else - @ex_end_time = @exercise.get_exercise_end_time(current_user.id) - end - # @ex_end_time = @exercise.get_exercise_end_time(current_user.id) - # if ex_answer_time > 0 - # left_answer_time = Time.now + ex_answer_time.minutes #判断试卷的倒计时和截止时间哪个先到 - # if left_answer_time < @ex_end_time - # exercise_end_time = @exercise.exercise_users.exercise_commit_users(current_user.id) - # if exercise_end_time.present? - # ex_end_times = exercise_end_time.first.start_at.nil? ? Time.now : exercise_end_time.first.start_at - # @ex_end_time = ex_end_times + ex_answer_time.minutes - # end - # end - # end - @exercise_questions.each do |q| - if q.question_type == Exercise::PRACTICAL #当为实训题时 - user_myshixun = q.shixun.myshixuns.search_myshixun_user(current_user.id) - if user_myshixun.blank? || user_myshixun.first.status != Exercise::UNPUBLISHED #当前用户的实训是否做完 - @shixun_undo += 1 - end - else - ques_vote = q.exercise_answers.search_exercise_answer("user_id", current_user.id) - if ques_vote.blank? - @ques_undo += 1 - end - end - end - end - end - end - - # 学生提交试卷 - def commit_exercise - tip_exception(0, "试卷截止时间已到,系统已自动提交") if @answer_committed_user.commit_status == 1 - ActiveRecord::Base.transaction do - can_commit_exercise = false - user_left_time = nil - if @user_course_identity > Course::ASSISTANT_PROFESSOR #为学生时 - if params[:commit_method].to_i == 2 #自动提交时 - user_left_time = get_exercise_left_time(@exercise, current_user) - Rails.logger.info("######__________auto_commit_user_left_time_________################{user_left_time}") - if user_left_time.to_i <= 0 - can_commit_exercise = true - end - else - can_commit_exercise = true - end - if can_commit_exercise - objective_score = calculate_student_score(@exercise, current_user, Time.now)[:total_score] - subjective_score = @answer_committed_user.subjective_score - total_score_subjective_score = subjective_score < 0.0 ? 0.0 : subjective_score - total_score = objective_score + total_score_subjective_score - commit_option = { - :status => 1, - :commit_status => 1, - :end_at => Time.now, - :objective_score => objective_score, - :score => total_score, - :subjective_score => subjective_score, - :commit_method => @answer_committed_user&.commit_method.to_i > 0 ? @answer_committed_user&.commit_method.to_i : params[:commit_method].to_i - } - @answer_committed_user.update!(commit_option) - CommitExercsieNotifyJobJob.perform_later(@exercise.id, current_user.id) - normal_status(0, "试卷提交成功!") - else - normal_status(-2, "#{user_left_time.to_i}") - end - else - normal_status(-1, "提交失败,当前用户不为课堂学生!") - end - end - end - - #教师评阅试卷 及学生查看试卷 - def review_exercise - ActiveRecord::Base.transaction do - # 1 老师权限,0 学生权限 - @is_teacher_or = (@user_course_identity < Course::STUDENT) ? 1 : 0 - @student_status = 2 - @exercise_questions = @exercise.exercise_questions.includes(:exercise_shixun_challenges, :exercise_standard_answers, :exercise_answers, :exercise_shixun_answers, :exercise_answer_comments).order("question_number ASC") - @question_status = [] - get_exercise_status = @exercise.get_exercise_status(current_user) #当前用户的试卷状态 - @ex_answer_status = @exercise.get_exercise_status(@ex_user&.user) #当前试卷用户的试卷状态 - if @ex_user.present? && @is_teacher_or == 0 - if get_exercise_status == Exercise::PUBLISHED #当前用户已提交,且试卷未截止 - if @ex_user.commit_status == 0 #学生未提交,且当前为学生 - @student_status = 0 - else - @student_status = 1 - get_user_answer_status(@exercise_questions, @exercise_current_user_id, @exercise, get_exercise_status) - end - end - end - if @student_status == 2 - get_each_student_exercise(@exercise.id, @exercise_questions, @exercise_current_user_id) - end - end - end - - #答题列表 - def exercise_lists - @current_user_id = current_user.id - exercise_ids = [@exercise.id] - @exercise_status = @exercise.get_exercise_status(current_user) - @course_all_members = @course.students - @c_group_counts = @course.course_groups_count - question_types = @exercise.exercise_questions.pluck(:question_type).uniq - @exercise_publish_count = get_user_permission_course(exercise_ids, Exercise::PUBLISHED).count #判断是否有已发布的分班 - @exercise_unpublish_count = get_user_permission_course(exercise_ids, Exercise::UNPUBLISHED).count #判断是否有未发布的分班 - - if (question_types.size > 1) && question_types.include?(Exercise::SUBJECTIVE) #是否包含主观题,或者是否大于1 - @subjective_type = 1 - else - @subjective_type = 0 - end - - #初始化值 - @exercise_users_list = [] #答题用户列表 - @exercise_course_groups = [] #当前用户有权限的班级 - @exercise_unanswers = 0 # 未答用户数 - @exercise_answers = 0 #已答用户数 - @exercise_users_count = 0 #全部用户数 - @teacher_review_count = 0 #已评数 - @teacher_unreview_count = 0 #未评数 - - #试卷的答题列表页的显示用户 - if @user_course_identity < Course::STUDENT #当前为老师,而且老师只能查看自己班级的/课堂的试卷 - @exercise_current_user_status = 0 - unless @exercise_status == Exercise::UNPUBLISHED - ex_common_ids = @exercise.common_published_ids(current_user.id) - @exercise_course_groups = @course.get_ex_published_course(ex_common_ids) - @exercise_users_list = @exercise.all_exercise_users(current_user.id) #当前老师所在班级的全部学生 - get_exercise_answers(@exercise_users_list, @exercise_status) - end - else #当前为学生或者有过答题的 - @ex_user_end_time = @exercise.get_exercise_end_time(current_user.id) #当前用户所看到的剩余时间 - @exercise_all_users = @exercise.get_stu_exercise_users - get_exercise_answers(@exercise_all_users, @exercise_status) # 未答和已答的 - exercise_current_user = @exercise_all_users.exercise_commit_users(current_user.id) - if exercise_current_user.exists? #表示为课堂学生或已回答的 - @exercise_current_user_status = 1 - if @exercise.score_open && @exercise_status == Exercise::DEADLINE #勾选了成绩公开且试卷已截止的 - all_user_ids = @exercise_all_users.pluck(:user_id) - all_user_ids.delete(current_user.id) #删除了当前用户的ID - @exercise_users_list = @exercise_all_users.exercise_commit_users(all_user_ids).distinct - @current_user_ex_answers = exercise_current_user #当前用户的回答 - else - @exercise_users_list = exercise_current_user - end - else #表示为未回答的,或未非课堂成员的 - @exercise_current_user_status = 2 #当前用户非课堂成员 - end - end - - if @exercise_unanswers < 0 - @exercise_unanswers = 0 - end - - #筛选/分类,排序 - order = params[:order] - order_type = params[:order_type] || "desc" - - if @exercise_users_list.present? && @exercise_users_list.size > 0 - @exercise_users_count = @exercise_users_list.size #当前显示的全部成员数量 - teacher_reviews = @exercise_users_list.exercise_review - teacher_unreviews = @exercise_users_list.exercise_unreview - @teacher_review_count = teacher_reviews.size #已评阅 - @teacher_unreview_count = teacher_unreviews.size #未评阅 - - #是否评阅 - if params[:review].present? - review_type = params[:review].first.to_i #已评,则数据为1,未评,则数据为0,前端传过来的为数组 - if review_type == 1 - @exercise_users_list = teacher_reviews - else - @exercise_users_list = teacher_unreviews - end - end - - #答题状态的选择 - if params[:commit_status].present? - choose_type = params[:commit_status] - @exercise_users_list = @exercise_users_list.commit_exercise_by_status(choose_type) - end - - #班级的选择 - if params[:exercise_group_id].present? - group_id = params[:exercise_group_id] - exercise_students = @course_all_members.course_find_by_ids("course_group_id", group_id) #试卷所分班的全部人数 - user_ids = exercise_students.pluck(:user_id).reject(&:blank?) - @exercise_users_list = @exercise_users_list.exercise_commit_users(user_ids) - end - - #搜索 - if params[:search].present? - @exercise_users_list = @exercise_users_list.joins(user: :user_extension).where("CONCAT(lastname, firstname) like ? OR student_id like ?", "%#{params[:search]}%", "%#{params[:search]}%") - end - - exercise_user_joins = @exercise_users_list.joins(user: :user_extension) - - if order == "student_id" - @exercise_users_list = exercise_user_joins.order("user_extensions.student_id #{order_type}") - elsif order == "score" - @exercise_users_list = exercise_user_joins.order("#{order} #{order_type}") - else - @exercise_users_list = exercise_user_joins.order("end_at #{order_type}, start_at #{order_type}") - end - - @export_ex_users = @exercise_users_list - - @exercise_users_size = @exercise_users_list.size - - # 分页 - @page = params[:page] || 1 - @limit = params[:limit] || 20 - @exercise_users_list = @exercise_users_list.page(@page).per(@limit) - else - @exercise_users_list = [] - @export_ex_users = @exercise_users_list - @exercise_users_size = 0 - end - - if params[:format] == "xlsx" - if @user_course_identity > Course::ASSISTANT_PROFESSOR - tip_exception(403, "无权限操作") - elsif @exercise_status == Exercise::UNPUBLISHED - normal_status(-1, "试卷未发布") - elsif (@exercise_users_size == 0) || (@export_ex_users&.exercise_user_committed.size == 0) - normal_status(-1, "暂无用户提交") - elsif params[:export].present? && params[:export] - normal_status(0, "正在下载中") - else - respond_to do |format| - format.xlsx { - set_export_cookies - get_export_users(@exercise, @course, @export_ex_users) - exercise_export_name_ = - "#{current_user.real_name}_#{@course.name}_#{@exercise.exercise_name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}" - render xlsx: "#{exercise_export_name_.strip}", template: "exercises/exercise_lists.xlsx.axlsx", locals: {table_columns: @table_columns, exercise_users: @user_columns} - } - end - end - end - end - - #导出空白试卷 - def export_exercise - @request_url = request.base_url - @exercise_questions = @exercise.exercise_questions.includes(:exercise_choices).order("question_number ASC") - filename_ = "#{@exercise.user.real_name}_#{@course.name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}.pdf" - stylesheets = "#{Rails.root}/app/templates/exercise_export/exercise_export.css" - if params[:export].present? && params[:export] - normal_status(0, "正在下载中") - else - set_export_cookies - render pdf: 'exercise_export/blank_exercise', filename: filename_, stylesheets: stylesheets, disposition: 'inline', type: "pdf_attachment.content_type", stream: false - end - end - - #空白试卷预览页面,仅供测试使用,无其他任何用途 - # def blank_exercise - # ActiveRecord::Base.transaction do - # begin - # @exercise_questions = @exercise.exercise_questions.order("question_number ASC") - # challenge_ids = @exercise_questions.joins(:exercise_shixun_challenges).pluck("exercise_shixun_challenges.challenge_id") - # get_each_student_exercise(@exercise.id,@exercise_questions,31798) - # @games = @exercise_user.user.games.ch_games(challenge_ids) - # respond_to do |format| - # format.html - # end - # rescue Exception => e - # uid_logger_error(e.message) - # tip_exception("没有权限") - # raise ActiveRecord::Rollback - # end - # end - # end - - #学生的统计结果 - def exercise_result - exercise_ids = [@exercise.id] - @exercise_publish_count = get_user_permission_course(exercise_ids, Exercise::PUBLISHED).size #判断是否有已发布的分班 - @exercise_unpublish_count = get_user_permission_course(exercise_ids, Exercise::UNPUBLISHED).size #判断是否有未发布的分班 - @course_all_members = @course.students #课堂的全部学生 - @exercise_all_users = @exercise.exercise_users - ex_common_ids = @exercise.common_published_ids(current_user.id) - @exercise_course_groups = @course.get_ex_published_course(ex_common_ids) - - #班级的选择 - if params[:exercise_group_id].present? - group_id = params[:exercise_group_id] - exercise_students = @course_all_members.course_find_by_ids("course_group_id", group_id) # 试卷所分班的全部人数 - user_ids = exercise_students.pluck(:user_id).reject(&:blank?) - @exercise_all_users = @exercise.exercise_users.exercise_commit_users(user_ids) - @course_all_members_count = @exercise_all_users.size - else - @exercise_users_list = @exercise.all_exercise_users(current_user.id) - @course_all_members_count = @exercise_users_list.size - end - @exercise_commit_users = @exercise_all_users.commit_exercise_by_status(1) #试卷的已提交用户 - @exercise_commit_user_ids = @exercise_commit_users.pluck(:user_id).uniq #已提交试卷的全部用户id - @exercise_commit_user_counts = @exercise_commit_users.size #试卷的已提交用户人数 - @exercise_status = @exercise.get_exercise_status(current_user) - - #提交率 - if @course_all_members_count == 0 - commit_percent = 0.00 - min_score = 0.0 - max_score = 0.0 - average_score = 0.0 - fail_counts = 0 - pass_counts = 0 - good_counts = 0 - best_counts = 0 - else - commit_percent = (@exercise_commit_user_counts / @course_all_members_count.to_f).round(3) - exercise_scores = @exercise_commit_users.pluck(:score).reject(&:blank?) - min_score = exercise_scores.min.present? ? exercise_scores.min : 0.0 - max_score = exercise_scores.max.present? ? exercise_scores.max : 0.0 - total_score = exercise_scores.sum.present? ? exercise_scores.sum : 0.0 - average_score = @exercise_commit_user_counts > 0 ? (total_score.round(1) / @exercise_commit_user_counts).round(1) : 0.0 - question_scores = @exercise.question_scores - fail_score = question_scores * 0.6.round(2) - pass_score = question_scores * 0.7.round(2) - good_score = question_scores * 0.9.round(2) - - fail_counts = exercise_scores.count {|a| a < fail_score} - pass_counts = exercise_scores.count {|a| a < pass_score && a >= fail_score} - good_counts = exercise_scores.count {|a| a < good_score && a >= pass_score} - best_counts = exercise_scores.count {|a| a >= good_score && a <= question_scores} - end - @counts_array = { - :commit_percent => commit_percent, - :min_score => min_score.to_s, - :max_score => max_score.to_s, - :average_score => average_score.to_s, - :fail_counts => fail_counts, - :pass_counts => pass_counts, - :good_counts => good_counts, - :best_counts => best_counts, - } - - @exercise_questions = @exercise.exercise_questions&.includes(:exercise_choices, :exercise_answers, :exercise_standard_answers, :exercise_shixun_challenges, :exercise_shixun_answers) - - percent_sort = "desc" - - if params[:sort].present? - percent_sort = params[:sort] - end - # @paging_type = "percent" - # # 按题型排序 - # if params[:sort].present? - # @paging_type = params[:sort].to_s - # end - - ques_result_all = exercise_commit_result(@exercise_questions, @exercise_commit_user_ids) - - #默认降序排列 - if percent_sort == "desc" - @question_result_hash = ques_result_all.sort_by {|s| s[:percent]}.reverse - else - @question_result_hash = ques_result_all.sort_by {|s| s[:percent]} - end - - @exercise_questions_count = @exercise_questions.size - @page = params[:page] || 1 - @limit = params[:limit] || 10 - @question_result_hash = Kaminari.paginate_array(@question_result_hash).page(@page).per(@limit) - end - - private - - def exercise_params - params.require(:exercise).permit(:exercise_name, :exercise_description, :course_id, :exercise_status, :user_id, :time, - :publish_time, :end_time, :show_result, :question_random, :choice_random, :is_public, - :score_open, :answer_open, :exercise_bank_id, :unified_setting, :show_statistic) - end - - def is_course_teacher - unless @user_course_identity < Course::STUDENT #为老师/助教/管理员 - normal_status(403, "...") - end - end - - #检查传入的参数内容是否符合 - def validates_exercise_params - normal_status(-1, "试卷标题不能为空!") if params[:exercise_name].blank? - normal_status(-1, "试卷标题不能超过60个字符") if (params[:exercise_name].length > 60) - normal_status(-1, "试卷须知不能超过100个字符") if (params[:exercise_description].present? && - params[:exercise_description].length > 100) - end - - #判断设置的时间是否合理 - def validate_publish_time - # 截止时间存在,且截止时间必须大于当前时间或发布时间 - unified_setting = params[:unified_setting] - publish_course = params[:publish_time_groups] - if @course.is_end - normal_status(-1, "课堂已结束不能再修改") - elsif unified_setting - ex_group_settings = @exercise.exercise_group_settings - if ex_group_settings.present? - p_time_present = ex_group_settings.publish_time_no_null.map(&:publish_time).min - if p_time_present && p_time_present < Time.now - normal_status(-1, "设置失败,存在已发布的分班") - end - elsif params[:publish_time].blank? - normal_status(-1, "发布时间不允许为空") - end - elsif unified_setting.present? && !unified_setting #非统一设置,分班不能为空 - if publish_course.present? - course_ids = publish_course.map {|a| a[:course_group_id]}.sum - publish_t = publish_course.map {|a| a[:publish_time]} - if course_ids.include?(nil) || course_ids.count == 0 - normal_status(-1, "请选择分班") - elsif publish_t.include?(nil) || publish_t.count == 0 - normal_status(-1, "发布时间不允许为空") - end - else - normal_status(-1, "请选择分班") - end - end - end - - def get_exercise - @exercise = Exercise.find_by(id: params[:id]) - if @exercise.blank? - normal_status(404, "试卷不存在") - else - @course = @exercise.course - normal_status(404, "课堂不存在") if @course.blank? - end - end - - def get_exercise_question_counts #获取试卷的问题数及总分数 - exercise_questions = @exercise.exercise_questions - @exercise_ques_count = exercise_questions.size # 全部的题目数 - @exercise_ques_scores = exercise_questions.pluck(:question_score).sum - - #单选题的数量及分数 - exercise_single_ques = exercise_questions.find_by_custom("question_type", Exercise::SINGLE) - @exercise_single_ques_count = exercise_single_ques.size - @exercise_single_ques_scores = exercise_single_ques.pluck(:question_score).sum - - #多选题的数量及分数 - exercise_double_ques = exercise_questions.find_by_custom("question_type", Exercise::MULTIPLE) - @exercise_double_ques_count = exercise_double_ques.size - @exercise_double_ques_scores = exercise_double_ques.pluck(:question_score).sum - - # 判断题数量及分数 - exercise_ques_judge = exercise_questions.find_by_custom("question_type", Exercise::JUDGMENT) - @exercise_ques_judge_count = exercise_ques_judge.size - @exercise_ques_judge_scores = exercise_ques_judge.pluck(:question_score).sum - - #填空题数量及分数 - exercise_ques_null = exercise_questions.find_by_custom("question_type", Exercise::COMPLETION) - @exercise_ques_null_count = exercise_ques_null.size - @exercise_ques_null_scores = exercise_ques_null.pluck(:question_score).sum - - #简答题数量及分数 - exercise_ques_main = exercise_questions.find_by_custom("question_type", Exercise::SUBJECTIVE) - @exercise_ques_main_count = exercise_ques_main.size - @exercise_ques_main_scores = exercise_ques_main.pluck(:question_score).sum - - #实训题数量及分数 - exercise_ques_shixun = exercise_questions.find_by_custom("question_type", Exercise::PRACTICAL) - @exercise_ques_shixun_count = exercise_ques_shixun.size - @exercise_ques_shixun_scores = exercise_ques_shixun.pluck(:question_score).sum - - @exercise_questions = @exercise_questions&.includes(:exercise_choices, :exercise_shixun_challenges, :exercise_answers, :exercise_shixun_answers, :exercise_answer_comments, :exercise_standard_answers) - - end - - #获取用户有权限的分班 - def get_user_permission_course(exercise_ids, status) - exercise_status = status.to_i #传入的试卷发布状态 - unpublish_group = [] - course_groups = [] - user_groups_id = @course.charge_group_ids(current_user) - exercises_all = Exercise.includes(:exercise_group_settings).where(id: exercise_ids) - exercises_all.each do |exercise| - if exercise.present? - if exercise.unified_setting #统一设置只有两种情况,全部发布,全部截止 - exercise_user_status = exercise.get_exercise_status(current_user) #当前用户的能看到的试卷 - if (exercise_user_status == exercise_status) || exercise_status == Exercise::DEADLINE #未发布的情况 - unpublish_group = unpublish_group + user_groups_id - end - else - ex_all_group_settings = exercise.exercise_group_settings - ex_group_settings = ex_all_group_settings.exercise_group_published.pluck(:course_group_id).uniq #问卷设置的班级 - if exercise_status == Exercise::UNPUBLISHED - unpublish_group = user_groups_id - ex_group_settings - elsif exercise_status == Exercise::DEADLINE - ex_ended_groups = ex_all_group_settings.exercise_group_ended.pluck(:course_group_id).uniq - ex_and_user = user_groups_id & ex_group_settings #用户已设置的分班 - unpublish_group = unpublish_group + ex_and_user - ex_ended_groups #已发布的全部班级减去截止的全部班级 - else - ex_ended_groups = ex_all_group_settings.exercise_group_ended.pluck(:course_group_id).uniq - ex_and_user = user_groups_id & ex_group_settings #用户已设置的分班 - unpublish_group = unpublish_group + ex_and_user - ex_ended_groups - end - end - end - end - Rails.logger.info("#####____________unpublish_group_______#######{unpublish_group}") - unpublish_group = unpublish_group.uniq - if unpublish_group.count > 0 - course_groups = CourseGroup.by_group_ids(unpublish_group) - end - course_groups - end - - def set_exercise_status(publish_time, end_time) - time_now_i = Time.now - if publish_time.present? && (publish_time <= time_now_i) && (end_time > time_now_i) - 2 - elsif publish_time.nil? || (publish_time.present? && publish_time > time_now_i) - 1 - elsif end_time.present? && (end_time <= time_now_i) - 3 - elsif end_time.present? && publish_time.present? && (end_time < publish_time) - normal_status(-1, "时间设置错误!") - else - 1 - end - end - - def check_course_public - unless @course.is_public == 1 # 0为私有,1为公开 - normal_status(403, "...") - end - end - - def check_user_id_start_answer #判断用户在开始答题时,是否有用户id传入,如果为老师,则id必需,否则为当前用户的id - user_login = params[:login] - if user_login.blank? && @user_course_identity < Course::STUDENT #id不存在,且当前为老师/管理员等 - normal_status(-1, "请输入学生登陆名!") - else - if @user_course_identity < Course::STUDENT || @exercise.score_open - @ex_answerer = user_login.blank? ? current_user : User.find_by(login: user_login) - else - @ex_answerer = current_user - end - - if @ex_answerer.blank? - normal_status(404, "答题用户不存在") - elsif @user_course_identity > Course::STUDENT && !@exercise.is_public - normal_status(403, "非公开试卷") - else - # @exercise_current_user_id = @ex_answerer.id || current_user.id - @exercise_current_user_id = @ex_answerer.id - end - end - end - - ## 判断开始答题页面的用户权限 - def check_user_on_answer - if @user_course_identity == Course::STUDENT && @exercise.get_exercise_status(current_user) == Exercise::UNPUBLISHED #试卷未发布,且当前用户不为老师/管理员 - normal_status(-1, "未发布试卷!") - elsif @user_course_identity > Course::STUDENT && (!@exercise.is_public || (@exercise.is_public && !@exercise.unified_setting)) ##不为课堂成员,且试卷不为公开的,或试卷公开,但不是统一设置的 - normal_status(-1, "试卷暂未公开!") - end - end - - def check_exercise_time - @answer_committed_user = @exercise.exercise_users.exercise_commit_users(current_user.id)&.first - if @answer_committed_user.blank? - normal_status(404, "答题用户不存在") - end - end - - #打回重做时的初步判断 - def check_exercise_status - @exercise_users = @exercise.all_exercise_users(current_user.id).commit_exercise_by_status(1) #当前教师所在分班的全部已提交的学生数 - if @exercise.get_exercise_status(current_user) != Exercise::PUBLISHED - normal_status(-1, "非提交中的试卷不允许打回重做!") - elsif @exercise_users.count < 1 - normal_status(-1, "暂无人提交试卷!") - end - end - - - #查看试题页面,当为学生时,除非试卷已截止,或已提交才可以查看 - def check_exercise_is_end - ex_status = @exercise.get_exercise_status(current_user) - @ex_user = @exercise.exercise_users.find_by(user_id: @exercise_current_user_id) #该试卷的回答者 - if @user_course_identity > Course::ASSISTANT_PROFESSOR - if ex_status == Exercise::UNPUBLISHED - normal_status(-1, "试卷未发布") - elsif @ex_user.present? && @ex_user.commit_status == 0 - normal_status(-1, "试卷未提交") - elsif params[:user_id].present? && current_user.id != params[:user_id] - normal_status(-1, "不能查看他人的试卷") - end - end - end - - #查看试卷是否选择为公开统计 - def check_exercise_public - if @user_course_identity > Course::ASSISTANT_PROFESSOR #当前为学生,试卷公开统计,且已截止,且已提交 - ex_user = @exercise.exercise_users.exercise_commit_users(current_user.id).first - unless @exercise.get_exercise_status(current_user) == Exercise::DEADLINE && ex_user.present? && ex_user.commit_status == 1 && - @exercise.show_statistic - normal_status(-1, "学生暂不能查看") - end - end - end - - def get_left_banner_id - left_banner_content = @course.course_modules.search_by_module_type("exercise") - if left_banner_content.present? - @left_banner_id = left_banner_content.first.id - @left_banner_name = left_banner_content.first.module_name - else - normal_status(404, "左侧导航不存在") - end - end - - def get_user_answer_status(exercise_questions, user_id, exercise, exercise_user_status) - @question_status = [] - @exercise_all_questions = [] - ex_question_random = exercise.question_random - question_answered = 0 - exercise_questions.each_with_index do |q, index| - if ex_question_random && exercise_user_status != Exercise::DEADLINE - ques_number = index + 1 - else - ques_number = q.question_number - end - ques_status = 0 - if q.question_type != Exercise::PRACTICAL - ques_vote = q.exercise_answers.select {|answer| answer.user_id == user_id} - - if ques_vote.present? - #其他题目,需回答的有内容,才会为已答,否则如内容为空,视为未答 - vote_answer_id = ques_vote.pluck(:exercise_choice_id).reject(&:blank?) - vote_text_count = ques_vote.pluck(:answer_text).reject(&:blank?).size - if q.question_type <= Exercise::JUDGMENT #选择题和判断题的时候,需要有选项,才算回答 - if vote_answer_id.size > 0 - ques_status = 1 - question_answered += 1 - end - else - if vote_text_count > 0 #主观题,必选有内容,才算回答 - ques_status = 1 - question_answered += 1 - end - end - end - else - if Myshixun.exists?(user_id: user_id, shixun_id: q.shixun_id) - ques_status = 1 - question_answered += 1 - end - end - question_status = { - :ques_id => q.id, - :ques_number => ques_number, #仅问题的显示位置变化,但是问题的question_number 不会变化,与之相关的choice/standard_answer/answer不会变化 - :ques_status => ques_status, - } - question_options = { - :question => q, - :ques_number => ques_number, - } - @question_status = @question_status.push(question_status).sort_by {|k| k[:ques_number]} - @exercise_all_questions = @exercise_all_questions.push(question_options).sort_by {|k| k[:ques_number]} - end - end - - #下一步也有check_on_users再进行判断 - def only_student_in - if @user_course_identity < Course::STUDENT - normal_status(-1, "老师身份不允许进入") - end - end - - #判断实训是否已选择 - def commit_shixun_present - question_shixun_ids = @exercise.exercise_questions.pluck(:shixun_id).reject(&:blank?) - shixun_id = params[:shixun_id] - @shixun = Shixun.find_by(id: shixun_id) - if shixun_id.present? && question_shixun_ids.include?(shixun_id) - normal_status(-1, "该实训已选择!") - elsif @shixun.blank? - normal_status(-1, "该实训不存在!") - end - end - - end @exercise_questions_count = @exercise_questions.size @page = params[:page] || 1 From e581771ec14286db7fbf3469cf761e27feafad4a Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Sat, 11 Jan 2020 17:33:04 +0800 Subject: [PATCH 121/156] =?UTF-8?q?=E8=AF=95=E5=8D=B7=E7=9A=84=E9=AA=8C?= =?UTF-8?q?=E8=AF=81=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/message_detail.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/message_detail.rb b/app/models/message_detail.rb index 9f5269bc5..d589ada3e 100644 --- a/app/models/message_detail.rb +++ b/app/models/message_detail.rb @@ -1,5 +1,5 @@ class MessageDetail < ApplicationRecord belongs_to :message, :touch => true - validates :content, length: { maximum: 5000, too_long: "内容不能超过5000个字符" } + validates :content, length: { maximum: 10000, too_long: "内容不能超过10000个字符" } end From 7ecac799d550d10bf5073187efad636e821a4006 Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Sat, 11 Jan 2020 17:50:47 +0800 Subject: [PATCH 122/156] =?UTF-8?q?=E7=BF=BB=E8=BD=AC=E8=AF=BE=E5=A0=82?= =?UTF-8?q?=EF=BC=9A=E5=85=AC=E5=BC=80=E8=AF=BE=EF=BC=8C=E5=AF=B9=E4=BA=8E?= =?UTF-8?q?=E9=9D=9E=E8=AF=BE=E5=A0=82=E6=88=90=E5=91=98=E4=B8=8D=E5=85=81?= =?UTF-8?q?=E8=AE=B8=E6=9F=A5=E7=9C=8B=E6=95=99=E5=B8=88=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E3=80=81=E5=AD=A6=E7=94=9F=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/courses_controller.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb index 753a3d942..0a6e95470 100644 --- a/app/controllers/courses_controller.rb +++ b/app/controllers/courses_controller.rb @@ -394,6 +394,7 @@ class CoursesController < ApplicationController # 教师列表以及教师搜索 def teachers + tip_exception(403, "无权限访问") if @course.excellent && @user_course_identity > Course::ASSISTANT_PROFESSOR @search_str = params[:search].present? ? params[:search].strip : "" if @course.try(:id) != 1309 || current_user.admin_or_business? || current_user.try(:id) == 15582 @@ -850,6 +851,8 @@ class CoursesController < ApplicationController # 学生列表(包括各个子分班的学生列表)及搜索 def students + tip_exception(403, "无权限访问") if @course.excellent && @user_course_identity > Course::ASSISTANT_PROFESSOR + search = params[:search].present? ? params[:search].strip : nil order = params[:order].present? ? params[:order].to_i : 1 sort = params[:sort].present? ? params[:sort] : "asc" From be4a2102fcf720e62c83d228c03b4c916bbc9a25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=98=8E?= <775174143@qq.com> Date: Sat, 11 Jan 2020 19:19:23 +0800 Subject: [PATCH 123/156] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/react/src/AppConfig.js | 2 +- .../tasks/GraduationTasksappraiseMainEditor.js | 18 ++++++++++++++---- .../Challenges/Challengesjupyter.js | 14 ++++++++------ 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/public/react/src/AppConfig.js b/public/react/src/AppConfig.js index 12e0043d5..02d554806 100644 --- a/public/react/src/AppConfig.js +++ b/public/react/src/AppConfig.js @@ -42,7 +42,7 @@ if (isDev) { // 老师 //debugType="teacher"; // 学生 -//debugType="student"; +debugType="student"; function railsgettimes(proxy) { diff --git a/public/react/src/modules/courses/graduation/tasks/GraduationTasksappraiseMainEditor.js b/public/react/src/modules/courses/graduation/tasks/GraduationTasksappraiseMainEditor.js index ec6979c19..376a45eb8 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduationTasksappraiseMainEditor.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduationTasksappraiseMainEditor.js @@ -20,7 +20,8 @@ class GraduationTasksappraiseMainEditor extends Component{ score: undefined, same_score: false, errorMessage: '', - numberErrorMessage: '' + numberErrorMessage: '', + errorMessagetype:false } } onSubmit = () => { @@ -37,7 +38,10 @@ class GraduationTasksappraiseMainEditor extends Component{ return; } if (!score && this.props.isAdmin()===false) { - this.setState( {errorMessage : '分数不能同时为空' }) + this.setState( { + errorMessage : '分数不能同时为空', + errorMessagetype:true + }) // this.props.showNotification('请先输入评阅说明') return; } @@ -142,6 +146,12 @@ class GraduationTasksappraiseMainEditor extends Component{ }); } onScoreChange = (val) => { + if(val){ + this.setState( { + errorMessage: '', + errorMessagetype:false + }) + } if (val > 100 ) { this.props.showNotification('不能大于100') this.setState({ score: 100 }) @@ -163,7 +173,7 @@ class GraduationTasksappraiseMainEditor extends Component{ this.setState({ same_score: e.target.checked }) //!this.state.same_score } render(){ - let { total_count, comments, pageCount, fileList, score, same_score, errorMessage, numberErrorMessage } = this.state + let { total_count, comments, errorMessagetype, fileList, score, same_score, errorMessage, numberErrorMessage } = this.state const { current_user, memo, showSameScore, placeholder } = this.props const isAdmin = this.props.isAdmin() const commentUploadProp = { @@ -215,7 +225,7 @@ class GraduationTasksappraiseMainEditor extends Component{ `} {this.props.title && {this.props.title}} + watch={false} height={160} className={errorMessage&&errorMessagetype!=true ? 'editorInputError' : ''} imageExpand={true}> { showSameScore == true &&
    整组同评 (选中,则本次评阅对象指小组全部成员,否则仅评阅此成员1人 ) diff --git a/public/react/src/modules/tpm/shixunchild/Challenges/Challengesjupyter.js b/public/react/src/modules/tpm/shixunchild/Challenges/Challengesjupyter.js index 61782d69f..9e50e44d5 100644 --- a/public/react/src/modules/tpm/shixunchild/Challenges/Challengesjupyter.js +++ b/public/react/src/modules/tpm/shixunchild/Challenges/Challengesjupyter.js @@ -87,7 +87,7 @@ class Challengesjupyter extends Component { // // } this.setState({ - opentitletype:true, + opentitletype:false, isopentitletype:"greater", boxoffsetHeigh:boxoffsetHeigh }) @@ -646,11 +646,13 @@ class Challengesjupyter extends Component { } {/*this.state.enlarge===false?"":*/} - {this.state.isopentitletype==="Less"?"":this.state.opentitletype===true?this.opentitle()} className={"pointer Breadcrumbfont color-grey-9 "}> - 阅读全文 - :this.opentitle()} className={"pointer Breadcrumbfont color-grey-9 "}> - 收起全文 - } + {/*{this.state.isopentitletype==="Less"?"":this.state.opentitletype===true?this.opentitle()} className={"pointer Breadcrumbfont color-grey-9 "}>*/} + {/* 阅读全文 */} + {/*:this.opentitle()} className={"pointer Breadcrumbfont color-grey-9 "}>*/} + {/* 收起全文 */} + {/*}*/} + +

    From c9bc9fbe1e5299b8ae2625b49e2a7efa283931b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=98=8E?= <775174143@qq.com> Date: Sat, 11 Jan 2020 19:19:45 +0800 Subject: [PATCH 124/156] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../graduation/tasks/GraduationTasksappraiseMainEditor.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/react/src/modules/courses/graduation/tasks/GraduationTasksappraiseMainEditor.js b/public/react/src/modules/courses/graduation/tasks/GraduationTasksappraiseMainEditor.js index 376a45eb8..1415414e4 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduationTasksappraiseMainEditor.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduationTasksappraiseMainEditor.js @@ -39,7 +39,7 @@ class GraduationTasksappraiseMainEditor extends Component{ } if (!score && this.props.isAdmin()===false) { this.setState( { - errorMessage : '分数不能同时为空', + errorMessage : '分数不能为空', errorMessagetype:true }) // this.props.showNotification('请先输入评阅说明') From 2ec0ffc1dbd95d6f9678414276d264be6ab93009 Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Sat, 11 Jan 2020 19:34:40 +0800 Subject: [PATCH 125/156] =?UTF-8?q?=E5=B8=96=E5=AD=90=E6=8A=9B=E5=BC=82?= =?UTF-8?q?=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/messages_controller.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/messages_controller.rb b/app/controllers/messages_controller.rb index 2b9d9d69f..0e28ccb4f 100644 --- a/app/controllers/messages_controller.rb +++ b/app/controllers/messages_controller.rb @@ -62,8 +62,8 @@ class MessagesController < ApplicationController end def reply - return normal_status(2, "回复内容不能为空") if params[:content].blank? - return normal_status(2, "回复内容不能超过2000字符") if params[:content].length > 2000 + return normal_status(-1, "回复内容不能为空") if params[:content].blank? + return normal_status(-1, "回复内容不能超过2000字符") if params[:content].length > 2000 @reply = Message.create!(board: @message.board, root_id: @message.root_id || @message.id, author: current_user, parent: @message, message_detail_attributes: { From 0b76c5d64892577e421f36f300369c04cecc51e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=98=8E?= <775174143@qq.com> Date: Sat, 11 Jan 2020 19:34:49 +0800 Subject: [PATCH 126/156] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/react/src/modules/forums/MemoDetail.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/react/src/modules/forums/MemoDetail.js b/public/react/src/modules/forums/MemoDetail.js index 9f3885906..792b24aa9 100644 --- a/public/react/src/modules/forums/MemoDetail.js +++ b/public/react/src/modules/forums/MemoDetail.js @@ -845,7 +845,7 @@ class MemoDetail extends Component {
    :
    -
    写评论1
    +
    写评论
    }
    From 079b5bb967bcf8a6e5795983a1554a30ebb8a07c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=98=8E?= <775174143@qq.com> Date: Sat, 11 Jan 2020 19:39:14 +0800 Subject: [PATCH 127/156] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/react/src/modules/tpm/NewHeader.js | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/public/react/src/modules/tpm/NewHeader.js b/public/react/src/modules/tpm/NewHeader.js index 572389b8a..5ca8e986b 100644 --- a/public/react/src/modules/tpm/NewHeader.js +++ b/public/react/src/modules/tpm/NewHeader.js @@ -1047,17 +1047,17 @@ submittojoinclass=(value)=>{ ` } -
  • - -
    -
    - 题库 -
    -
    -
    -
  • + {/*
  • */} + {/* */} + {/*
    */} + {/*
    */} + {/* 题库*/} + {/*
    */} + {/*
    */} + {/*
    */} + {/*
  • */}
  • Date: Sat, 11 Jan 2020 20:18:52 +0800 Subject: [PATCH 128/156] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/react/src/AppConfig.js | 2 +- public/react/src/context/TPIContextProvider.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/public/react/src/AppConfig.js b/public/react/src/AppConfig.js index 02d554806..12e0043d5 100644 --- a/public/react/src/AppConfig.js +++ b/public/react/src/AppConfig.js @@ -42,7 +42,7 @@ if (isDev) { // 老师 //debugType="teacher"; // 学生 -debugType="student"; +//debugType="student"; function railsgettimes(proxy) { diff --git a/public/react/src/context/TPIContextProvider.js b/public/react/src/context/TPIContextProvider.js index ed7eb2210..bb1e0bef4 100644 --- a/public/react/src/context/TPIContextProvider.js +++ b/public/react/src/context/TPIContextProvider.js @@ -32,7 +32,7 @@ import _ from 'lodash' import TPIContext from './TPIContext' import { EDU_ADMIN, EDU_SHIXUN_MANAGER, EDU_SHIXUN_MEMBER, EDU_CERTIFICATION_TEACHER - , EDU_GAME_MANAGER, EDU_TEACHER, EDU_NORMAL, EDU_BUSINESS, CNotificationHOC } from 'educoder' + , EDU_GAME_MANAGER, EDU_TEACHER, EDU_NORMAL, EDU_BUSINESS, CNotificationHOC ,getRandomNumber} from 'educoder' import { MuiThemeProvider, createMuiTheme, withStyles } from 'material-ui/styles'; import MUIDialogStyleUtil from '../modules/page/component/MUIDialogStyleUtil' @@ -176,7 +176,7 @@ class TPIContextProvider extends Component { testPath = 'http://test-newweb.educoder.net' } // var url = `${testPath}/api/v1/games/${ game.identifier }/cost_time` - var url = `${testPath}/api/tasks/${ game.identifier }/cost_time` + var url = `${testPath}/api/tasks/${ game.identifier }/cost_time${getRandomNumber()}` window.$.ajax({ type: 'get', url: url, From 06bae0facf6ef87cabb1232deccd26c8d545b730 Mon Sep 17 00:00:00 2001 From: daiao <358551898@qq.com> Date: Sat, 11 Jan 2020 20:31:16 +0800 Subject: [PATCH 129/156] =?UTF-8?q?=E6=97=B6=E9=97=B4=E8=AF=BE=E7=A8=8B?= =?UTF-8?q?=E7=BB=9F=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/subjects_controller.rb | 1 + app/views/subjects/statistics_info.json.jbuilder | 6 ++++++ 2 files changed, 7 insertions(+) create mode 100644 app/views/subjects/statistics_info.json.jbuilder diff --git a/app/controllers/subjects_controller.rb b/app/controllers/subjects_controller.rb index d58c4a9c3..47863a3a0 100644 --- a/app/controllers/subjects_controller.rb +++ b/app/controllers/subjects_controller.rb @@ -13,6 +13,7 @@ class SubjectsController < ApplicationController include ApplicationHelper include SubjectsHelper include GitCommon + include CustomSortable def index @tech_system = current_laboratory.subject_repertoires diff --git a/app/views/subjects/statistics_info.json.jbuilder b/app/views/subjects/statistics_info.json.jbuilder new file mode 100644 index 000000000..b31e41b31 --- /dev/null +++ b/app/views/subjects/statistics_info.json.jbuilder @@ -0,0 +1,6 @@ +json.status 0 +json.message "success" +json.data do + json.subject_info @subject.subject_record + json.other_info @data +end \ No newline at end of file From 72cea0893900ceceddc6703c1c2dfbe2eb61bddf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=98=8E?= <775174143@qq.com> Date: Sat, 11 Jan 2020 20:33:44 +0800 Subject: [PATCH 130/156] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../react/src/modules/courses/coursesDetail/CoursesLeftNav.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/public/react/src/modules/courses/coursesDetail/CoursesLeftNav.js b/public/react/src/modules/courses/coursesDetail/CoursesLeftNav.js index c37b45c84..ba8fe27b0 100644 --- a/public/react/src/modules/courses/coursesDetail/CoursesLeftNav.js +++ b/public/react/src/modules/courses/coursesDetail/CoursesLeftNav.js @@ -549,6 +549,10 @@ class Coursesleftnav extends Component{ window.location.href=`/courses/${coursesId}/boards/${result.data.category_id}`; } + if(positiontype!="course_groups"){ + this.updasaveNavmoda() + } + if(positiontype==="course_groups"){ window.location.href=`/courses/${coursesId}/course_groups/${result.data.group_id}`; } From 6f610eebd26e9c93ffef348d9e6ea864ccbbe95d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=98=8E?= <775174143@qq.com> Date: Sat, 11 Jan 2020 20:50:34 +0800 Subject: [PATCH 131/156] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modules/page/layers/TaskResultLayer.js | 55 +++++++++++-------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/public/react/src/modules/page/layers/TaskResultLayer.js b/public/react/src/modules/page/layers/TaskResultLayer.js index 9e096b7b3..f4ccea8f7 100644 --- a/public/react/src/modules/page/layers/TaskResultLayer.js +++ b/public/react/src/modules/page/layers/TaskResultLayer.js @@ -14,6 +14,7 @@ import passpartImg from '../../../images/tpi/passpart.png' import empiricgreenImg from '../../../images/tpi/empiricgreen.png' import { trigger } from 'educoder'; +import SecondTab from "../../paths/SchoolStatistics/SecondTab"; class TaskResultLayer extends Component { @@ -29,7 +30,7 @@ class TaskResultLayer extends Component { } componentWillReceiveProps(newProps, newContext) { - if (newProps.currentGamePassed && (!this.props.currentGamePassed + if (newProps.currentGamePassed && (!this.props.currentGamePassed || (newProps.currentGamePassed !== this.props.currentGamePassed ))) { // this.fakeRanking = this._fakeRanking() const $ = window.$; @@ -51,10 +52,10 @@ class TaskResultLayer extends Component { } } } - + onStarChange(challenge, index, value) { this.props.onStarChange(challenge, index, value); - + this.setState({ stared: value ? true : false, }) @@ -87,11 +88,11 @@ class TaskResultLayer extends Component { // this.context.router.push('/sample'); if (goNext === true) { if (next_game) { // https://www.trustie.net/issues/18573 - this.goNext = true; + this.goNext = true; } // 隐藏掉效果查看页面 window.$('#picture_display').hide() - } + } this.props.onGamePassed(); this.setState({ stared: false @@ -110,9 +111,9 @@ class TaskResultLayer extends Component { // return; // } // const { showLanguagePictrue } = this.props.challenge; - // if ( prevProps.challenge.showLanguagePictrue != showLanguagePictrue && + // if ( prevProps.challenge.showLanguagePictrue != showLanguagePictrue && // showLanguagePictrue == true ) { - + // } // } initEffectDisplayServerTimer = () => { @@ -128,7 +129,7 @@ class TaskResultLayer extends Component { this.setState({ timeRemain }) }, 1000) }) - + } componentWillUnmount() { this.intervalHandler && clearInterval(this.intervalHandler); @@ -162,7 +163,7 @@ class TaskResultLayer extends Component { // const fakeRanking = this.fakeRanking; return (
    - {currentGamePassed ? + {currentGamePassed ?
    @@ -174,52 +175,60 @@ class TaskResultLayer extends Component {

    {currentPassedGameGainExperience >= 0 ? `+${currentPassedGameGainExperience}` : '+0'} -

    +

    - +
    - { !game.star ? + { !game.star ?

    您的评价决定老师的江湖地位~

    this.onStarChange(this.props.game, this.props.challenge.position, value)} - /> + />
    : ''} -

    +

    {/*下一关*/} this.onFinish(true)}>{ next_game ? '下一关' : '完成'} - { challenge.showLanguagePictrue && + { challenge.showLanguagePictrue && this.onFinish()}> { `查看效果` } {/* ${ moment(this.state.timeRemain * 1000).format('mm:ss') } */} - + } - {/* - - (this.state.timeRemain ? + {/* + + (this.state.timeRemain ? - - + + : {}} style={{ backgroundColor: 'gray'}}> { `查看效果` } - + ) */} - {/* + {/* 注意:效果查看服务只会保留5分钟 效果查看服务已被终止运行,需要重新评测后才能查看 */} From 21c6e3ba7bcc6edb83b1257cc51c291588150c11 Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Sun, 12 Jan 2020 10:58:24 +0800 Subject: [PATCH 132/156] =?UTF-8?q?=E8=AF=95=E5=8D=B7=E7=9A=84=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E9=9B=86=E5=BE=97=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/helpers/exercises_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/helpers/exercises_helper.rb b/app/helpers/exercises_helper.rb index cf9aec815..4b18ccba2 100644 --- a/app/helpers/exercises_helper.rb +++ b/app/helpers/exercises_helper.rb @@ -530,7 +530,7 @@ module ExercisesHelper exercise_cha_score = 0.0 answer_status = 0 # if game.status == 2 && game.final_score >= 0 - if game.final_score > 0 && game.end_time && game.end_time < exercise_end_time + if game.final_score > 0 && (game.end_time.nil? && game.end_time < exercise_end_time) exercise_cha_score = game.real_score(exercise_cha.question_score) # exercise_cha_score = exercise_cha.question_score #每一关卡的得分 answer_status = 1 From 5a6c58a0f61aad60dcaf0434e22b50f1bbc6c7cc Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Sun, 12 Jan 2020 10:59:10 +0800 Subject: [PATCH 133/156] =?UTF-8?q?=E8=AF=95=E5=8D=B7=E6=8C=89=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E9=9B=86=E7=BB=99=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/helpers/exercises_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/helpers/exercises_helper.rb b/app/helpers/exercises_helper.rb index 4b18ccba2..eaeb458a3 100644 --- a/app/helpers/exercises_helper.rb +++ b/app/helpers/exercises_helper.rb @@ -530,7 +530,7 @@ module ExercisesHelper exercise_cha_score = 0.0 answer_status = 0 # if game.status == 2 && game.final_score >= 0 - if game.final_score > 0 && (game.end_time.nil? && game.end_time < exercise_end_time) + if game.final_score > 0 && (game.end_time.nil? || game.end_time < exercise_end_time) exercise_cha_score = game.real_score(exercise_cha.question_score) # exercise_cha_score = exercise_cha.question_score #每一关卡的得分 answer_status = 1 From ee3444394572d84ad834a67b2a1f6eb1fbc92d81 Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Sun, 12 Jan 2020 11:14:37 +0800 Subject: [PATCH 134/156] =?UTF-8?q?=E8=AF=95=E5=8D=B7=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E8=BF=81=E7=A7=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...00112030419_migrate_3176_exercise_score.rb | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 db/migrate/20200112030419_migrate_3176_exercise_score.rb diff --git a/db/migrate/20200112030419_migrate_3176_exercise_score.rb b/db/migrate/20200112030419_migrate_3176_exercise_score.rb new file mode 100644 index 000000000..449a87578 --- /dev/null +++ b/db/migrate/20200112030419_migrate_3176_exercise_score.rb @@ -0,0 +1,50 @@ +class Migrate3176ExerciseScore < ActiveRecord::Migration[5.2] + + def calculate_student_score(exercise,user) + score5 = 0.0 #实训题 + exercise_end_time = exercise.end_time + exercise_questions = exercise.exercise_questions.includes(:exercise_standard_answers,:exercise_shixun_challenges) + exercise_questions.each do |q| + if q.question_type == 5 + q.exercise_shixun_challenges.each do |exercise_cha| + game = Game.user_games(user.id,exercise_cha.challenge_id)&.first #当前用户的关卡 + if game.present? + exercise_cha_score = 0.0 + answer_status = 0 + # if game.status == 2 && game.final_score >= 0 + if game.final_score > 0 && (game.end_time.nil? || game.end_time < exercise_end_time) + exercise_cha_score = game.real_score(exercise_cha.question_score) + # exercise_cha_score = exercise_cha.question_score #每一关卡的得分 + answer_status = 1 + end + ex_shixun_answer_content = exercise_cha.exercise_shixun_answers.find_by(user_id:user.id,exercise_question_id:q.id) + if ex_shixun_answer_content.present? && !ex_shixun_answer_content.score >0 #把关卡的答案存入试卷的实训里 + ex_shixun_answer_content.update_attributes!(score:exercise_cha_score.round(1),status:answer_status) + end + score5 += exercise_cha_score + else + score5 += 0.0 + end + end + end + end + score5 + end + + def change + exercise = Exercise.find_by(id: 3176) + if exercise + exercise_users = exercise.exercise_users.where("start_at is not null") + exercise_users.each do |exercise_user| + calculate_score = calculate_student_score(exercise, exercise_user.user) + subjective_score = exercise_user.subjective_score + total_score_subjective_score = subjective_score < 0.0 ? 0.0 : subjective_score + total_score = calculate_score + total_score_subjective_score + if exercise_user.end_at.present? + exercise_user.update_attributes!(score:total_score,objective_score:calculate_score) + end + puts exercise_user.id + end + end + end +end From b4d6c003821d6ba05a80194ce67ce1ebe124db83 Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Sun, 12 Jan 2020 11:21:18 +0800 Subject: [PATCH 135/156] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db/migrate/20200111024736_add_index_for_subject_records.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/migrate/20200111024736_add_index_for_subject_records.rb b/db/migrate/20200111024736_add_index_for_subject_records.rb index c27c9b9ae..e196c407f 100644 --- a/db/migrate/20200111024736_add_index_for_subject_records.rb +++ b/db/migrate/20200111024736_add_index_for_subject_records.rb @@ -1,6 +1,6 @@ class AddIndexForSubjectRecords < ActiveRecord::Migration[5.2] def change - remove_index :subject_records, :subject_id + # remove_index :subject_records, :subject_id add_index :subject_records, :subject_id, unique: true end end From f4a95fa206514fb5c950c39db69ac3dbdaaf7df9 Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Sun, 12 Jan 2020 11:50:16 +0800 Subject: [PATCH 136/156] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db/migrate/20200112030419_migrate_3176_exercise_score.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/migrate/20200112030419_migrate_3176_exercise_score.rb b/db/migrate/20200112030419_migrate_3176_exercise_score.rb index 449a87578..e96931f79 100644 --- a/db/migrate/20200112030419_migrate_3176_exercise_score.rb +++ b/db/migrate/20200112030419_migrate_3176_exercise_score.rb @@ -18,7 +18,7 @@ class Migrate3176ExerciseScore < ActiveRecord::Migration[5.2] answer_status = 1 end ex_shixun_answer_content = exercise_cha.exercise_shixun_answers.find_by(user_id:user.id,exercise_question_id:q.id) - if ex_shixun_answer_content.present? && !ex_shixun_answer_content.score >0 #把关卡的答案存入试卷的实训里 + if ex_shixun_answer_content.present? && !(ex_shixun_answer_content.score >0) #把关卡的答案存入试卷的实训里 ex_shixun_answer_content.update_attributes!(score:exercise_cha_score.round(1),status:answer_status) end score5 += exercise_cha_score From ab089c2cc5ef9a943c13e5c88814faf829765bf3 Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Sun, 12 Jan 2020 11:53:27 +0800 Subject: [PATCH 137/156] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...00112035304_migrate_3517_exercise_score.rb | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 db/migrate/20200112035304_migrate_3517_exercise_score.rb diff --git a/db/migrate/20200112035304_migrate_3517_exercise_score.rb b/db/migrate/20200112035304_migrate_3517_exercise_score.rb new file mode 100644 index 000000000..821b2bbd8 --- /dev/null +++ b/db/migrate/20200112035304_migrate_3517_exercise_score.rb @@ -0,0 +1,49 @@ +class Migrate3517ExerciseScore < ActiveRecord::Migration[5.2] + def calculate_student_score(exercise,user) + score5 = 0.0 #实训题 + exercise_end_time = exercise.end_time + exercise_questions = exercise.exercise_questions.includes(:exercise_standard_answers,:exercise_shixun_challenges) + exercise_questions.each do |q| + if q.question_type == 5 + q.exercise_shixun_challenges.each do |exercise_cha| + game = Game.user_games(user.id,exercise_cha.challenge_id)&.first #当前用户的关卡 + if game.present? + exercise_cha_score = 0.0 + answer_status = 0 + # if game.status == 2 && game.final_score >= 0 + if game.final_score > 0 && (game.end_time.nil? || game.end_time < exercise_end_time) + exercise_cha_score = game.real_score(exercise_cha.question_score) + # exercise_cha_score = exercise_cha.question_score #每一关卡的得分 + answer_status = 1 + end + ex_shixun_answer_content = exercise_cha.exercise_shixun_answers.find_by(user_id:user.id,exercise_question_id:q.id) + if ex_shixun_answer_content.present? && !(ex_shixun_answer_content.score >0) #把关卡的答案存入试卷的实训里 + ex_shixun_answer_content.update_attributes!(score:exercise_cha_score.round(1),status:answer_status) + end + score5 += exercise_cha_score + else + score5 += 0.0 + end + end + end + end + score5 + end + + def change + exercise = Exercise.find_by(id: 3517) + if exercise + exercise_users = exercise.exercise_users.where("start_at is not null") + exercise_users.each do |exercise_user| + calculate_score = calculate_student_score(exercise, exercise_user.user) + subjective_score = exercise_user.subjective_score + total_score_subjective_score = subjective_score < 0.0 ? 0.0 : subjective_score + total_score = calculate_score + total_score_subjective_score + if exercise_user.end_at.present? + exercise_user.update_attributes!(score:total_score,objective_score:calculate_score) + end + puts exercise_user.id + end + end + end +end From 185a64dce29145a5eba64b78c86bc19ca52ef86f Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Mon, 13 Jan 2020 10:02:45 +0800 Subject: [PATCH 138/156] =?UTF-8?q?=E4=BA=A4=E6=B5=81=E9=97=AE=E7=AD=94?= =?UTF-8?q?=EF=BC=9A=E5=8F=91=E9=80=81=E8=AF=84=E8=AE=BA=EF=BC=8C=E9=9C=80?= =?UTF-8?q?=E8=A6=81=E5=9C=A8=E7=8E=B0=E6=9C=89=E6=B5=81=E7=A8=8B=E7=9A=84?= =?UTF-8?q?=E5=9F=BA=E7=A1=80=E4=B8=8A=E5=A2=9E=E5=8A=A0=E2=80=9C=E5=AE=8C?= =?UTF-8?q?=E5=96=84=E8=B5=84=E6=96=99=E2=80=9D=E7=9A=84check=E5=92=8C?= =?UTF-8?q?=E5=BC=95=E5=AF=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/memos_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/memos_controller.rb b/app/controllers/memos_controller.rb index b80bfed32..c0ea8d601 100644 --- a/app/controllers/memos_controller.rb +++ b/app/controllers/memos_controller.rb @@ -1,6 +1,6 @@ class MemosController < ApplicationController before_action :require_login, except: [:show, :index] - before_action :check_account, only: [:new, :create] + before_action :check_account, only: [:new, :create, :reply] before_action :set_memo, only: [:show, :edit, :update, :destroy, :sticky_or_cancel, :hidden, :more_reply] before_action :validate_memo_params, only: [:create, :update] before_action :owner_or_admin, only: [:edit, :update, :destroy] From b6cdd2ed1aaf3311d38da10393f21589d4ddd5cc Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Mon, 13 Jan 2020 10:08:25 +0800 Subject: [PATCH 139/156] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E7=89=88=E8=B7=B3?= =?UTF-8?q?=E8=BF=87=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/application_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index fdb41c114..e0639de3f 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -23,7 +23,7 @@ class ApplicationController < ActionController::Base # 所有请求必须合法签名 def check_sign - if !Rails.env.development? + if !Rails.env.development? && EduSetting.get("host_name") != "https://test-newweb.educoder.net" Rails.logger.info("66666 #{params}") # suffix = request.url.split(".").last.split("?").first # suffix_arr = ["xls", "xlsx", "pdf", "zip"] # excel文件先注释 From 457c629b9ea59034bc663789b5bbfbc245deb6f8 Mon Sep 17 00:00:00 2001 From: daiao <358551898@qq.com> Date: Mon, 13 Jan 2020 10:30:03 +0800 Subject: [PATCH 140/156] =?UTF-8?q?=E8=B0=83=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/application_controller.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index e0639de3f..ed839eccf 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -23,6 +23,8 @@ class ApplicationController < ActionController::Base # 所有请求必须合法签名 def check_sign + Rails.logger.info("#####################request: #{request.headers}") + Rails.logger.info("#####################type: #{request.type}") if !Rails.env.development? && EduSetting.get("host_name") != "https://test-newweb.educoder.net" Rails.logger.info("66666 #{params}") # suffix = request.url.split(".").last.split("?").first From ec8e92c5f616bdb7ae8f5e8bd0a8349e28f5b8ff Mon Sep 17 00:00:00 2001 From: daiao <358551898@qq.com> Date: Mon, 13 Jan 2020 10:31:09 +0800 Subject: [PATCH 141/156] =?UTF-8?q?=E8=B0=83=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/application_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index ed839eccf..9faa14593 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -24,7 +24,7 @@ class ApplicationController < ActionController::Base # 所有请求必须合法签名 def check_sign Rails.logger.info("#####################request: #{request.headers}") - Rails.logger.info("#####################type: #{request.type}") + #Rails.logger.info("#####################type: #{request.type}") if !Rails.env.development? && EduSetting.get("host_name") != "https://test-newweb.educoder.net" Rails.logger.info("66666 #{params}") # suffix = request.url.split(".").last.split("?").first From b2ad28591b418980713992e0c5480dacd982e69d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=98=8E?= <775174143@qq.com> Date: Mon, 13 Jan 2020 10:40:09 +0800 Subject: [PATCH 142/156] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modules/courses/graduation/tasks/GraduationTaskDetail.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/react/src/modules/courses/graduation/tasks/GraduationTaskDetail.js b/public/react/src/modules/courses/graduation/tasks/GraduationTaskDetail.js index 44bcf5777..3330f9389 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduationTaskDetail.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduationTaskDetail.js @@ -523,7 +523,7 @@ class GraduationTaskDetail extends Component{ 导出

  • :""} {questionslist.work_status===undefined||questionslist.work_status===null||questionslist.work_status.length===0?"":questionslist.work_status.map((item,key)=>{ From b4f6f5be639b4adf08c38d4e3b60cd67f90f31ec Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Mon, 13 Jan 2020 10:59:20 +0800 Subject: [PATCH 143/156] =?UTF-8?q?=E6=AF=95=E8=AE=BE=E4=BD=9C=E5=93=81?= =?UTF-8?q?=E9=99=84=E4=BB=B6=E5=AF=BC=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/helpers/export_helper.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/helpers/export_helper.rb b/app/helpers/export_helper.rb index 8b61ca2b6..a5268a789 100644 --- a/app/helpers/export_helper.rb +++ b/app/helpers/export_helper.rb @@ -851,7 +851,8 @@ module ExportHelper def make_zip_name(work, file_name="") Rails.logger.info("######################file_name: #{file_name}") # name = file_name === "" ? "" : (file_name[0, file_name.rindex('.')]+"_") - "#{work&.homework_common.course&.user_group_name(work.user_id)}_#{work&.user&.student_id}_#{work&.user&.real_name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}" + course = work&.homework_common.course || work&.graduation_task.course + "#{course&.user_group_name(work.user_id)}_#{work&.user&.student_id}_#{work&.user&.real_name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}" end def zipping(zip_name_refer, files_paths, output_path, is_attachment=false, not_exist_file=[]) From 39fa3c8096d94a6493557d02a56c137fb3317c40 Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Mon, 13 Jan 2020 11:04:03 +0800 Subject: [PATCH 144/156] =?UTF-8?q?=E6=AF=95=E8=AE=BE=E4=BD=9C=E5=93=81?= =?UTF-8?q?=E9=99=84=E4=BB=B6=E5=AF=BC=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/helpers/export_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/helpers/export_helper.rb b/app/helpers/export_helper.rb index a5268a789..b7a4d4def 100644 --- a/app/helpers/export_helper.rb +++ b/app/helpers/export_helper.rb @@ -851,7 +851,7 @@ module ExportHelper def make_zip_name(work, file_name="") Rails.logger.info("######################file_name: #{file_name}") # name = file_name === "" ? "" : (file_name[0, file_name.rindex('.')]+"_") - course = work&.homework_common.course || work&.graduation_task.course + course = work&.homework_common&.course || work&.graduation_task&.course "#{course&.user_group_name(work.user_id)}_#{work&.user&.student_id}_#{work&.user&.real_name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}" end From 1c7db6bef9f2b87ca5f321d98d0af153eb9351a0 Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Mon, 13 Jan 2020 11:06:56 +0800 Subject: [PATCH 145/156] =?UTF-8?q?=E6=AF=95=E8=AE=BE=E4=BD=9C=E5=93=81?= =?UTF-8?q?=E9=99=84=E4=BB=B6=E5=AF=BC=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/helpers/export_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/helpers/export_helper.rb b/app/helpers/export_helper.rb index b7a4d4def..64ad114bd 100644 --- a/app/helpers/export_helper.rb +++ b/app/helpers/export_helper.rb @@ -851,7 +851,7 @@ module ExportHelper def make_zip_name(work, file_name="") Rails.logger.info("######################file_name: #{file_name}") # name = file_name === "" ? "" : (file_name[0, file_name.rindex('.')]+"_") - course = work&.homework_common&.course || work&.graduation_task&.course + course = work.is_a?(StudentWork) ? work&.homework_common&.course : work&.graduation_task&.course "#{course&.user_group_name(work.user_id)}_#{work&.user&.student_id}_#{work&.user&.real_name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}" end From 573cf053445c8756cdc8107648693463c541806c Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Mon, 13 Jan 2020 11:14:30 +0800 Subject: [PATCH 146/156] =?UTF-8?q?=E9=99=84=E4=BB=B6=E7=9A=84=E5=AF=BC?= =?UTF-8?q?=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/helpers/export_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/helpers/export_helper.rb b/app/helpers/export_helper.rb index a5268a789..64ad114bd 100644 --- a/app/helpers/export_helper.rb +++ b/app/helpers/export_helper.rb @@ -851,7 +851,7 @@ module ExportHelper def make_zip_name(work, file_name="") Rails.logger.info("######################file_name: #{file_name}") # name = file_name === "" ? "" : (file_name[0, file_name.rindex('.')]+"_") - course = work&.homework_common.course || work&.graduation_task.course + course = work.is_a?(StudentWork) ? work&.homework_common&.course : work&.graduation_task&.course "#{course&.user_group_name(work.user_id)}_#{work&.user&.student_id}_#{work&.user&.real_name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}" end From 1ecf433fc5cc084eef5b1babc563ade9bd251d7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=98=8E?= <775174143@qq.com> Date: Mon, 13 Jan 2020 11:48:49 +0800 Subject: [PATCH 147/156] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/images/educoder/xcx/weixinhome.png | Bin 0 -> 54273 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 public/images/educoder/xcx/weixinhome.png diff --git a/public/images/educoder/xcx/weixinhome.png b/public/images/educoder/xcx/weixinhome.png new file mode 100644 index 0000000000000000000000000000000000000000..0ba56d1b6a64d80ecbada157231fabb19fbfb96d GIT binary patch literal 54273 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 E0eq`7f&c&j literal 0 HcmV?d00001 From 1fa2fe4ad3b6ffc0d2adee088eb2e4980f118ae1 Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Mon, 13 Jan 2020 14:37:53 +0800 Subject: [PATCH 148/156] =?UTF-8?q?=E8=B0=83=E6=95=B4=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E8=BA=AB=E4=BB=BD=E7=9A=84api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/users/interests_controller.rb | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/app/controllers/users/interests_controller.rb b/app/controllers/users/interests_controller.rb index 93f2345f1..06470f553 100644 --- a/app/controllers/users/interests_controller.rb +++ b/app/controllers/users/interests_controller.rb @@ -9,18 +9,18 @@ class Users::InterestsController < Users::BaseController extension = current_user.user_extension || current_user.build_user_extension return render_error('请选择职业') unless %w(teacher student professional).include?(identity) - interest_ids = Array.wrap(params[:interest_ids]).map(&:to_i) - return render_error('请选择兴趣') if interest_ids.blank? + # interest_ids = Array.wrap(params[:interest_ids]).map(&:to_i) + # return render_error('请选择兴趣') if interest_ids.blank? ActiveRecord::Base.transaction do extension.update_column(:identity, identity) # 兴趣 - UserInterest.bulk_insert(:user_id, :repertoire_id) do |worker| - (Repertoire.pluck(:id) & interest_ids).each do |repertoire_id| - worker.add(user_id: current_user.id, repertoire_id: repertoire_id) - end - end + # UserInterest.bulk_insert(:user_id, :repertoire_id) do |worker| + # (Repertoire.pluck(:id) & interest_ids).each do |repertoire_id| + # worker.add(user_id: current_user.id, repertoire_id: repertoire_id) + # end + # end end render_ok From 2e6222bca279fbfc70dd83d25d6607a18d1b70f2 Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Mon, 13 Jan 2020 15:23:36 +0800 Subject: [PATCH 149/156] =?UTF-8?q?=E9=A2=98=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/hacks_controller.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/controllers/hacks_controller.rb b/app/controllers/hacks_controller.rb index 0e98e771b..6eb454feb 100644 --- a/app/controllers/hacks_controller.rb +++ b/app/controllers/hacks_controller.rb @@ -232,7 +232,11 @@ class HacksController < ApplicationController hacks = Hack.select(select_sql).mine(current_user.id) else # 全部包括已经发布的,和我的未发布的 - hacks = Hack.select(select_sql).published.opening.or(Hack.select(select_sql).unpublish.mine(current_user.id)) + if current_user.admin_or_business? + hacks = Hack.select(select_sql) + else + hacks = Hack.select(select_sql).published.opening.or(Hack.select(select_sql).unpublish.mine(current_user.id)) + end end # 搜索 if params[:search] From 6ebb02775dfbe64f8cc6bd0a1efa952d724b50e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=98=8E?= <775174143@qq.com> Date: Mon, 13 Jan 2020 17:00:45 +0800 Subject: [PATCH 150/156] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/images/educoder/xcx/Professional.png | Bin 0 -> 23683 bytes public/images/educoder/xcx/Student.png | Bin 0 -> 20682 bytes public/images/educoder/xcx/Teacher.png | Bin 0 -> 36789 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 public/images/educoder/xcx/Professional.png create mode 100644 public/images/educoder/xcx/Student.png create mode 100644 public/images/educoder/xcx/Teacher.png diff --git a/public/images/educoder/xcx/Professional.png b/public/images/educoder/xcx/Professional.png new file mode 100644 index 0000000000000000000000000000000000000000..8273d9e795355254f0383f743cf8a66ea5e65647 GIT binary patch literal 23683 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�i& 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 Date: Mon, 13 Jan 2020 17:07:06 +0800 Subject: [PATCH 151/156] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/weapps/shared/_user.json.jbuilder | 1 + 1 file changed, 1 insertion(+) diff --git a/app/views/weapps/shared/_user.json.jbuilder b/app/views/weapps/shared/_user.json.jbuilder index be67384cc..53212ec15 100644 --- a/app/views/weapps/shared/_user.json.jbuilder +++ b/app/views/weapps/shared/_user.json.jbuilder @@ -7,6 +7,7 @@ json.admin user.admin? json.business user.business? json.is_teacher user.user_extension&.teacher? json.user_identity user.identity +json.identity user.user_extension&.identity json.tidding_count 0 json.user_phone_binded user.phone.present? json.phone user.phone From 0f822648408d4b4aaca4672be3874af05ebc36d2 Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Mon, 13 Jan 2020 17:18:23 +0800 Subject: [PATCH 152/156] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E5=8F=91=E9=80=81?= =?UTF-8?q?=E9=AA=8C=E8=AF=81=E7=A0=81=E5=8A=A0=E5=AF=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../weapps/verification_codes_controller.rb | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/app/controllers/weapps/verification_codes_controller.rb b/app/controllers/weapps/verification_codes_controller.rb index 7590c49f7..1876014db 100644 --- a/app/controllers/weapps/verification_codes_controller.rb +++ b/app/controllers/weapps/verification_codes_controller.rb @@ -19,11 +19,10 @@ class Weapps::VerificationCodesController < Weapps::BaseController return render_error('请输入正确的邮箱或手机号') end - code = %W(0 1 2 3 4 5 6 7 8 9) - verification_code = code.sample(6).join send_type = login =~ /^1\d{10}$/ ? 1 : 8 - # 记录验证码 - check_verification_code(verification_code, send_type, login) + + # 发送验证码 + send_code(send_type, login) render_ok end @@ -40,12 +39,21 @@ class Weapps::VerificationCodesController < Weapps::BaseController return render_error('请输入正确的邮箱或手机号') end + send_type = login =~ /^1\d{10}$/ ? 2 : 3 + + # 发送验证码 + send_code(send_type, login) + + render_ok + end + + def send_code send_type, login code = %W(0 1 2 3 4 5 6 7 8 9) verification_code = code.sample(6).join - send_type = login =~ /^1\d{10}$/ ? 2 : 3 # 记录验证码 - check_verification_code(verification_code, send_type, login) + sign = Digest::MD5.hexdigest("#{OPENKEY}#{login}") + tip_exception(501, "请求不合理") if sign != params[:smscode] - render_ok + check_verification_code(verification_code, send_type, login) end end \ No newline at end of file From 870f195f48db12fe139fe96ee4ce6a3f1a597e11 Mon Sep 17 00:00:00 2001 From: daiao <358551898@qq.com> Date: Mon, 13 Jan 2020 17:41:00 +0800 Subject: [PATCH 153/156] =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=A4=9A=E4=BD=99?= =?UTF-8?q?=E7=9A=84=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/application_controller.rb | 2 -- app/services/git_service.rb | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 9faa14593..e0639de3f 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -23,8 +23,6 @@ class ApplicationController < ActionController::Base # 所有请求必须合法签名 def check_sign - Rails.logger.info("#####################request: #{request.headers}") - #Rails.logger.info("#####################type: #{request.type}") if !Rails.env.development? && EduSetting.get("host_name") != "https://test-newweb.educoder.net" Rails.logger.info("66666 #{params}") # suffix = request.url.split(".").last.split("?").first diff --git a/app/services/git_service.rb b/app/services/git_service.rb index eedac2595..2bfc7423c 100644 --- a/app/services/git_service.rb +++ b/app/services/git_service.rb @@ -64,7 +64,7 @@ class GitService end def parse_return(body) - logger.info("--uri_exec: .....res is #{body}") + #logger.info("--uri_exec: .....res is #{body}") content = JSON.parse(body) if content["code"] != 0 From 49fb413662b27cb2eb985698e2a88828a0e87e3a Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Mon, 13 Jan 2020 17:42:27 +0800 Subject: [PATCH 154/156] =?UTF-8?q?=E5=B0=8F=E7=A8=8B=E5=BA=8F=E7=9A=84?= =?UTF-8?q?=E6=84=8F=E8=A7=81=E5=8F=8D=E9=A6=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/helps_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/helps_controller.rb b/app/controllers/helps_controller.rb index 8d58663f6..12cc8b9b3 100644 --- a/app/controllers/helps_controller.rb +++ b/app/controllers/helps_controller.rb @@ -29,7 +29,7 @@ class HelpsController < ApplicationController content = "

    [#{params[:question_kind]}]

    #{params[:description]}" if params[:attachment_ids] params[:attachment_ids].each do |attachment_id| - content += "![](/api/attachments/#{attachment_id})↵" + content += "![](/api/attachments/#{attachment_id})\n" end end else From 57235bd5198565965586fec50165a72f832f7b37 Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Mon, 13 Jan 2020 17:47:21 +0800 Subject: [PATCH 155/156] =?UTF-8?q?=E5=B0=8F=E7=A8=8B=E5=BA=8F=E7=9A=84?= =?UTF-8?q?=E6=84=8F=E8=A7=81=E5=8F=8D=E9=A6=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/helps_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/helps_controller.rb b/app/controllers/helps_controller.rb index 12cc8b9b3..145ac1bec 100644 --- a/app/controllers/helps_controller.rb +++ b/app/controllers/helps_controller.rb @@ -26,7 +26,7 @@ class HelpsController < ApplicationController def feedback if params[:url].blank? - content = "

    [#{params[:question_kind]}]

    #{params[:description]}" + content = "

    [#{params[:question_kind]}]

    #{params[:description]}

    " if params[:attachment_ids] params[:attachment_ids].each do |attachment_id| content += "![](/api/attachments/#{attachment_id})\n" From d1ec190180ce69fc41a3fc73d09f2fde32ca5171 Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Mon, 13 Jan 2020 18:02:37 +0800 Subject: [PATCH 156/156] =?UTF-8?q?=E5=B0=8F=E7=A8=8B=E5=BA=8F=E7=9A=84?= =?UTF-8?q?=E6=84=8F=E8=A7=81=E5=8F=8D=E9=A6=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/helps_controller.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/helps_controller.rb b/app/controllers/helps_controller.rb index 145ac1bec..10a073684 100644 --- a/app/controllers/helps_controller.rb +++ b/app/controllers/helps_controller.rb @@ -26,14 +26,14 @@ class HelpsController < ApplicationController def feedback if params[:url].blank? - content = "

    [#{params[:question_kind]}]

    #{params[:description]}

    " + content = "[#{params[:question_kind]}]
    #{params[:description]}
    " if params[:attachment_ids] params[:attachment_ids].each do |attachment_id| - content += "![](/api/attachments/#{attachment_id})\n" + content += "![](/api/attachments/#{attachment_id})
    " end end else - content = "

    [#{params[:question_kind]}]

    问题页面网址:#{params[:url]}

    #{params[:description]}" + content = "[#{params[:question_kind]}]
    问题页面网址:#{params[:url]}
    #{params[:description]}" end ActiveRecord::Base.transaction do