Merge branch 'dev_item_bank' of http://bdgit.educoder.net/Hjqreturn/educoder into dev_item_bank

dev_jupyter
cxt 5 years ago
commit 6fcfac707d

@ -106,3 +106,6 @@ gem 'omniauth-oauth2', '~> 1.6.0'
# global var
gem 'request_store'
# 敏感词汇
gem 'harmonious_dictionary', '~> 0.0.1'

@ -224,7 +224,7 @@ class CoursesController < ApplicationController
normal_status(0, "成功")
rescue => e
uid_logger_error(e.message)
tip_exception("课堂更新失败")
tip_exception("课堂更新失败,原因: #{e.message}")
raise ActiveRecord::Rollback
end
end
@ -1554,7 +1554,7 @@ class CoursesController < ApplicationController
end
def course_statistics course, max_exp, limit
max_rate = max_exp.nil? ? 0 : 20.0 / max_exp
max_rate = max_exp.nil? || max_exp <= 0 ? 0 : 20.0 / max_exp
sql_select = %Q{ SELECT a.*, (message_num*0.2 + message_reply_num*0.1 + resource_num*0.5 + homework_journal_num*0.1 + graduation_num +
homework_num + exercise_num + poll_num*0.7 + exercise_score * 0.7 + graduation_score * 0.7 + homework_score * 0.7 + exp*#{max_rate})

@ -85,7 +85,7 @@ class DiscussesController < ApplicationController
:hidden => !current_user.admin?) # 管理员回复的能够显示
rescue Exception => e
uid_logger_error("create discuss failed : #{e.message}")
raise Educoder::TipException.new("评论异常")
raise Educoder::TipException.new("评论异常,原因:#{e.message}")
end
end
@ -97,7 +97,7 @@ class DiscussesController < ApplicationController
:dis_type => @discuss.dis_type, :position => @discuss.position)
rescue Exception => e
uid_logger_error("reply discuss failed : #{e.message}")
raise Educoder::TipException.new("回复评论异常")
raise Educoder::TipException.new("回复评论异常,原因: #{e.message}")
end
end

