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/app/controllers/tag_disciplines_controller.rb b/app/controllers/tag_disciplines_controller.rb index 2650f51eb..c978762ad 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 + tip_exception("请输入知识点") if params[:name].blank? + tip_exception("输入字符长度限制在15个以内") if params[:name].length > 15 sub_discipline = SubDiscipline.find_by!(id: params[:sub_discipline_id]) + 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 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 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 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 ( +