diff --git a/app/controllers/admins/examination_authentications_controller.rb b/app/controllers/admins/examination_authentications_controller.rb index 8045644e1..c68c062b6 100644 --- a/app/controllers/admins/examination_authentications_controller.rb +++ b/app/controllers/admins/examination_authentications_controller.rb @@ -12,7 +12,7 @@ class Admins::ExaminationAuthenticationsController < Admins::BaseController ActiveRecord::Base.transaction do exam = ExaminationBank.find current_apply.container_id current_apply.update!(status: 1) - exam.update!(public: 0) + exam.update!(public: 1) end render_success_js end diff --git a/app/controllers/admins/item_authentications_controller.rb b/app/controllers/admins/item_authentications_controller.rb index 88d833ee9..8da9b232f 100644 --- a/app/controllers/admins/item_authentications_controller.rb +++ b/app/controllers/admins/item_authentications_controller.rb @@ -16,7 +16,7 @@ class Admins::ItemAuthenticationsController < Admins::BaseController ActiveRecord::Base.transaction do item = ItemBank.find current_apply.container_id current_apply.update!(status: 1) - item.update!(public: 0) + item.update!(public: 1) end render_success_js end diff --git a/app/controllers/examination_banks_controller.rb b/app/controllers/examination_banks_controller.rb index 9ffbd6630..251cd197f 100644 --- a/app/controllers/examination_banks_controller.rb +++ b/app/controllers/examination_banks_controller.rb @@ -50,8 +50,11 @@ class ExaminationBanksController < ApplicationController end def destroy - @exam.destroy! - render_ok + ActiveRecord::Base.transaction do + ApplyAction.where(container_type: "ExaminationBank", container_id: @exam.id).destroy_all + @exam.destroy! + render_ok + end end def set_public 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/controllers/item_banks_controller.rb b/app/controllers/item_banks_controller.rb index 10dd10e07..a0abffe6c 100644 --- a/app/controllers/item_banks_controller.rb +++ b/app/controllers/item_banks_controller.rb @@ -39,8 +39,11 @@ class ItemBanksController < ApplicationController end def destroy - @item.destroy! - render_ok + ActiveRecord::Base.transaction do + ApplyAction.where(container_type: "ItemBank", container_id: @item.id).destroy_all + @item.destroy! + render_ok + end end def set_public 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/models/examination_bank.rb b/app/models/examination_bank.rb index f7b7cc0bf..824f0bb69 100644 --- a/app/models/examination_bank.rb +++ b/app/models/examination_bank.rb @@ -7,6 +7,10 @@ class ExaminationBank < ApplicationRecord has_many :examination_items, -> {order(position: :asc)}, dependent: :destroy + def apply? + !public && ApplyAction.where(container_type: "ExaminationBank", container_id: id, status: 0).exists? + end + def question_count examination_items.size end diff --git a/app/models/item_bank.rb b/app/models/item_bank.rb index dcc0007e2..840f488d8 100644 --- a/app/models/item_bank.rb +++ b/app/models/item_bank.rb @@ -18,6 +18,10 @@ class ItemBank < ApplicationRecord item_analysis&.analysis end + def apply? + !public && ApplyAction.where(container_type: "ItemBank", container_id: id, status: 0).exists? + end + def type_string result = case item_type when "SINGLE" 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/app/views/examination_banks/index.json.jbuilder b/app/views/examination_banks/index.json.jbuilder index 75bd006fe..ae24a377c 100644 --- a/app/views/examination_banks/index.json.jbuilder +++ b/app/views/examination_banks/index.json.jbuilder @@ -1,8 +1,9 @@ json.exams @exams.each do |exam| - json.(exam, :id, :name, :difficulty, :quotes) + json.(exam, :id, :name, :difficulty, :quotes, :public) json.question_count exam.question_count json.total_score exam.total_score json.update_time exam.updated_at&.strftime("%Y-%m-%d %H:%M") + json.apply exam.apply? json.author do json.login exam.user&.login json.name exam.user&.full_name diff --git a/app/views/item_banks/index.json.jbuilder b/app/views/item_banks/index.json.jbuilder index 50a3e063c..c1695b866 100644 --- a/app/views/item_banks/index.json.jbuilder +++ b/app/views/item_banks/index.json.jbuilder @@ -3,6 +3,7 @@ json.items @items.each do |item| json.partial! "item_banks/item", locals: {item: item} json.update_time item.updated_at&.strftime("%Y-%m-%d %H:%M") json.choosed @item_basket_ids.include?(item.id) + json.apply item.apply? json.author do json.login item.user&.login json.name item.user&.full_name 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 diff --git a/public/react/src/common/quillForEditor/README.md b/public/react/src/common/quillForEditor/README.md index eea4de5cc..c9c53b902 100644 --- a/public/react/src/common/quillForEditor/README.md +++ b/public/react/src/common/quillForEditor/README.md @@ -4,7 +4,7 @@ * @Github: * @Date: 2020-01-06 16:20:03 * @LastEditors : tangjiang - * @LastEditTime : 2020-01-06 17:13:19 + * @LastEditTime : 2020-01-09 09:45:29 --> ## QuillForEditor 使用 [https://quilljs.com/] @@ -21,7 +21,7 @@ | autoFocus | 自动获得焦点 | | options | 配置参数, 指定工具栏内容 | | value | 文本编辑器内容 | - | imgAttrs | 指定上传图片的尺寸 | + | imgAttrs | 指定上传图片的尺寸 { width: 'xxpx}, height: 'xxpx'| | style | 指定quill容器样式 | | wrapStyle | 指定包裹quill容器的样式| | onContentChange | 当编辑器内容变化时调用此回调函数(注: 此时返回的内容为对象,提交到后台时需要格式成 JSON 字符串: JSON.stringify(xx)) | diff --git a/public/react/src/common/quillForEditor/index.js b/public/react/src/common/quillForEditor/index.js index 326ca21ae..2cded3fc3 100644 --- a/public/react/src/common/quillForEditor/index.js +++ b/public/react/src/common/quillForEditor/index.js @@ -4,7 +4,7 @@ * @Github: * @Date: 2019-12-18 08:49:30 * @LastEditors : tangjiang - * @LastEditTime : 2020-01-06 16:45:50 + * @LastEditTime : 2020-01-09 11:01:51 */ import './index.scss'; import 'quill/dist/quill.core.css'; // 核心样式 @@ -18,11 +18,12 @@ import deepEqual from './deepEqual.js' import { fetchUploadImage } from '../../services/ojService.js'; import { getImageUrl } from 'educoder' import ImageBlot from './ImageBlot'; +import { Modal } from 'antd'; // import Toolbar from 'quill/modules/toolbar'; import FillBlot from './FillBlot'; const Size = Quill.import('attributors/style/size'); const Font = Quill.import('formats/font'); - +const { confirm } = Modal; // const Color = Quill.import('attributes/style/color'); Size.whitelist = ['12px', '14px', '16px', '18px', '20px', false]; Font.whitelist = ['SimSun', 'SimHei','Microsoft-YaHei','KaiTi','FangSong','Arial','Times-New-Roman','sans-serif']; @@ -36,6 +37,7 @@ Quill.register(Font, true); Quill.register(FillBlot); // Quill.register(Color); + function QuillForEditor ({ placeholder, readOnly, @@ -79,10 +81,44 @@ function QuillForEditor ({ const renderOptions = options || defaultConfig; + const bindings = { + tab: { + key: 9, + handler: function () { + console.log('调用了tab=====>>>>'); + } + }, + enter: { + key: 'Enter', + handler: function () { + console.log('enter====>>>>>>'); + } + }, + backspace: { + key: 'Backspace', + handler: function (range, context) { + console.log('调用了删除按钮', range, context); + // 1. 获取删除的文件 + // 2. 判断删除的文件中包含空格的个数 + // 3. 循环调用删除方法 + const r = window.confirm('确定要删除吗?') + console.log('+++++', quill); + if (r) { + // 调用传入的删除事件 + return true + } else { + return false; + } + } + } + }; // quill 配置信息 const quillOption = { modules: { - toolbar: renderOptions + toolbar: renderOptions, + keyboard: { + bindings: bindings + } // toolbar: { // container: renderOptions // } @@ -98,8 +134,14 @@ function QuillForEditor ({ const quillNode = document.createElement('div'); editorRef.current.appendChild(quillNode); const _quill = new Quill(editorRef.current, quillOption); - setQuill(_quill); + // _quill.keyboard.addBinding({ + // key: 'tab' + // }, function (range, context) { + // console.log('点击了键盘的删除按钮: ', range, context); + // }); + + setQuill(_quill); // 处理图片上传功能 _quill.getModule('toolbar').addHandler('image', (e) => { const input = document.createElement('input'); @@ -142,6 +184,12 @@ function QuillForEditor ({ // 点击填空图标时,插入一个下划线 // 1. 获取编辑器内容 }); + + // TODO + /** + * 1.获取键盘删除事件 + * 2.点击时获取删除的叶子节点 getLeaf(range.index) + */ }, []); // 设置值 @@ -232,6 +280,7 @@ function QuillForEditor ({ }, [quill, handleOnChange]); useEffect(() => { + if (!quill) return; if (autoFocus) { quill.focus(); } diff --git a/public/react/src/modules/courses/coursesDetail/CoursesLeftNav.js b/public/react/src/modules/courses/coursesDetail/CoursesLeftNav.js index 16e8a1576..c37b45c84 100644 --- a/public/react/src/modules/courses/coursesDetail/CoursesLeftNav.js +++ b/public/react/src/modules/courses/coursesDetail/CoursesLeftNav.js @@ -530,20 +530,22 @@ class Coursesleftnav extends Component{ {name:value}).then((result)=>{ if(result!=undefined){ if(result.data.status===0){ - // window.location.reload() - // this.updasaveNavmoda() - // + notification.open({ message:"提示", description:result.data.message }); - trigger('updateNavSuccess') + if(positiontype==="files"){ + this.updasaveNavmoda() + trigger('updateNavSuccess') window.location.href=`/courses/${coursesId}/file/${result.data.category_id}`; } if(positiontype==="boards"){ + this.updasaveNavmoda() + trigger('updateNavSuccess') window.location.href=`/courses/${coursesId}/boards/${result.data.category_id}`; } diff --git a/public/react/src/modules/courses/exercise/ExerciseListItem.js b/public/react/src/modules/courses/exercise/ExerciseListItem.js index 72b5e579f..8bb42b042 100644 --- a/public/react/src/modules/courses/exercise/ExerciseListItem.js +++ b/public/react/src/modules/courses/exercise/ExerciseListItem.js @@ -188,7 +188,7 @@ class ExerciseListItem extends Component{ - { IsAdmin &&
{object.name}
+{object.name}
+ this.deletesobject(object, index)} src={getImageUrl("images/educoder/bzucha.png")}/> +{object.name}
+ }}> - this.deletesobject(object, index)} src={getImageUrl("/images/educoder/bzucha.png")}/> + {this.state.Knowpoints === undefined ? "" : this.state.Knowpoints.map((object, index) => { + return ( +{object.name}
-