@ -1,9 +1,9 @@
class GraduationTasksController < ApplicationController
before_action :require_login, :check_auth, except: [:index]
before_action :find_course, except: [:edit, :update, :settings, :update_settings, :tasks_list, :show, :show_comment,
:cross_comment_setting, :assign_works, :commit_comment_setting]
:cross_comment_setting, :assign_works, :commit_comment_setting, :sonar]
before_action :find_task, only: [:edit, :update, :settings, :update_settings, :tasks_list, :show, :show_comment,
:cross_comment_setting, :assign_works, :commit_comment_setting]
:cross_comment_setting, :assign_works, :commit_comment_setting, :sonar]
before_action :user_course_identity
before_action :task_publish, only: [:show, :show_comment, :tasks_list, :settings]
before_action :teacher_allowed, only: [:new, :create, :edit, :update, :set_public,:multi_destroy, :publish_task, :end_task,
@ -66,62 +66,8 @@ class GraduationTasksController < ApplicationController
(@user_course_identity == Course::STUDENT && @work.present? && @work.take.work_status > 0 &&
((!@task.allow_late && @task.status > 1) || (@task.allow_late && @task.late_time && @task.late_time < Time.now)) &&
(@task.open_work || @task.open_score)))
# 如有有分班则看分班内的学生,否则看所有学生的作品
user_ids =
if @user_course_identity < Course::STUDENT
@course.teacher_group_user_ids(current_user.id)
else
course_group_id = @course.course_member(current_user.id).course_group_id
@course.students.where(course_group_id: course_group_id).pluck(:user_id)
end
@work_list = @task.graduation_works.where(user_id: user_ids).includes(user: [:user_extension])
@all_work_count = @work_list.count
@teachers = @course.teachers.where.not(user_id: current_user.id).includes(:user)
# 教师评阅搜索 0: 未评, 1 已评
unless params[:teacher_comment].blank?
graduation_work_ids = GraduationWorkScore.where(graduation_work_id: @work_list.map(&:id)).pluck(:graduation_work_id)
if params[:teacher_comment].to_i == 0
@work_list = @work_list.where("work_status != 0")
elsif params[:teacher_comment].to_i == 1
@work_list = @work_list.where("work_status != 0").where(id: graduation_work_ids)
end
end
# 作品状态 0 未提交, 1 按时提交, 2 延迟提交
unless params[:task_status].blank?
@work_list = @work_list.where(work_status: params[:task_status])
end
# 分班情况
unless params[:course_group].blank?
group_user_ids = @course.students.where(course_group_id: params[:course_group]).pluck(:user_id)
# 有分组只可能是老师身份查看列表
@work_list = @work_list.where(user_id: group_user_ids)
end
# 只看我的交叉评阅
unless params[:cross_comment].blank?
graduation_work_id = @task.graduation_work_comment_assignations.where(:user_id =>current_user.id)
.pluck(:graduation_work_id).uniq if @task.graduation_work_comment_assignations
@work_list = @task.graduation_works.where(id: graduation_work_id)
end
# 组员、组长作品的筛选
if @task.task_type == 2 && !params[:member_work].blank?
if params[:member_work].to_i == 1
@work_list = @work_list.where("user_id = commit_user_id")
elsif params[:member_work].to_i == 0
@work_list = @work_list.where("user_id != commit_user_id")
end
end
# 输入姓名和学号搜索
# TODO user_extension 如果修改 请调整
unless params[:search].blank?
@work_list = @work_list.joins(user: :user_extension).where("concat(lastname, firstname) like ?
or student_id like ?", "%#{params[:search]}%", "%#{params[:search]}%")
end
_tasks_list
# 排序
rorder = params[:order].blank? ? "update_time" : params[:order]
@ -265,6 +211,33 @@ class GraduationTasksController < ApplicationController
end
end
# 代码检测
def sonar
tip_exception(403, "无权限访问") unless current_user.admin_or_business?
_tasks_list
person_list = @work_list.map do |work|
o = {
name: "#{work.user&.real_name}",
uid: "#{work.user&.student_id}",
downloadUrl: ''
}
attachment = work.attachments.last
if attachment
o[:downloadUrl] = "https://#{edu_setting('host_name')}/"+download_url(attachment)
end
o
end
filename = "#{@task.name}_#{Time.now.strftime('%Y%m%d%H%M%S')}.json"
json = File.open("/tmp/#{filename}", "w+")
json.puts(person_list.to_json)
json.close
send_file json.path, filename: filename
end
# 设为公开
def set_public
tip_exception("仅公开课堂才能公开毕设任务") if @course.is_public == 0
@ -657,6 +630,65 @@ class GraduationTasksController < ApplicationController
tip_exception("请先开启交叉评阅再设置") unless @task.cross_comment
end
def _tasks_list
# 如有有分班则看分班内的学生,否则看所有学生的作品
user_ids =
if @user_course_identity < Course::STUDENT
@course.teacher_group_user_ids(current_user.id)
else
course_group_id = @course.course_member(current_user.id).course_group_id
@course.students.where(course_group_id: course_group_id).pluck(:user_id)
end
@work_list = @task.graduation_works.where(user_id: user_ids).includes(user: [:user_extension])
@all_work_count = @work_list.count
@teachers = @course.teachers.where.not(user_id: current_user.id).includes(:user)
# 教师评阅搜索 0: 未评, 1 已评
unless params[:teacher_comment].blank?
graduation_work_ids = GraduationWorkScore.where(graduation_work_id: @work_list.map(&:id)).pluck(:graduation_work_id)
if params[:teacher_comment].to_i == 0
@work_list = @work_list.where("work_status != 0")
elsif params[:teacher_comment].to_i == 1
@work_list = @work_list.where("work_status != 0").where(id: graduation_work_ids)
end
end
# 作品状态 0 未提交, 1 按时提交, 2 延迟提交
unless params[:task_status].blank?
@work_list = @work_list.where(work_status: params[:task_status])
end
# 分班情况
unless params[:course_group].blank?
group_user_ids = @course.students.where(course_group_id: params[:course_group]).pluck(:user_id)
# 有分组只可能是老师身份查看列表
@work_list = @work_list.where(user_id: group_user_ids)
end
# 只看我的交叉评阅
unless params[:cross_comment].blank?
graduation_work_id = @task.graduation_work_comment_assignations.where(:user_id =>current_user.id)
.pluck(:graduation_work_id).uniq if @task.graduation_work_comment_assignations
@work_list = @task.graduation_works.where(id: graduation_work_id)
end
# 组员、组长作品的筛选
if @task.task_type == 2 && !params[:member_work].blank?
if params[:member_work].to_i == 1
@work_list = @work_list.where("user_id = commit_user_id")
elsif params[:member_work].to_i == 0
@work_list = @work_list.where("user_id != commit_user_id")
end
end
# 输入姓名和学号搜索
# TODO user_extension 如果修改 请调整
unless params[:search].blank?
@work_list = @work_list.joins(user: :user_extension).where("concat(lastname, firstname) like ?
or student_id like ?", "%#{params[:search]}%", "%#{params[:search]}%")
end
end
#
# def graduation_work_to_xls items
# xls_report = StringIO.new

@ -81,6 +81,8 @@ class Course < ApplicationRecord
# 老版的members弃用 现用course_members
has_many :members
validate :validate_sensitive_string
scope :hidden, ->(is_hidden = true) { where(is_hidden: is_hidden) }
scope :ended, ->(is_end = true) { where(is_end: is_end) }
scope :processing, -> { where(is_end: false) }
@ -435,4 +437,8 @@ class Course < ApplicationRecord
self.laboratory = Laboratory.current if laboratory_id.blank?
end
def validate_sensitive_string
raise("课堂名称包含敏感词汇,请重新输入") unless HarmoniousDictionary.clean?(name)
end
end

@ -6,4 +6,10 @@ class CourseList < ApplicationRecord
has_many :gtask_banks
has_many :gtopic_banks
belongs_to :user
validate :validate_sensitive_string
def validate_sensitive_string
raise("课程名称包含敏感词汇,请重新输入") unless HarmoniousDictionary.clean?(name)
end
end

@ -11,6 +11,8 @@ class Discuss < ApplicationRecord
belongs_to :dis, polymorphic: true
belongs_to :challenge, optional: true
validate :validate_sensitive_string
after_create :send_tiding
scope :children, -> (discuss_id){ where(parent_id: discuss_id).includes(:user).reorder(created_at: :asc) }
@ -69,4 +71,8 @@ class Discuss < ApplicationRecord
}
tidings.create!(base_attrs.merge(user_id: send_user_id))
end
def validate_sensitive_string
raise("内容包含敏感词汇,请重新输入") unless HarmoniousDictionary.clean?(content)
end
end

@ -16,6 +16,7 @@ class Memo < ApplicationRecord
has_many :children, foreign_key: :parent_id, class_name: 'Memo'
has_many :attachments, as: :container, dependent: :destroy
has_many :tidings, as: :container, dependent: :destroy
validate :validate_sensitive_string
scope :field_for_list, lambda{
select([:id, :subject, :author_id, :sticky, :updated_at, :language, :reward, :all_replies_count, :viewed_count, :forum_id])
@ -54,4 +55,9 @@ class Memo < ApplicationRecord
self.tidings << Tiding.new(tiding_attr)
end
def validate_sensitive_string
raise("标题包含敏感词汇,请重新输入") unless HarmoniousDictionary.clean?(subject)
raise("内容包含敏感词汇,请重新输入") unless HarmoniousDictionary.clean?(content)
end
end

@ -178,13 +178,8 @@ class User < ApplicationRecord
validates_uniqueness_of :phone, :if => Proc.new { |user| user.phone_changed? && user.phone.present? }, case_sensitive: false
validates_length_of :login, maximum: LOGIN_LENGTH_LIMIT
validates_length_of :mail, maximum: MAIL_LENGTH_LMIT
# validates_format_of :mail, with: VALID_EMAIL_REGEX, multiline: true
# validates_format_of :phone, with: VALID_PHONE_REGEX, multiline: true
validate :validate_sensitive_string
validate :validate_password_length
#validate :validate_ID_number
#validates_format_of :ID_number, with: VALID_NUMBER_REGEX, multiline: true, message: "身份证号格式不对"
# validates :nickname, presence: true, length: { maximum: 10 }
# validates :lastname, presence: true
# 删除自动登录的token一旦退出下次会提示需要登录
def delete_autologin_token(value)
@ -727,6 +722,11 @@ class User < ApplicationRecord
end
end
def validate_sensitive_string
raise("真实姓名包含敏感词汇,请重新输入") unless HarmoniousDictionary.clean?(lastname)
raise("昵称包含敏感词汇,请重新输入") unless HarmoniousDictionary.clean?(nickname)
end
def set_laboratory
return unless new_record?

@ -17,7 +17,7 @@
</td>
<td>
<% if department.identifier.present? %>
<%= link_to department.identifier.to_s, statistics_college_path(department.identifier), target: '_blank' %>
<%= link_to department.identifier.to_s, "/colleges/#{department.identifier}/statistics", target: '_blank' %>
<% else %>
--
<% end %>

File diff suppressed because it is too large Load Diff

@ -0,0 +1,66 @@
6-4tianwang
89-64cdjp
ADMIN
Administrator
asshole
BLOWJOB
chinaliberal
chinamz
chinesenewsnet
Clockgemstone
creaders
Crestbone
dajiyuan
dfdz
DICK
falun
falundafa
Feelmistone
freechina
freenet
fuck
gcd
Gruepin
Guichuideng
HACKING
hongzhi
hrichina
HUANET
hypermart.net
incest
jiangdongriji
jiaochuang
jiaochun
KEFU
KISSMYASS
lihongzhi
minghui
minghuinews
nacb
Neckromancer
NMIS
PAPER64
penis
qiangjian
renminbao
renmingbao
SHIT
SUCKPENIS
taip
tibetalk
triangle
triangleboy
Tringel
UltraSurf
ustibet
voachinese
wangce
WEBZEN
wstaiji
xinsheng
YUMING
zangdu
ZHENGJIAN
ZHENGJIANWANG
ZHENSHANREN
zhuanfalun

@ -0,0 +1,67 @@
---
- 6-4tianwang
- 89-64cdjp
- ADMIN
- Administrator
- asshole
- BLOWJOB
- chinaliberal
- chinamz
- chinesenewsnet
- Clockgemstone
- creaders
- Crestbone
- dajiyuan
- dfdz
- DICK
- falun
- falundafa
- Feelmistone
- freechina
- freenet
- fuck
- gcd
- Gruepin
- Guichuideng
- HACKING
- hongzhi
- hrichina
- HUANET
- hypermart.net
- incest
- jiangdongriji
- jiaochuang
- jiaochun
- KEFU
- KISSMYASS
- lihongzhi
- minghui
- minghuinews
- nacb
- Neckromancer
- NMIS
- PAPER64
- penis
- qiangjian
- renminbao
- renmingbao
- SHIT
- SUCKPENIS
- taip
- tibetalk
- triangle
- triangleboy
- Tringel
- UltraSurf
- ustibet
- voachinese
- wangce
- WEBZEN
- wstaiji
- xinsheng
- YUMING
- zangdu
- ZHENGJIAN
- ZHENGJIANWANG
- ZHENSHANREN
-

@ -700,6 +700,7 @@ Rails.application.routes.draw do
get :cross_comment_setting
post :assign_works
post :commit_comment_setting
get :sonar
end
collection do

@ -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控制避免用户通过双击等操作发出重复的请求

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-12-17 17:32:55
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-27 16:50:43
* @LastEditTime : 2020-01-06 18:42:09
*/
import './index.scss';
import React, { useState } from 'react';
@ -28,11 +28,12 @@ function CommentForm (props) {
const [focus, setFocus] = useState(false);
const options = [
['bold', 'italic', 'underline'],
[{header: [1,2,3,false]}],
['blockquote', 'code-block'],
['link', 'image'],
['formula']
// ['bold', 'italic', 'underline'],
// [{header: [1,2,3,false]}],
'code-block',
'link',
'image',
'formula'
];
// const { form: { getFieldDecorator } } = props;
const [showQuill, setShowQuill] = useState(false);

@ -1,4 +1,6 @@
.quill_editor_for_react_area{
// background: #fff;
// margin: 0 15px;
.ql-editing{
left: 0 !important;
}

@ -56,12 +56,17 @@
.ysltitbt{
float: left;
padding-top: 31px;
padding-top: 28px;
padding-left: 25px;
font-size: 21px;
color: #05101A;
color: #05101a;
text-align: left;
font-weight:bold;
font-weight: bold;
max-width: 805px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: inline-block;
}
.markdownysltext{
font-size: 14px;

@ -4,11 +4,11 @@
* @Github:
* @Date: 2019-12-30 13:51:19
* @LastEditors : tangjiang
* @LastEditTime : 2020-01-03 18:56:36
* @LastEditTime : 2020-01-07 15:46:24
*/
import './index.scss';
import React, { useState, useEffect } from 'react';
import { Select, notification } from 'antd';
import { Select, notification, Modal, Form, Input, Button } from 'antd';
const { Option } = Select;
@ -17,7 +17,10 @@ function KnowLedge (props) {
const {
options = [], // 下拉选项
values = [], // 已选择的下拉项
onChange // 获取选择的值
onChange, // 获取选择的值
form,
showAdd, // 显示新增图标
addKnowledge // 调用新增知识点接口
} = props;
useEffect(() => {
@ -38,9 +41,12 @@ function KnowLedge (props) {
const [selectOptions, setSelectOptions] = useState(options);
// 已选择的下拉项
const [selectValue, setSelectValue] = useState([]);
const [visible, setVisible] = useState(false);
//
const [value] = useState([]);
const { getFieldDecorator } = form;
const FormItem = Form.Item;
// 渲染下拉选项
const renderOptions = (options = []) => {
return options.map((opt, i) => (
@ -58,10 +64,10 @@ function KnowLedge (props) {
}
return item.id !== value;
});
if (tempArr.length > 50) {
if (tempArr.length > 5) {
notification.warning({
message: '提示',
description: '知识点不能超过50个'
description: '知识点不能超过5个'
});
return;
}
@ -114,15 +120,75 @@ function KnowLedge (props) {
)
}
// 添加知识点
const handleAddKnowledge = () => {
setVisible(true);
};
const handleResetForm = () => {
form.resetFields();
setVisible(false);
}
const handleSubmitForm = (e) => {
e.preventDefault();
form.validateFieldsAndScroll((err, values) => {
if (err) {
return;
}
setVisible(false);
form.resetFields();
// console.log(values);
addKnowledge && addKnowledge(values);
})
}
const _styles = {
display: showAdd ? 'inline-block' : 'none'
};
return (
<div className="knowledge-select-area">
{ renderSelect(selectOptions) }
{/* 渲染下拉选择项 */}
<div className="knowledge-result">
{ renderResult(selectValue) }
<React.Fragment>
<div className="knowledge-select-area">
{ renderSelect(selectOptions) }
{/* 渲染下拉选择项 */}
<div className="knowledge-result">
<i
style={_styles}
className="iconfont icon-roundaddfill icon-add-knowledge"
onClick={handleAddKnowledge}
></i>
{ renderResult(selectValue) }
</div>
</div>
</div>
<Modal
closable={false}
title="新增知识点"
visible={visible}
footer={null}
>
<Form className="knowledge-form">
<FormItem>
{
getFieldDecorator('name', {
rules: [{
required: true, message: '知识点名称不能为空'
}]
})(
<Input />
)
}
</FormItem>
<FormItem style={{ textAlign: 'center' }}>
<Button style={{ marginRight: '20px' }} onClick={handleResetForm}>取消</Button>
<Button type="primary" onClick={handleSubmitForm}>确定</Button>
</FormItem>
</Form>
</Modal>
</React.Fragment>
);
}
export default KnowLedge;
export default Form.create()(KnowLedge);

@ -38,5 +38,19 @@
}
}
}
.icon-add-knowledge{
line-height: 36px;
margin-top: 10px;
margin-right: 10px;
// cursor: ;
color: rgb(78, 188, 126)
}
}
}
.knowledge-form{
.ant-form-explain{
padding: 0;
}
}

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-11-20 10:35:40
* @LastEditors : tangjiang
* @LastEditTime : 2020-01-06 16:17:22
* @LastEditTime : 2020-01-07 15:29:18
*/
import './index.scss';
// import 'katex/dist/katex.css';
@ -61,6 +61,7 @@ class EditTab extends React.Component {
top: 500,
bottom: 20,
offsetTop: 0,
showAdd: false
// knowledges: [],
// coursers: [] // 选中的课程
}
@ -147,13 +148,15 @@ class EditTab extends React.Component {
item.sub_disciplines && item.sub_disciplines.forEach(c => {
if (value[1] && c.id === value[1]) {
saveKnowledge(c.tag_disciplines)
console.log(c.tag_disciplines);
} else if (!value[1]) {
saveKnowledge([]);
}
});
}
});
this.setState({
showAdd: value[1] ? true : false
});
// this.props.validateOjCategory(value[1] || '');
this.props.validateOjSubDisciplineId(value[1] || '');
}
@ -167,6 +170,8 @@ class EditTab extends React.Component {
}
render () {
const { showAdd } = this.state;
const {
ojForm,
ojFormValidate,
@ -177,9 +182,10 @@ class EditTab extends React.Component {
openTestCodeIndex = [],
courseQuestions,
tag_discipline_id,
knowledges
knowledges,
tagDisciplines,
} = this.props;
console.log('knowledge======>>>>>>', knowledges);
// console.log('knowledge======>>>>>>', knowledges);
// const {knowledges} = this.state;
// 表单label
const myLabel = (name, subTitle, nostar) => {
@ -321,7 +327,6 @@ class EditTab extends React.Component {
}
});
console.log(choid_ids);
return (
<Cascader
placeholder="请选择"
@ -340,11 +345,20 @@ class EditTab extends React.Component {
values.forEach(v => {
_result.push(v.id);
});
console.log('下拉选择的值:===>>>', _result);
// console.log('下拉选择的值:===>>>', _result);
// 保存选择的知识点
this.props.saveTagDisciplineId(_result);
}
// 新增知识点
const handleAddKnowledge = (values) => {
// console.log('调用了新增知识点并返回了结果: ', values);
// 获取课程id
const {sub_discipline_id} = this.props.ojForm;
const obj = Object.assign({}, values, {sub_discipline_id})
tagDisciplines(obj);
}
return (
<div className={'editor_area'} id="textCase">
<Form className={'editor_form'}>
@ -384,9 +398,11 @@ class EditTab extends React.Component {
label={<span>{myLabel(jcLabel['knowledge'], '', 'nostar')}</span>}
>
<KnowLedge
showAdd={showAdd}
options={knowledges}
values={tag_discipline_id}
onChange={handleKnowledgeChange}
addKnowledge={handleAddKnowledge}
/>
</FormItem>
@ -514,7 +530,8 @@ const mapDispatchToProps = (dispatch) => ({
addTestCase: (value) => dispatch(actions.addTestCase(value)),
// 删除测试用例
deleteTestCase: (value) => dispatch(actions.deleteTestCase(value)),
saveKnowledge: (value) => dispatch(actions.saveKnowledge(value))
saveKnowledge: (value) => dispatch(actions.saveKnowledge(value)),
tagDisciplines: (params) => dispatch(actions.tagDisciplines(params))
// 获取题库
// getQuestion: (params) => dispatch(actions.getQuestion(params))
});

@ -3,7 +3,7 @@
flex-direction: column;
justify-content: space-between;
background: #fff;
padding: 20px 30px 0;
padding: 0px 20px 0;
height: calc(100vh - 177px);
box-sizing: border-box;
overflow-y: auto;

@ -53,6 +53,7 @@
.commit_record_area{
padding: 0 20px;
background: #fff;
// height: calc(100vh - 178px);
}
.task_description_area{
@ -61,7 +62,8 @@
.task_desc_area{
height: calc(100vh - 242px);
overflow-y: auto;
padding: 0 0 0 15px;
// padding: 0 0 0 15px;
background: #fff;
}
.desc_area_header{
display: flex;
@ -69,14 +71,20 @@
align-items: center;
height: 64px;
padding: 0 20px;
background: #fff;
box-sizing: border-box;
border-bottom: 1px solid #f4f4f4;
.header_flex{
font-size: 14px;
.flex_label{
color: #999999;
color: #888888;
margin-right: 10px;
}
.flex_value{
font-weight: bold;
font-weight: 500;
color: #333;
// color: green;
}
}
}

@ -278,6 +278,8 @@ class VNCContainer extends Component {
.vncDrawer .ant-drawer-body {
padding: 0px;
}
.vncDrawer .rc-tree {
padding: 16px;
max-width: 220px;
@ -286,6 +288,7 @@ class VNCContainer extends Component {
.vncDrawer .ant-drawer-wrapper-body {
background: #242324;
height: 100%;
}
.codeInDrawer .ant-drawer-wrapper-body {
background: #1D1C1D;
@ -294,6 +297,10 @@ class VNCContainer extends Component {
.vncDrawer .ant-drawer-header, .codeInDrawer .ant-drawer-header {
border-bottom: 0;
}
.codeInDrawer .ant-drawer-header,
.codeInDrawer .ant-drawer-content{
background: rgb(28, 28, 28) !important;
}
.vncDrawer > div:nth-child(1) {
opacity: 1 !important;

@ -0,0 +1,929 @@
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,
item_id:this.props.exam_id===undefined?"":parseInt(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,
item_id:this.props.exam_id===undefined?"":parseInt(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,
item_id:this.props.exam_id===undefined?"":parseInt(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,
item_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) => {
// ////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,
item_id:this.props.exam_id===undefined?"":parseInt(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,
item_id:this.props.exam_id===undefined?"":parseInt(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,
item_id:this.props.exam_id===undefined?"":parseInt(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,
item_id:this.props.exam_id===undefined?"":parseInt(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,
item_id:this.props.exam_id===undefined?"":parseInt(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,
item_id:this.props.exam_id===undefined?"":parseInt(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,
item_id:this.props.exam_id===undefined?"":parseInt(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="";
if(this.props.exam_id===undefined){
url="/item_baskets.json";
}else{
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,
item_id:this.props.exam_id===undefined?"":parseInt(this.props.exam_id),
};
this.getdatasy(data);
this.getbasket_listdata();
// this.setState({
// visible:true
// })
}
}).catch((error) => {
//console.log(error);
})
}
// 撤销
getitem_basketss=(id)=>{
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: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,
item_id:this.props.exam_id===undefined?"":parseInt(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,
item_id:this.props.exam_id===undefined?"":parseInt(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,
item_id:this.props.exam_id===undefined?"":parseInt(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,
item_id:this.props.exam_id===undefined?"":parseInt(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 (
<div className="newMain clearfix " ref={this.saveContainer}>
{
visible===true?
<style>
{
`
.newHeaders{
position: fixed;
top: 0px;
z-index: 999 !important;
}
.ant-drawer {
z-index: 800 !important;
}
.ant-notification{
position: fixed;
z-index: 1500 !important;
}
.newFooter{
position: relative;
z-index: 9999999 ;
}
`
}
</style>
:""
}
{
visible===true?
<div
style={{
marginTop: "60px"
}}></div>
:""}
{
modalsTypes===true?
<QuestionModals {...this.props}{...this.state} modalsTypes={modalsTypes} modalCancels={() => this.modalCancels()}
setDownloads={(e) => this.setDownloads(e)}></QuestionModals>
:""
}
{
modalsType===true?
<QuestionModal {...this.props}{...this.state} modalsType={modalsType} modalCancel={() => this.modalCancel()}
setDownload={() => this.setDownload()}></QuestionModal>
:""
}
{/*顶部*/}
<Headplugselections
disciplinesdata={this.state.disciplinesdata}
{...this.props}
{...this.state}
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)}
settag_discipline_id={(e)=>this.settag_discipline_id(e)}
/>
{/*头部*/}
<Contentpart {...this.state} {...this.props}
exam_id={this.props.exam_id}
getitem_basketss={(id)=>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)}></Contentpart>
{
items_count&&items_count>10?
<div className="mb30 clearfix educontent mt40 intermediatecenter">
<Pagination showQuickJumper current={page} onChange={this.paginationonChange}
pageSize={per_page}
total={items_count}></Pagination>
</div>
:<div className="h30 clearfix educontent mt40 intermediatecenter">
</div>
}
<Bottomsubmit {...this.props} {...this.state} bottomvalue={"确定"}
Cohetepaperbool={true}
setCohetepaperbool={() => this.props.setnewmyshixunmodelbool(false)}
onSubmits={() => this.props.setnewmyshixunmodelbool(false)} url={'/paperlibrary'}></Bottomsubmit>
</div>
)
}
}
export default NewMyShixunModel;

@ -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,50 @@ 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
})
var data = {}
this.getdata(data);
}
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 (
<div>
<div id={"Itembankstopid"} className="newMain clearfix intermediatecenter "
>
{
newmyshixunmodelbool===true?
<style>{
`
body{ overflow: hidden !important; }
`
}</style>
:""
}
{
newmyshixunmodelbool===true?
<div className="fangdatwo">
<NewMyShixunModel exam_id={this.props.match.params.id} setnewmyshixunmodelbool={(e)=>this.setnewmyshixunmodelbool(e)}></NewMyShixunModel>
</div>
:
""
}
<style>
{
@ -284,7 +321,7 @@ class Paperreview extends Component {
{
Cohetepaperbool===false?
<Paperreview_item {...this.state} {...this.props} getdata={(data)=>this.getdata(data)}>
<Paperreview_item {...this.state} {...this.props} getdata={(data)=>this.getdata(data)} setnewmyshixunmodelbool={(e)=>this.setnewmyshixunmodelbool(e)}>
</Paperreview_item>
:

@ -430,7 +430,7 @@ class Paperreview_item extends Component {
<p className="ml58 questionstotal lh34">总分{this.props.all_questions_count}</p>
</div>
<div className="w30s xaxisreverseorder">
<div className="jixuxuanti xiaoshou" onClick={() => this.jixuxuantioncli()}>
<div className="jixuxuanti xiaoshou" onClick={() => this.props.setnewmyshixunmodelbool(true)}>
继续选题
</div>
</div>

@ -882,7 +882,6 @@ class Question extends Component {
/>
{/*头部*/}
<Contentpart {...this.state} {...this.props}
getitem_basketss={(id)=>this.getitem_basketss(id)}
selectallquestionsonthispage={()=>this.selectallquestionsonthispage()}
getitem_baskets={(e)=>this.getitem_baskets(e)}

@ -309,7 +309,7 @@ class ChoquesEditor extends Component{
{/* 点击设置答案 */}
{/* TODO 加了tooltip后会丢失掉span的class */}
{/* <Tooltip title={standard_answers[index] ? '点击取消标准答案设置' : '点击设置为标准答案'}> */}
<span class={`option-item fr mr10 color-grey select-choice ${bg} `}
<span className={`option-item fr mr10 color-grey select-choice ${bg} `}
name="option_span" onClick={() => this.onOptionClick(index)} style={{flex: '0 0 38px'}}>
<ConditionToolTip title={standard_answers[index] ? '点击取消标准答案设置' : '点击设置为标准答案'} placement="left" condition={true}>
<div style={{width: '100%', height: '100%'}}>{tagArray[index]}</div>

@ -132,7 +132,7 @@ class Contentpart extends Component {
}
.xaxisreverseorder .ant-input-lg {
height: 41px;}
height: 41px !important;}
.xaxisreverseorder .ant-popover{
top: 30px !important;
@ -176,7 +176,8 @@ class Contentpart extends Component {
{
defaultActiveKey===0||defaultActiveKey==="0"?
<Search
style={{ width: "347px",marginRight:"30px"}}
style={{ marginRight:"30px"}}
className={"xaxisreverseorder searchwidth"}
placeholder="请输入题目名称、内容"
enterButton
size="large"
@ -184,7 +185,7 @@ class Contentpart extends Component {
onSearch={ (value)=>this.props.setdatafuns(value)} />
:
<Search
style={{ width: "347px"}}
className={"xaxisreverseorder searchwidth"}
placeholder="请输入题目名称、内容"
enterButton
size="large"

@ -519,31 +519,28 @@ class Itembankstop extends Component {
}
<Form onSubmit={this.handleSubmit}>
<div className="sortinxdirection">
<Form.Item
label="课程"
>
{getFieldDecorator("rbkc",
{
{initialValue: this.state.rbkc,
rules: [{required: true, message: '请选择课程'}],
}
)(
<div className="sortinxdirection">
<InputGroup >
<Cascader style={{width: '270px'}} value={this.state.rbkc} options={options} onChange={this.handleFormzhishidian}
<Cascader style={{width: '270px'}} options={options} onChange={this.handleFormzhishidian}
placeholder="请选择..."/>
</InputGroup>
</div>
)}
</Form.Item>
</div>
<Form.Item
label="知识点"
>
{getFieldDecorator("rbzsd"
)(
<div className="sortinxdirection">
<InputGroup >
<Select style={{width: '270px'}} value={undefined} onChange={this.handleFormkechen}
placeholder="请选择...">
{knowledgepoints2 && knowledgepoints2.map((object, index) => {
@ -552,11 +549,10 @@ class Itembankstop extends Component {
)
})}
</Select>
</InputGroup>
<img className=" ml22 zjzsdian xiaoshou" src={getImageUrl("/images/educoder/zjzsd.png")} onClick={()=>this.NewknTypedeldel(true)}/>
<img className=" ml22 zjzsdian xiaoshou" src={getImageUrl("images/educoder/zjzsd.png")} onClick={()=>this.NewknTypedeldel(true)}/>
<div className="sortinxdirection" style={{
@ -572,7 +568,7 @@ class Itembankstop extends Component {
}}>
<p className="w100s stestcen lh32">{object.name}</p>
<img className=" ml7 zjzsdian xiaoshou icondowncolorssy" onClick={() => this.deletesobject(object, index)} src={getImageUrl("/images/educoder/bzucha.png")}/>
<img className=" ml7 zjzsdian xiaoshou icondowncolorssy" onClick={() => this.deletesobject(object, index)} src={getImageUrl("images/educoder/bzucha.png")}/>
</div>
)
@ -590,19 +586,18 @@ class Itembankstop extends Component {
label="题型"
>
{getFieldDecorator("rbtx",
{
{initialValue: this.state.rbtx,
rules: [{required: true, message: '请选择题型'}],
}
)(
<InputGroup >
<Select style={{width: '270px'}} value={this.state.rbtx} onChange={this.handleFormtixing}
<Select style={{width: '270px'}} onChange={this.handleFormtixing}
placeholder="请选择...">
<Option value="PROGRAM">编程题</Option>
<Option value="SINGLE">单选题</Option>
<Option value="MULTIPLE">多选题</Option>
<Option value="JUDGMENT">判断题</Option>
<Option value="PROGRAM">编程题</Option>
</Select>
</InputGroup>
)}
</Form.Item>
@ -663,11 +658,11 @@ class Itembankstop extends Component {
<div className="rbndclass">
<Form.Item label="难度">
{getFieldDecorator('rbnd',
{
{initialValue: this.state.rbnd,
rules: [{required: true, message: '请选择难度'}],
}
)(
<Radio.Group initialValue={this.state.rbnd} onChange={this.handleFormLayoutChange}>
<Radio.Group onChange={this.handleFormLayoutChange}>
<Radio.Button value="1">简单</Radio.Button>
<Radio.Button value="2">适中</Radio.Button>
<Radio.Button value="3">困难</Radio.Button>

@ -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===undefined?"":parseInt(this.props.exam_id),
}
}
this.props.getitem_baskets(data);
}
//撤销
@ -184,8 +193,8 @@ class Listjihe extends Component {
{
items.choosed===true?
<p className="selectionss xiaoshou" onClick={()=>this.Selectingpracticaltrainings(items.id)}>
<i className="iconfont icon-jianhao font-12 lg ml7 lh30 icontianjiadaohangcolor mr10"></i>
<span>撤销</span></p>
<i className="iconfont icon-jianhao font-12 lg ml7 lh30 icontianjiadaohangcolor mr5"></i>
<span className="mr15 lh30">撤销</span></p>
:
items.item_type==="PROGRAM"?
items.program_attr.status===0?

@ -393,7 +393,23 @@ class Comthetestpapers extends Component {
.ant-select-selection{
height: 33px !important;
}
.ant-input-group{
.kechen .ant-input-group{
width:258px !important;
}
.zsdd .ant-input-group{
width:258px !important;
}
.sjmc .ant-input-group{
width:258px !important;
}
.kssc .ant-input-group{
width:258px !important;
}
.rbndclass .ant-input-group{
width:258px !important;
}
.ant-input {

@ -575,7 +575,23 @@ class Comthetestpaperst extends Component {
.ant-select-selection{
height: 33px !important;
}
.ant-input-group{
.kechen .ant-input-group{
width:258px !important;
}
.zsdd .ant-input-group{
width:258px !important;
}
.sjmc .ant-input-group{
width:258px !important;
}
.kssc .ant-input-group{
width:258px !important;
}
.rbndclass .ant-input-group{
width:258px !important;
}
.ant-input {
@ -600,24 +616,24 @@ class Comthetestpaperst extends Component {
}
<Form onSubmit={this.handleSubmit}>
<div className="kechen">
<div className="sortinxdirection">
<Form.Item
label="课程"
>
{getFieldDecorator("rbkc",
{
{getFieldDecorator("rbkc"
,
{initialValue: this.state.rbkc,
rules: [{required: true, message: '请选择课程'}],
}
)(
<div className="sortinxdirection">
<InputGroup compact>
<Cascader style={{width: '258px'}} value={this.state.rbkc} options={options} onChange={this.handleFormzhishidian}
<Cascader style={{width: '258px'}} options={options} onChange={this.handleFormzhishidian}
placeholder="请选择..."/>
</InputGroup>
</div>
)}
</Form.Item>
</div>
</div>
<div className="zsdd">
<Form.Item
label="知识点"
>
@ -666,7 +682,7 @@ class Comthetestpaperst extends Component {
</div>
)}
</Form.Item>
</div>
<style>
{
`
@ -791,12 +807,13 @@ class Comthetestpaperst extends Component {
</style>
<div className="rbndclass">
<Form.Item label="难度">
{getFieldDecorator('rbnd',
{
{getFieldDecorator('rbnd'
,
{initialValue: this.state.rbnd,
rules: [{required: true, message: '请选择难度'}],
}
)(
<Radio.Group initialValue={this.state.rbnd} onChange={this.handleFormLayoutChange}>
<Radio.Group onChange={this.handleFormLayoutChange}>
<Radio.Button value="1">简单</Radio.Button>
<Radio.Button value="2">适中</Radio.Button>
<Radio.Button value="3">困难</Radio.Button>

@ -922,3 +922,20 @@
.mr15{
margin-right: 15px;
}
.fangdatwo{
background: #fefefe;
background-color: #fefefe;
height: 100%;
overflow-y: scroll !important;
width: 100%;
position: fixed;
top:0px;
bottom: 0px;
left: 0px;
z-index: 999999;
right: 0px;
}
.searchwidth{
width: 347px !important;
}

@ -22,8 +22,10 @@ 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) {
super(props);
@ -33,7 +35,8 @@ class Paperlibraryeditid extends Component {
disciplinesdata: [],
knowledgepoints: [],
disciplmy: [],
item_banksedit: []
item_banksedit: [],
newmyshixunmodelbool:false,
}
@ -185,14 +188,50 @@ class Paperlibraryeditid 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();
}
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 (
<div>
<div id={"Itembankstopid"} className="newMain clearfix intermediatecenter "
>
{
newmyshixunmodelbool===true?
<style>{
`
body{ overflow: hidden !important; }
`
}</style>
:""
}
{
newmyshixunmodelbool===true?
<div className="fangdatwo">
<NewMyShixunModel exam_id={this.props.match.params.id} setnewmyshixunmodelbool={(e)=>this.setnewmyshixunmodelbool(e)}></NewMyShixunModel>
</div>
:
""
}
<style>
{
@ -221,6 +260,7 @@ class Paperlibraryeditid extends Component {
<div className=" clearfix educontent Contentquestionbankstyle w100s w1200wuh mt19">
<Seeoagertits
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}
@ -253,10 +293,12 @@ class Paperlibraryeditid extends Component {
</div>
<Bottomsubmit {...this.props} {...this.state} bottomvalue={"保存"}
setCohetepaperbool={(bool) => this.setCohetepaperbool(bool)}
onSubmits={() => this.preservation()} url={'/paperlibrary'}></Bottomsubmit>
{
newmyshixunmodelbool === true ? "" :
<Bottomsubmit {...this.props} {...this.state} bottomvalue={"保存"}
setCohetepaperbool={(bool) => this.setCohetepaperbool(bool)}
onSubmits={() => this.preservation()} url={'/paperlibrary'}></Bottomsubmit>
}
</div>
)

@ -48,7 +48,7 @@ class Seeoagertit extends Component {
</div>
<div className="w30s xaxisreverseorder">
<div className="jixuxuanti xiaoshou" onClick={() => this.jixuxuantioncli()}>
<div className="jixuxuanti xiaoshou" onClick={() => this.props.setnewmyshixunmodelbool(true)}>
继续选题
</div>
</div>

@ -1039,17 +1039,17 @@ submittojoinclass=(value)=>{
`
}
</style>
{/*<li className={`pr `}>*/}
{/* <Popover placement="bottom" content={contents} trigger="click" >*/}
{/* <div className=" sortinxdirection mr10">*/}
{/* <div style={{*/}
{/* color:"#fff"*/}
{/* }}>*/}
{/* 题库*/}
{/* </div>*/}
{/* </div>*/}
{/* </Popover>*/}
{/*</li>*/}
<li className={`pr `}>
<Popover placement="bottom" content={contents} trigger="click" >
<div className=" sortinxdirection mr10">
<div style={{
color:"#fff"
}}>
题库
</div>
</div>
</Popover>
</li>
<li
style={{display: this.props.Headertop === undefined ? 'none' : this.props.Headertop.auth === null ? 'none' : 'block'}}

@ -858,11 +858,6 @@ class TPMBanner extends Component {
const antIcon = <Icon type="loading" style={{fontSize: 24}} spin/>;
const MyRate = ({defaultValue, ...rest}) => {
let myValue = defaultValue;
// console.log(myValue-Math.floor(myValue))
// if (myValue < Math.ceil(myValue)) {
// myValue = Math.floor(myValue) + 0.5;
// }
return <Rating {...rest} value={myValue}/>;
};
//

@ -138,15 +138,26 @@
}
.shixunstartbutton33BD8C{
background: #33BD8C !important;
border: #33BD8C !important;
/* border: #33BD8C !important; */
cursor: inherit !important;
border: 1px solid #33BD8C !important;
background: transparent !important;
color: #33BD8C !important;
box-shadow: none;
text-shadow: none;
}
.shixunstartbuttonFF6601{
background: #FF6601 !important;
border: #FF6601 !important;
/*background: #FF6601 !important;*/
/*border: #FF6601 !important;*/
/*cursor: inherit !important;*/
/* border: #33BD8C !important; */
cursor: inherit !important;
border: 1px solid #FF6601 !important;
background: transparent !important;
color: #FF6601 !important;
box-shadow: none;
text-shadow: none;
}
.shixunstartbutton666666{

@ -107,7 +107,10 @@ class ShixunsIndex extends Component {
this.setState({
parsedid:parsed.id,
newtag_level:nawparsed,
newpalce:newpalce
tag_level:nawparsed,
newpalce:newpalce,
tag_id:parsed.id,
keyword: _keyword || keyword,
})
this.shixunresultend(params);
}

@ -36,7 +36,8 @@ import {
handleClickCancelPublish,
getQuestion,
saveKnowledge,
setOjInitialValue
setOjInitialValue,
tagDisciplines
} from './ojForm';
import {
@ -125,6 +126,7 @@ export default {
getQuestion,
saveKnowledge,
setOjInitialValue,
tagDisciplines,
//
addTestCase,
deleteTestCase,

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-11-27 13:42:11
* @LastEditors : tangjiang
* @LastEditTime : 2020-01-02 14:17:49
* @LastEditTime : 2020-01-07 16:21:53
*/
import types from "./actionTypes";
import { Base64 } from 'js-base64';
@ -18,7 +18,7 @@ import {
fetchUpdateCode,
fetchUserCodeSubmit,
fetchRestoreInitialCode,
fetchAddNotes
fetchAddNotes,
} from "../../services/ojService";
import { notification } from "antd";
@ -148,11 +148,12 @@ export const saveUserCodeForInterval = (identifier, code) => {
* @param {*} type 测评类型 debug | submit
*/
export const updateCode = (identifier, inputValue, type) => {
console.log(1111);
return (dispatch, getState) => {
const { userCode, isUpdateCode } = getState().ojForUserReducer;
if (isUpdateCode) {
fetchUpdateCode(identifier, {
code: userCode
code: Base64.encode(userCode)
}).then(res => {
// 是否更新了代码, 目的是当代码没有更新时不调用更新代码接口,目录没有实现
// TODO 需要优化

@ -4,7 +4,11 @@
* @Github:
* @Date: 2019-11-20 16:35:46
* @LastEditors : tangjiang
<<<<<<< HEAD
* @LastEditTime : 2020-01-07 15:27:22
=======
* @LastEditTime : 2020-01-03 17:39:32
>>>>>>> dev_aliyun
*/
import types from './actionTypes';
import CONST from '../../constants';
@ -13,7 +17,8 @@ import {
fetchGetOjById,
publishTask,
cancelPublicTask,
fetchQuestion
fetchQuestion,
fetchTagDisciplines
} from '../../services/ojService';
import { Base64 } from 'js-base64';
import { notification } from 'antd';
@ -677,30 +682,46 @@ export const updateOpenTestCaseIndex = (value) => {
export const getQuestion = (params) => {
return (dispatch, getState) => {
const {ojForm: {sub_discipline_id}} = getState().ojFormReducer;
fetchQuestion(params, ).then(res => {
fetchQuestion(params).then(res => {
const { data = {} } = res;
const { disciplines = [] } = data;
dispatch({
type: types.GET_COURSE_QUESTION,
payload: disciplines
});
let temp_knowledges = [];
// console.log('选择的课程: =====>>>>>>', sub_discipline_id);
disciplines.forEach(c => {
if (sub_discipline_id && c.sub_disciplines) {
c.sub_disciplines.forEach(sub => {
if (+sub.id === +sub_discipline_id) {
temp_knowledges = sub.tag_disciplines || [];
}
});
}
});
dispatch({
type: types.CHANGE_KNOWLEDGES,
payload: temp_knowledges
});
})
// 如果课程id号存在 同步更新知识点
if (sub_discipline_id) {
let temp_knowledges = [];
disciplines.forEach(c => {
if (sub_discipline_id && c.sub_disciplines) {
c.sub_disciplines.forEach(sub => {
if (+sub.id === sub_discipline_id) {
temp_knowledges = sub.tag_disciplines || [];
}
});
}
});
dispatch({
type: types.CHANGE_KNOWLEDGES,
payload: temp_knowledges
})
}
// let temp_knowledges = [];
// // console.log('选择的课程: =====>>>>>>', sub_discipline_id);
// disciplines.forEach(c => {
// if (sub_discipline_id && c.sub_disciplines) {
// c.sub_disciplines.forEach(sub => {
// if (+sub.id === +sub_discipline_id) {
// temp_knowledges = sub.tag_disciplines || [];
// }
// });
// }
// });
// dispatch({
// type: types.CHANGE_KNOWLEDGES,
// payload: temp_knowledges
// });
});
}
}
@ -727,3 +748,22 @@ export const setOjInitialValue = (params) => {
payload: params
}
}
// 新增知识点
export const tagDisciplines = (params) => {
return (dispatch) => {
fetchTagDisciplines(params).then(res => {
// console.log('新增知识点成功======>>>>', res);
if (res.data.status === 0) {
notification.success({
message: '提示',
description: '新增知识点成功'
});
// 重新调用获取课程列表接口
dispatch(getQuestion({
source: 'question'
}));
}
});
}
}

@ -3,8 +3,8 @@
* @Author: tangjiang
* @Github:
* @Date: 2019-11-27 16:27:09
* @LastEditors: tangjiang
* @LastEditTime: 2019-12-12 17:36:51
* @LastEditors : tangjiang
* @LastEditTime : 2020-01-07 15:23:39
*/
import types from "../actions/actionTypes";
@ -22,7 +22,7 @@ const initialState = {
}
const commonReducer = (state = initialState, action) => {
console.log(action)
// console.log(action)
switch (action.type) {
case types.SHOW_OR_HIDE_CONTROL:
return {

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-11-20 10:55:38
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-30 09:44:56
* @LastEditTime : 2020-01-07 15:23:19
*/
import axios from 'axios';
@ -71,7 +71,7 @@ export async function fetchUserProgramDetail (identifier) {
// 获取提交记录
export async function fetchUserCommitRecord (identifier, params) {
console.log('identifier=====', identifier);
// console.log('identifier=====', identifier);
const url = `/myproblems/${identifier}/submit_records.json`;
return axios.get(url, { params });
}
@ -149,3 +149,9 @@ export async function fetchQuestion (params) {
const url = `/disciplines.json`;
return axios.get(url, { params });
}
// 新增选题
export async function fetchTagDisciplines (params) {
const url = `/tag_disciplines.json`;
return axios.post(url, params);
}
Loading…
Cancel
Save