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

yslnewtiku
cxt 5 years ago
commit 60808b21c9

@ -5,9 +5,10 @@ class Admins::ShixunSettingsController < Admins::BaseController
shixun_settings = Admins::ShixunSettingsQuery.call(params)
@editing_shixuns = shixun_settings.where(status:0).size
@pending_shixuns = shixun_settings.where(status:1).size
@processed_shixuns = shixun_settings.where(status:2).size
@processed_shixuns = shixun_settings.where(status:2, public: 0).size
@closed_shixuns = shixun_settings.where(status:3).size
@pending_public_shixuns = shixun_settings.where(public:1).size
@processed_pubic_shixuns = shixun_settings.where(public:2).size
@sort_json = {
can_copy: params[:can_copy].present? ? params[:can_copy] : false,

@ -5,10 +5,8 @@ class Admins::ShixunsController < Admins::BaseController
params[:sort_direction] = params[:sort_direction].presence || 'desc'
shixuns = Admins::ShixunQuery.call(params)
@editing_shixuns = shixuns.where(status:0).size
@pending_shixuns = shixuns.where(status:1).size
@processed_shixuns = shixuns.where(status:2).size
@processed_shixuns = shixuns.where(status:2, public: 0).size
@closed_shixuns = shixuns.where(status:3).size
@none_public_shixuns = shixuns.where(public:0).size
@pending_public_shixuns = shixuns.where(public:1).size
@processed_pubic_shixuns = shixuns.where(public:2).size
@shixuns_type_check = MirrorRepository.pluck(:type_name,:id)

@ -400,7 +400,7 @@ class ApplicationController < ActionController::Base
end
rescue Exception => e
uid_logger("--uri_exec: exception #{e.message}")
raise Educoder::TipException.new("实训平台繁忙繁忙等级84")
raise Educoder::TipException.new(message)
end
end

@ -70,6 +70,9 @@ class HackUserLastestCodesController < ApplicationController
# 提交记录详情
def record_detail
@hack_user = HackUserCode.find params[:id]
set = HackSet.find_by(id: @hack_user.error_test_set_id)
@pass_set_count = set ? set.position - 1 : 0
@set_count = @hack_user.hack.hack_sets.count
@my_hack = @hack_user.hack_user_lastest_code
end
@ -96,7 +99,8 @@ class HackUserLastestCodesController < ApplicationController
if ojEvaResult['execMode'] == "debug"
save_debug_data ds_params
elsif ojEvaResult['execMode'] == "submit"
save_submit_data ds_params.merge(expected_output: testCase['expectedOutput'])
save_submit_data ds_params.merge(expected_output: testCase['expectedOutput'],
error_test_set_id: ojEvaResult['failCaseNum'])
end
# 评测完成后,还原评测中的状态
@my_hack.update_attribute(:submit_status, 0)
@ -172,7 +176,7 @@ class HackUserLastestCodesController < ApplicationController
# 编程题已经发布,且之前未通关奖励积分
@hack.increment!(:pass_num)
if @hack.status == 1 && !@my_hack.passed?
reward_attrs = { container_id: game.id, container_type: 'Hack', score: @hack.score }
reward_attrs = { container_id: @hack.id, container_type: 'Hack', score: @hack.score }
RewardGradeService.call(@my_hack.user, reward_attrs)
RewardExperienceService.call(@my_hack.user, reward_attrs)
# 评测完成更新通过数

@ -100,7 +100,7 @@ class HacksController < ApplicationController
@hack.update_attribute(:status, 1)
base_attrs = {
trigger_user_id: current_user.id, viewed: 0, tiding_type: 'System', user_id: @hack.user_id,
parent_container_type: "HackPublish"
parent_container_type: "HackPublish", extra: @hack.identifier
}
@hack.tidings.create!(base_attrs)
render_ok
@ -111,7 +111,7 @@ class HacksController < ApplicationController
@hack.update_attribute(:status, 0)
base_attrs = {
trigger_user_id: current_user.id, viewed: 0, tiding_type: 'System', user_id: @hack.user_id,
parent_container_type: "HackUnPublish"
parent_container_type: "HackUnPublish", extra: @hack.identifier
}
@hack.tidings.create!(base_attrs)
render_ok
@ -232,6 +232,11 @@ class HacksController < ApplicationController
hacks = hacks.where(category: params[:category])
end
# 语言
if params[:language]
hacks = hacks.joins(:hack_codes).where(hack_codes: {language: params[:language]})
end
# 排序
sort_by = params[:sort_by] || "hack_user_lastest_codes_count"
sort_direction = params[:sort_direction] || "desc"

@ -88,7 +88,7 @@ class JupytersController < ApplicationController
def timeinfo_with_tpi
myshixun = Myshixun.find_by(identifier: params[:identifier])
info = jupyter_timeinfo_tpi(shixun)
info = jupyter_timeinfo_tpi(myshixun)
render json: {status: 0}.merge(info)
end

@ -795,12 +795,12 @@ class ShixunsController < ApplicationController
rep_url = Base64.urlsafe_encode64(repo_ip_url @repo_path)
uri = "#{cloud_bridge}/bridge/game/openGameInstance"
params = {tpiID: "#{@myshixun.id}", tpmGitURL: rep_url, tpiRepoName: @myshixun.repo_name.split("/").last}
interface_post uri, params, 83, "实训云平台繁忙繁忙等级83"
interface_post uri, params, 83, "服务器出现问题,请重置环境"
end
end
rescue => e
uid_logger_error(e.message)
tip_exception("服务器出现问题,请重置环境")
tip_exception(e.message)
end
end

@ -53,18 +53,20 @@ class Discuss < ApplicationRecord
def send_tiding
if dis_type == 'Shixun'
user_id = has_parent? ? parent.user_id : Challenge.find(challenge_id).user_id
send_user_id = has_parent? ? parent.user_id : Challenge.find(challenge_id).user_id
parent_container_type = 'Challenge'
challenge_id = challenge_id
extra = ''
elsif dis_type == 'Hack'
user_id = has_parent? ? parent.user_id : Hack.find(dis_id).user_id
send_user_id = has_parent? ? parent.user_id : Hack.find(dis_id).user_id
parent_container_type = 'Hack'
challenge_id = dis_id
extra = HackUserLastestCode.where(user_id: user_id, hack_id: dis_id).first&.identifier
end
base_attrs = {
trigger_user_id: user_id, parent_container_id: challenge_id, parent_container_type: parent_container_type,
belong_container_id: dis_id, belong_container_type: dis_type, viewed: 0, tiding_type: 'Comment'
belong_container_id: dis_id, belong_container_type: dis_type, viewed: 0, tiding_type: 'Comment', extra: extra
}
tidings.create!(base_attrs.merge(user_id: user_id))
tidings.create!(base_attrs.merge(user_id: send_user_id))
end
end

@ -1,4 +1,5 @@
class HackUserCode < ApplicationRecord
# error_test_set_id: 错误的测试集id
# 用户编程题的信息
belongs_to :hack
belongs_to :hack_user_lastest_code

@ -13,25 +13,14 @@ class Admins::ShixunQuery < ApplicationQuery
all_shixuns = Shixun.all
status =
case params[:status]
when "editing" then [0]
when "pending" then [1]
when "processed" then [2]
when "closed" then [3]
else
[0,1,2,3]
when "editing" then {status: 0}
when "processed" then {status: 2, public: 0}
when "pending" then {public: 1}
when "publiced" then {public: 2}
when "closed" then {status: 3}
end
public =
case params[:public]
when "editing" then [0]
when "pending" then [1]
when "processed" then [2]
else
[0,1,2]
end
all_shixuns = all_shixuns.where(status: status) if status.present?
all_shixuns = all_shixuns.where(public: public) if public.present?
all_shixuns = all_shixuns.where(status) if status.present?
if params[:fork_status].present?
all_shixuns = all_shixuns.where.not(fork_from: nil)

@ -15,16 +15,15 @@ class Admins::ShixunSettingsQuery < ApplicationQuery
all_shixuns = all_shixuns.where(id: params[:id]) if params[:id].present?
status =
case params[:status]
when "editing" then [0]
when "pending" then [1]
when "processed" then [2]
when "closed" then [3]
else
[0,1,2,3]
end
all_shixuns = all_shixuns.where(status: status) if status.present?
case params[:status]
when "editing" then {status: 0}
when "processed" then {status: 2, public: 0}
when "pending" then {public: 1}
when "publiced" then {public: 2}
when "closed" then {status: 3}
end
all_shixuns = all_shixuns.where(status) if status.present?
if params[:tag].present?
all_shixuns = all_shixuns.joins(:mirror_repositories).where("mirror_repositories.id = ?",params[:tag].to_i)

@ -9,7 +9,7 @@ module ElasticsearchAble
highlight: highlight_options,
body_options: body_options,
page: page,
per_page: per_page
per_page: 20
}
end
@ -37,7 +37,7 @@ module ElasticsearchAble
def per_page
per_page = params[:per_page].to_s.strip.presence || params[:limit].to_s.strip.presence
per_page.to_i <= 0 ? 20 : per_page.to_i
per_page.to_i <= 0 || per_page.to_i > 20 ? 20 : per_page.to_i
end
def page

@ -8,7 +8,7 @@
<div class="d-flex position-r">
<div class="form-group mr-2">
<label for="status">状态:</label>
<% status_options = [['全部', ''], ["编辑中(#{@editing_shixuns})", "editing"], ["待审核(#{@pending_shixuns})", 'pending'], ["已发布(#{@processed_shixuns})", 'processed'],["已关闭(#{@closed_shixuns})",'closed']] %>
<% status_options = [['全部', ''], ["编辑中(#{@editing_shixuns})", "editing"], ["已发布未公开(#{@processed_shixuns})", 'processed'], ["待审核(#{@pending_public_shixuns})", 'pending'], ["已公开(#{@processed_pubic_shixuns})", 'publiced'], ["已关闭(#{@closed_shixuns})",'closed']] %>
<%= select_tag(:status, options_for_select(status_options), class: 'form-control') %>
</div>
<div class="form-group mr-2">

@ -8,16 +8,10 @@
<div class="d-flex position-r">
<div class="form-group">
<label for="status">状态:</label>
<% status_options = [['全部', ''], ["编辑中(#{@editing_shixuns})", "editing"], ["待审核(#{@pending_shixuns})", 'pending'], ["已发布(#{@processed_shixuns})", 'processed'],["已关闭(#{@closed_shixuns})",'closed']] %>
<% status_options = [['全部', ''], ["编辑中(#{@editing_shixuns})", "editing"], ["已发布未公开(#{@processed_shixuns})", 'processed'], ["待审核(#{@pending_public_shixuns})", 'pending'], ["已公开(#{@processed_pubic_shixuns})", 'publiced'], ["已关闭(#{@closed_shixuns})",'closed']] %>
<%= select_tag(:status, options_for_select(status_options), class: 'form-control') %>
</div>
<div class="form-group mr-2">
<label for="status">公开:</label>
<% public_options = [['全部', ''], ["未公开(#{@none_public_shixuns})", "editing"], ["待审核(#{@pending_public_shixuns})", 'pending'], ["已公开(#{@processed_pubic_shixuns})", 'processed']] %>
<%= select_tag(:public, options_for_select(public_options), class: 'form-control') %>
</div>
<div class="form-group mr-2">
<label for="tag-choosed">技术平台:</label>
<%= select_tag(:tag, options_for_select(@shixuns_type_check.unshift(["",nil])), class: 'form-control',id:"tag-choosed") %>

@ -6,6 +6,9 @@ json.data do
json.language @hack_user.hack.language
json.name @hack_user.hack.name
json.myproblem_identifier @my_hack.identifier
json.pass_sets_count @pass_set_count
json.set_count @set_count
json.user do
json.partial! 'users/user', user: current_user
end

@ -1,5 +1,5 @@
json.extract! tiding, :id, :status, :viewed, :user_id, :tiding_type, :container_id, :container_type,
:parent_container_id, :parent_container_type, :belong_container_id, :belong_container_type
:parent_container_id, :parent_container_type, :belong_container_id, :belong_container_type, :extra
json.content tiding.content
json.identifier tiding.identifier

@ -0,0 +1,5 @@
class AddErrorTestSetIdForHackUserLastest < ActiveRecord::Migration[5.2]
def change
add_column :hack_user_codes, :error_test_set_id, :integer
end
end

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

@ -326,8 +326,8 @@ module.exports = {
comments: false
},
compress: {
drop_debugger: true,
drop_console: true
drop_debugger: false,
drop_console: false
}
}
}),

@ -1242,6 +1242,12 @@
<div class="code-name">&amp;#xe6c8;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe70f;</span>
<div class="name">减号</div>
<div class="code-name">&amp;#xe70f;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe60f;</span>
<div class="name">工程</div>
@ -1758,6 +1764,54 @@
<div class="code-name">&amp;#xe6d9;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe701;</span>
<div class="name">缩小</div>
<div class="code-name">&amp;#xe701;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe707;</span>
<div class="name">放大</div>
<div class="code-name">&amp;#xe707;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe709;</span>
<div class="name">编辑</div>
<div class="code-name">&amp;#xe709;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe70b;</span>
<div class="name">公开</div>
<div class="code-name">&amp;#xe70b;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe70c;</span>
<div class="name">解析</div>
<div class="code-name">&amp;#xe70c;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe70d;</span>
<div class="name">删除</div>
<div class="code-name">&amp;#xe70d;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe70e;</span>
<div class="name">试题栏</div>
<div class="code-name">&amp;#xe70e;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe710;</span>
<div class="name">复制</div>
<div class="code-name">&amp;#xe710;</div>
</li>
</ul>
<div class="article markdown">
<h2 id="unicode-">Unicode 引用</h2>
@ -3626,6 +3680,15 @@
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-jianhao"></span>
<div class="name">
减号
</div>
<div class="code-name">.icon-jianhao
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-gongcheng"></span>
<div class="name">
@ -4400,6 +4463,78 @@
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-suoxiao2"></span>
<div class="name">
缩小
</div>
<div class="code-name">.icon-suoxiao2
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-fangda"></span>
<div class="name">
放大
</div>
<div class="code-name">.icon-fangda
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-bianji2"></span>
<div class="name">
编辑
</div>
<div class="code-name">.icon-bianji2
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-gongkai"></span>
<div class="name">
公开
</div>
<div class="code-name">.icon-gongkai
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-jiexi"></span>
<div class="name">
解析
</div>
<div class="code-name">.icon-jiexi
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-shanchu1"></span>
<div class="name">
删除
</div>
<div class="code-name">.icon-shanchu1
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-shitilan"></span>
<div class="name">
试题栏
</div>
<div class="code-name">.icon-shitilan
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-fuzhi3"></span>
<div class="name">
复制
</div>
<div class="code-name">.icon-fuzhi3
</div>
</li>
</ul>
<div class="article markdown">
<h2 id="font-class-">font-class 引用</h2>
@ -6045,6 +6180,14 @@
<div class="code-name">#icon-pinglun</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-jianhao"></use>
</svg>
<div class="name">减号</div>
<div class="code-name">#icon-jianhao</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-gongcheng"></use>
@ -6733,6 +6876,70 @@
<div class="code-name">#icon-zhiding</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-suoxiao2"></use>
</svg>
<div class="name">缩小</div>
<div class="code-name">#icon-suoxiao2</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-fangda"></use>
</svg>
<div class="name">放大</div>
<div class="code-name">#icon-fangda</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-bianji2"></use>
</svg>
<div class="name">编辑</div>
<div class="code-name">#icon-bianji2</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-gongkai"></use>
</svg>
<div class="name">公开</div>
<div class="code-name">#icon-gongkai</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-jiexi"></use>
</svg>
<div class="name">解析</div>
<div class="code-name">#icon-jiexi</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-shanchu1"></use>
</svg>
<div class="name">删除</div>
<div class="code-name">#icon-shanchu1</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-shitilan"></use>
</svg>
<div class="name">试题栏</div>
<div class="code-name">#icon-shitilan</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-fuzhi3"></use>
</svg>
<div class="name">复制</div>
<div class="code-name">#icon-fuzhi3</div>
</li>
</ul>
<div class="article markdown">
<h2 id="symbol-">Symbol 引用</h2>

@ -397,9 +397,9 @@ label.infolabel{display: block;float: left;width: 56px;text-align: right;margin-
.task-colspan{min-width:25%;text-align: left;display: block;float: left;color: #999; }
.colspan-grey{border-radius: 12px;background-color: #E6E6E6;padding: 3px 10px;color: #747A7F}
/*新建任务*/
.challenge_nav{padding: 40px 20px 0px 20px;border-bottom: 1px solid #eee;}
.challenge_nav li{width: auto;float: left;margin-right: 40px;position: relative}
.challenge_nav li.active:after{position: absolute;content: '';width: 50%;background-color: #4CACFF;height: 3px;border-radius: 2px;left: 25%;bottom: 0px;}
.challenge_nav{padding: 20px 20px 0px 20px;border-bottom: 1px solid #eee;}
.challenge_nav li{width: auto;float: left;margin-right: 20px;position: relative}
.challenge_nav li.active:after{position: absolute;content: '';width: 76%;background-color: #4CACFF;height: 3px;border-radius: 2px;left: 25%;bottom: 0px;}
.challenge_nav li a{display: block;width: 100%;padding-bottom: 20px;}
.add_choose_type{width: 60px;height: 20px;line-height: 19px;border-radius: 2px;background-color: #eaeaea;color: #999!important;display: block;float: left;text-align: center;margin-top: 4px;}
@ -524,7 +524,7 @@ li.li-width15{width: 15%;text-align: left}
li.li-width7{width: 7%;text-align: left}
/*-----------------------------在线课堂动态----------------------------------*/
.courseHead{width: 100%;margin-bottom:40px;background-size: 100% 100%;background-image: url("/images/educoder/course-detail.jpg");height: 240px;
.courseHead{width: 100%;margin-bottom:40px;background-size: 100% 100%;background-image: url("/images/educoder/courtailsbdpicture.jpg");height: 240px;
justify-content: center;align-items: center;display: -webkit-flex;
background-size: cover;
background-position: center;
@ -3483,4 +3483,4 @@ a.singlepublishtwo{
.markdown-body {
text-align: justify;
word-break: break-all;
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1419,6 +1419,13 @@
"unicode": "e6c8",
"unicode_decimal": 59080
},
{
"icon_id": "7556166",
"name": "减号",
"font_class": "jianhao",
"unicode": "e70f",
"unicode_decimal": 59151
},
{
"icon_id": "7587940",
"name": "工程",
@ -2020,6 +2027,62 @@
"font_class": "zhiding",
"unicode": "e6d9",
"unicode_decimal": 59097
},
{
"icon_id": "12403050",
"name": "缩小",
"font_class": "suoxiao2",
"unicode": "e701",
"unicode_decimal": 59137
},
{
"icon_id": "12403054",
"name": "放大",
"font_class": "fangda",
"unicode": "e707",
"unicode_decimal": 59143
},
{
"icon_id": "12491363",
"name": "编辑",
"font_class": "bianji2",
"unicode": "e709",
"unicode_decimal": 59145
},
{
"icon_id": "12491366",
"name": "公开",
"font_class": "gongkai",
"unicode": "e70b",
"unicode_decimal": 59147
},
{
"icon_id": "12491369",
"name": "解析",
"font_class": "jiexi",
"unicode": "e70c",
"unicode_decimal": 59148
},
{
"icon_id": "12491370",
"name": "删除",
"font_class": "shanchu1",
"unicode": "e70d",
"unicode_decimal": 59149
},
{
"icon_id": "12491850",
"name": "试题栏",
"font_class": "shitilan",
"unicode": "e70e",
"unicode_decimal": 59150
},
{
"icon_id": "12568379",
"name": "复制",
"font_class": "fuzhi3",
"unicode": "e710",
"unicode_decimal": 59152
}
]
}

@ -626,6 +626,9 @@ Created by iconfont
<glyph glyph-name="pinglun" unicode="&#59080;" d="M896 704H128c-35.2 0-64-28.8-64-64v-448c0-35.2 28.8-64 64-64h256l128-64 128 64h256c35.2 0 64 28.8 64 64V640c0 35.2-28.8 64-64 64zM304 368c-26.5 0-48 21.5-48 48s21.5 48 48 48 48-21.5 48-48-21.5-48-48-48z m208 0c-26.5 0-48 21.5-48 48s21.5 48 48 48 48-21.5 48-48-21.5-48-48-48z m208 0c-26.5 0-48 21.5-48 48s21.5 48 48 48 48-21.5 48-48-21.5-48-48-48z" horiz-adv-x="1024" />
<glyph glyph-name="jianhao" unicode="&#59151;" d="M768 341.333333H256c-25.6 0-42.666667 17.066667-42.666667 42.666667s17.066667 42.666667 42.666667 42.666667h512c25.6 0 42.666667-17.066667 42.666667-42.666667s-17.066667-42.666667-42.666667-42.666667z" horiz-adv-x="1024" />
<glyph glyph-name="gongcheng" unicode="&#58895;" d="M141.9 476.8L454.1 298c18.2-10.6 38.9-16.3 59.9-16.3 21.2 0 41.7 5.6 59.4 16.3l312.4 178.6c21.7 11.8 35.2 36.5 34.5 63.1-0.8 26.2-15.4 50.2-37.4 61.2L567.3 758.4c-33.9 16.9-72.8 16.9-106.6 0L144.9 600.8c-22.5-11.6-36.4-34.5-37.2-61.1-0.8-26.3 12.3-50.4 34.2-62.9z m22.3 85.9l315.6 157.5c10.9 5.4 22.5 8.2 34.2 8.2 11.7 0 23.4-2.7 34.2-8.2l315.5-157.5c8.1-4 13.5-13.6 13.8-24.2 0.3-10.6-4.5-20.2-12.2-24.3L552 335l-0.5-0.3c-11-6.7-24-10.2-37.5-10.2s-26.7 3.6-38.5 10.5L163.1 513.8c-8 4.6-13 14.3-12.7 24.6 0.3 10.9 5.6 20 13.8 24.3zM888.4 249.7l-369-211c-3.5-2-7.1-2-10.7 0.1L139.6 249.7c-10.3 5.9-23.3 2.3-29.1-7.9-5.9-10.2-2.3-23.3 7.9-29.1l368.8-210.8c8.4-4.9 17.6-7.3 26.7-7.3 9.2 0 18.3 2.4 26.6 7.2l368.9 210.9c10.2 5.9 13.8 18.9 7.9 29.1-5.6 10.2-18.7 13.8-28.9 7.9zM888.4 387.1l-369-211c-3.5-2-7.1-2-10.7 0.1L139.6 387.1c-10.3 5.9-23.3 2.3-29.1-7.9-5.9-10.2-2.3-23.3 7.9-29.1l368.8-210.8c8.4-4.9 17.6-7.3 26.7-7.3 9.2 0 18.3 2.4 26.6 7.2L909.6 350c10.2 5.9 13.8 18.9 7.9 29.1-5.8 10.3-18.9 13.8-29.1 8z" horiz-adv-x="1024" />
@ -884,6 +887,30 @@ Created by iconfont
<glyph glyph-name="zhiding" unicode="&#59097;" d="M496.0256 671.232L129.024 212.48A20.48 20.48 0 0 1 144.9984 179.2H337.92c11.264 0 20.48-9.216 20.48-20.48v-266.24c0-11.264 9.216-20.48 20.48-20.48h266.24a20.48 20.48 0 0 1 20.48 20.48V158.72c0 11.264 9.216 20.48 20.48 20.48h192.9216a20.48 20.48 0 0 1 15.9744 33.28l-367.0016 458.752a20.48 20.48 0 0 1-31.9488 0zM153.6 896m51.2 0l614.4 0q51.2 0 51.2-51.2l0 0q0-51.2-51.2-51.2l-614.4 0q-51.2 0-51.2 51.2l0 0q0 51.2 51.2 51.2Z" horiz-adv-x="1024" />
<glyph glyph-name="suoxiao2" unicode="&#59137;" d="M921.6 418.133333h-318.577778c-5.688889 0-17.066667 0-22.755555 5.688889-5.688889 0-11.377778 5.688889-17.066667 11.377778-5.688889 5.688889-11.377778 11.377778-11.377778 17.066667 0 5.688889-5.688889 11.377778-5.688889 22.755555V793.6c0 34.133333 22.755556 56.888889 56.888889 56.888889s56.888889-22.755556 56.888889-56.888889V611.555556L927.288889 878.933333c22.755556 22.755556 56.888889 22.755556 79.644444 0s22.755556-56.888889 0-79.644444L739.555556 531.911111h182.044444c34.133333 0 56.888889-22.755556 56.888889-56.888889s-22.755556-56.888889-56.888889-56.888889zM56.888889-128c-17.066667 0-28.444444 5.688889-39.822222 17.066667-22.755556 22.755556-22.755556 56.888889 0 79.644444L284.444444 236.088889H102.4c-34.133333 0-56.888889 22.755556-56.888889 56.888889s22.755556 56.888889 56.888889 56.888889h318.577778c5.688889 0 17.066667 0 22.755555-5.688889 5.688889 0 11.377778-5.688889 17.066667-11.377778 5.688889-5.688889 11.377778-11.377778 11.377778-17.066667 0-5.688889 5.688889-11.377778 5.688889-22.755555v-318.577778c0-34.133333-22.755556-56.888889-56.888889-56.888889s-56.888889 22.755556-56.888889 56.888889V156.444444l-267.377778-267.377777c-11.377778-11.377778-22.755556-17.066667-39.822222-17.066667z" horiz-adv-x="1024" />
<glyph glyph-name="fangda" unicode="&#59143;" d="M603.022222 418.133333c-17.066667 0-28.444444 5.688889-39.822222 17.066667-22.755556 22.755556-22.755556 56.888889 0 79.644444L830.577778 782.222222h-182.044445c-34.133333 0-56.888889 22.755556-56.888889 56.888889s22.755556 56.888889 56.888889 56.888889H967.111111c5.688889 0 17.066667 0 22.755556-5.688889 5.688889 0 11.377778-5.688889 17.066666-11.377778 5.688889-5.688889 11.377778-11.377778 11.377778-17.066666 5.688889-5.688889 5.688889-17.066667 5.688889-22.755556v-318.577778c0-34.133333-22.755556-56.888889-56.888889-56.888889s-56.888889 22.755556-56.888889 56.888889V702.577778l-267.377778-267.377778c-11.377778-11.377778-22.755556-17.066667-39.822222-17.066667zM375.466667-128H56.888889c-5.688889 0-17.066667 0-22.755556 5.688889-5.688889 0-11.377778 5.688889-17.066666 11.377778-5.688889 5.688889-11.377778 11.377778-11.377778 17.066666-5.688889 5.688889-5.688889 17.066667-5.688889 22.755556v318.577778c0 34.133333 22.755556 56.888889 56.888889 56.888889s56.888889-22.755556 56.888889-56.888889v-182.044445l267.377778 267.377778c22.755556 22.755556 56.888889 22.755556 79.644444 0s22.755556-56.888889 0-79.644444L193.422222-14.222222h182.044445c34.133333 0 56.888889-22.755556 56.888889-56.888889s-22.755556-56.888889-56.888889-56.888889z" horiz-adv-x="1024" />
<glyph glyph-name="bianji2" unicode="&#59145;" d="M704.752941-97.882353H198.776471c-78.305882 0-138.541176 60.235294-138.541177 132.517647V667.105882c0 72.282353 66.258824 132.517647 138.541177 132.517647h319.247058c18.070588 0 30.117647-12.047059 30.117647-30.117647s-12.047059-24.094118-30.117647-24.094117H198.776471c-42.164706 0-78.305882-36.141176-78.305883-72.282353v-632.470588c0-42.164706 36.141176-72.282353 78.305883-72.282353h499.952941c42.164706 0 78.305882 36.141176 78.305882 72.282353V293.647059c0 18.070588 12.047059 30.117647 30.117647 30.117647s30.117647-12.047059 30.117647-30.117647v-259.011765c6.023529-72.282353-60.235294-132.517647-132.517647-132.517647zM313.223529 161.129412c-24.094118 0-54.211765 18.070588-60.235294 48.188235v30.117647l36.141177 126.494118 445.741176 445.741176c48.188235 48.188235 120.470588 48.188235 168.658824 0 48.188235-48.188235 48.188235-120.470588 0-168.658823l-445.741177-445.741177-126.494117-30.117647c-6.023529-6.023529-12.047059-6.023529-18.070589-6.023529z m36.141177 174.682353l-36.141177-114.447059 120.470589 30.117647 433.694117 433.694118c12.047059 12.047059 18.070588 24.094118 18.070589 42.164705 0 18.070588-6.023529 30.117647-18.070589 42.164706-24.094118 24.094118-60.235294 24.094118-84.329411 0L349.364706 335.811765z" horiz-adv-x="1024" />
<glyph glyph-name="gongkai" unicode="&#59147;" d="M512 42.666667C432.355556 42.666667 369.777778 105.244444 369.777778 184.888889S432.355556 327.111111 512 327.111111s142.222222-62.577778 142.222222-142.222222S591.644444 42.666667 512 42.666667z m0 227.555555c-45.511111 0-85.333333-39.822222-85.333333-85.333333S466.488889 99.555556 512 99.555556 597.333333 139.377778 597.333333 184.888889 557.511111 270.222222 512 270.222222zM256 469.333333c-17.066667 0-28.444444 11.377778-28.444444 28.444445V662.755556C244.622222 782.222222 352.711111 867.555556 483.555556 867.555556c142.222222 0 250.311111-96.711111 256-221.866667v-5.688889c0-17.066667-11.377778-28.444444-28.444445-28.444444s-28.444444 11.377778-28.444444 28.444444c-5.688889 96.711111-91.022222 170.666667-199.111111 170.666667-102.4 0-187.733333-68.266667-199.111112-153.6V497.777778c0-17.066667-11.377778-28.444444-28.444444-28.444445zM739.555556-128h-455.111112C176.355556-128 85.333333-36.977778 85.333333 71.111111v227.555556C85.333333 406.755556 176.355556 497.777778 284.444444 497.777778h455.111112c108.088889 0 199.111111-91.022222 199.111111-199.111111v-227.555556c0-108.088889-91.022222-199.111111-199.111111-199.111111z m-455.111112 568.888889C204.8 440.888889 142.222222 378.311111 142.222222 298.666667v-227.555556C142.222222-8.533333 204.8-71.111111 284.444444-71.111111h455.111112c79.644444 0 142.222222 62.577778 142.222222 142.222222v227.555556C881.777778 378.311111 819.2 440.888889 739.555556 440.888889h-455.111112z" horiz-adv-x="1024" />
<glyph glyph-name="jiexi" unicode="&#59148;" d="M506.311111-99.555556c-73.955556 0-147.911111 17.066667-216.177778 51.2-11.377778 5.688889-22.755556 22.755556-11.377777 39.822223 5.688889 11.377778 22.755556 22.755556 39.822222 11.377777 56.888889-28.444444 125.155556-45.511111 187.733333-45.511111 238.933333 0 432.355556 187.733333 432.355556 426.666667 0 85.333333-22.755556 164.977778-73.955556 233.244444-11.377778 11.377778-5.688889 28.444444 5.688889 39.822223 11.377778 11.377778 28.444444 5.688889 39.822222-5.688889 51.2-79.644444 79.644444-170.666667 79.644445-267.377778 5.688889-267.377778-216.177778-483.555556-483.555556-483.555556z m-301.511111 125.155556c-5.688889 0-11.377778 0-17.066667 5.688889C85.333333 122.311111 28.444444 253.155556 28.444444 389.688889 28.444444 651.377778 238.933333 867.555556 500.622222 867.555556c119.466667 0 233.244444-45.511111 318.577778-125.155556 11.377778-11.377778 11.377778-28.444444 0-39.822222-11.377778-11.377778-28.444444-11.377778-39.822222 0-79.644444 73.955556-176.355556 113.777778-278.755556 113.777778-227.555556 0-415.288889-187.733333-415.288889-420.977778 0-125.155556 51.2-238.933333 142.222223-318.577778 11.377778-11.377778 11.377778-28.444444 0-39.822222-5.688889-11.377778-11.377778-11.377778-22.755556-11.377778zM512 31.288889c-56.888889 0-102.4 45.511111-102.4 102.4v34.133333c-62.577778 34.133333-102.4 102.4-102.4 170.666667C307.2 446.577778 398.222222 537.6 512 537.6s204.8-91.022222 204.8-199.111111c0-68.266667-39.822222-136.533333-102.4-170.666667v-34.133333c0-51.2-39.822222-96.711111-91.022222-102.4H512z m0 449.422222c-79.644444 0-147.911111-62.577778-147.911111-142.222222 0-51.2 28.444444-96.711111 73.955555-125.155556l28.444445-17.066666v-68.266667c0-22.755556 17.066667-45.511111 45.511111-45.511111h5.688889c22.755556 0 39.822222 22.755556 39.822222 45.511111v68.266667l28.444445 17.066666c45.511111 22.755556 73.955556 73.955556 73.955555 125.155556 0 73.955556-68.266667 142.222222-147.911111 142.222222zM676.977778 497.777778c-5.688889 0-17.066667 0-22.755556 5.688889-11.377778 11.377778-11.377778 28.444444 0 39.822222L739.555556 628.622222c11.377778 11.377778 28.444444 11.377778 39.822222 0s11.377778-28.444444 0-39.822222l-85.333334-85.333333c-5.688889 0-11.377778-5.688889-17.066666-5.688889zM347.022222 497.777778c-5.688889 0-11.377778 5.688889-17.066666 5.688889L238.933333 594.488889c-11.377778 11.377778-11.377778 28.444444 0 39.822222s28.444444 11.377778 39.822223 0l85.333333-85.333333c11.377778-11.377778 11.377778-28.444444 0-39.822222 0-5.688889-5.688889-11.377778-17.066667-11.377778zM512 560.355556c-17.066667 0-28.444444 11.377778-28.444444 28.444444V685.511111c0 17.066667 11.377778 28.444444 28.444444 28.444445s28.444444-11.377778 28.444444-28.444445v-102.4c0-11.377778-11.377778-22.755556-28.444444-22.755555z" horiz-adv-x="1024" />
<glyph glyph-name="shanchu1" unicode="&#59149;" d="M672-96H358.4c-76.8 0-140.8 57.6-153.6 140.8L96 569.6c0 19.2 6.4 32 25.6 38.4 19.2 6.4 32-6.4 38.4-25.6l102.4-524.8c12.8-51.2 51.2-89.6 96-89.6h313.6c44.8 0 83.2 38.4 96 89.6l102.4 524.8c6.4 19.2 19.2 25.6 38.4 25.6 19.2-6.4 25.6-19.2 25.6-38.4L832 44.8c-19.2-83.2-83.2-140.8-160-140.8zM608 704v6.4c0 51.2-44.8 89.6-96 89.6S416 755.2 416 704h-64C352 793.6 422.4 864 512 864c83.2 0 153.6-64 160-153.6V704h-64zM384 38.4c-12.8 0-25.6 12.8-32 25.6L256 576c0 19.2 12.8 32 25.6 38.4 19.2 0 38.4-12.8 38.4-25.6l96-512c0-19.2-6.4-38.4-32-38.4 6.4 0 0 0 0 0zM640 38.4s-6.4 0 0 0c-25.6 6.4-32 19.2-32 38.4l96 512c0 19.2 19.2 32 38.4 25.6 12.8-6.4 25.6-19.2 25.6-38.4l-96-512c-6.4-12.8-19.2-25.6-32-25.6zM512 38.4c-19.2 0-32 12.8-32 32v512c0 19.2 12.8 32 32 32s32-12.8 32-32v-512c0-19.2-12.8-32-32-32zM992 640H32C12.8 640 0 652.8 0 672S12.8 704 32 704h960c19.2 0 32-12.8 32-32s-12.8-32-32-32z" horiz-adv-x="1024" />
<glyph glyph-name="shitilan" unicode="&#59150;" d="M816.118519-128H184.019753c-69.530864 0-126.419753 56.888889-126.419753 126.419753V756.938272C57.6 826.469136 114.488889 883.358025 184.019753 883.358025h568.888889l189.62963-189.62963v-695.308642c0-69.530864-56.888889-126.419753-126.419753-126.419753zM727.624691 820.148148H184.019753c-37.925926 0-63.209877-25.283951-63.209876-63.209876v-758.518519c0-37.925926 25.283951-63.209877 63.209876-63.209876h632.098766c37.925926 0 63.209877 25.283951 63.209876 63.209876V668.444444L727.624691 820.148148zM955.180247 662.123457h-189.62963c-25.283951 0-44.246914 18.962963-44.246913 44.246913l6.320987 189.62963 227.555556-233.876543z m-170.666667 82.172839v-18.962963h18.962963l-18.962963 18.962963zM670.735802 567.308642H329.402469c-18.962963 0-31.604938 12.641975-31.604938 31.604938S310.439506 630.518519 329.402469 630.518519h341.333333c18.962963 0 31.604938-12.641975 31.604939-31.604939s-12.641975-31.604938-31.604939-31.604938zM670.735802 314.469136H329.402469c-18.962963 0-31.604938 12.641975-31.604938 31.604938S310.439506 377.679012 329.402469 377.679012h341.333333c18.962963 0 31.604938-12.641975 31.604939-31.604938s-12.641975-31.604938-31.604939-31.604938zM670.735802 61.62963H329.402469c-18.962963 0-31.604938 12.641975-31.604938 31.604938s12.641975 31.604938 31.604938 31.604938h341.333333c18.962963 0 31.604938-12.641975 31.604939-31.604938s-12.641975-31.604938-31.604939-31.604938z" horiz-adv-x="1024" />
<glyph glyph-name="fuzhi3" unicode="&#59152;" d="M648.533333-128h-477.866666C75.093333-128 0-52.906667 0 42.666667v477.866666C0 616.106667 75.093333 691.2 170.666667 691.2h477.866666C744.106667 691.2 819.2 616.106667 819.2 520.533333v-477.866666c0-95.573333-75.093333-170.666667-170.666667-170.666667z m-477.866666 750.933333C116.053333 622.933333 68.266667 575.146667 68.266667 520.533333v-477.866666c0-54.613333 47.786667-102.4 102.4-102.4h477.866666c54.613333 0 102.4 47.786667 102.4 102.4v477.866666c0 54.613333-47.786667 102.4-102.4 102.4h-477.866666zM955.733333 110.933333c-20.48 0-34.133333 13.653333-34.133333 34.133334V691.2c0 54.613333-47.786667 102.4-102.4 102.4H273.066667c-20.48 0-34.133333 13.653333-34.133334 34.133333s13.653333 34.133333 34.133334 34.133334h546.133333c95.573333 0 170.666667-75.093333 170.666667-170.666667v-546.133333c0-20.48-13.653333-34.133333-34.133334-34.133334z" horiz-adv-x="1024" />
</font>

Before

Width:  |  Height:  |  Size: 362 KiB

After

Width:  |  Height:  |  Size: 374 KiB

@ -301,6 +301,22 @@ const Developer = Loadable({
loader: () => import('./modules/developer'),
loading: Loading
})
// 题库
const Headplugselection = Loadable({
loader: () => import('./modules/question/Question'),
loading: Loading
})
//题库新建 //题库编辑
const Questionitem_banks = Loadable({
loader: () => import('./modules/question/Questionitem_banks'),
loading: Loading
})
// 学院统计
const College = Loadable({
loader: () => import('./college/College'),
@ -727,6 +743,19 @@ class App extends Component {
(props) => (<RecordDetail {...this.props} {...props} {...this.state} />)
}
/>
<Route path="/question/edit/:id"
render={
(props) => (<Questionitem_banks {...this.props} {...props} {...this.state} />)
} />
<Route path="/question/newitem"
render={
(props) => (<Questionitem_banks {...this.props} {...props} {...this.state} />)
} />
<Route path="/question/:type"
render={
(props) => (<Headplugselection {...this.props} {...props} {...this.state} />)
} />
<Route path="/myproblems/:id"
render={
(props) => (<StudentStudy {...this.props} {...props} {...this.state} />)
@ -736,7 +765,10 @@ class App extends Component {
render={
(props) => (<Developer {...this.props} {...props} {...this.state} />)
}/>
<Route path="/question"
render={
(props) => (<Headplugselection {...this.props} {...props} {...this.state} />)
}/>
<Route exact path="/"
// component={ShixunsHome}
render={

@ -27,7 +27,7 @@ function onMessageByLocalStorage(eventName, callback) {
}
window.addEventListener("storage", function(ev) {
const cb = localStorageMap[ev.key];
console.log('storage event:', ev)
// console.log('storage event:', ev)
if (cb) {
cb(JSON.parse(ev.newValue))
}

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-12-17 17:32:55
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-26 11:11:57
* @LastEditTime : 2019-12-26 18:43:21
*/
import './index.scss';
import React, { useState } from 'react';
@ -69,7 +69,7 @@ function CommentForm (props) {
props.form.setFieldsValue({'comment': ''});
setCtx('');
// const _html = formatDelta(content.ops);
console.log('保存的内容=====》》》》', content);
// console.log('保存的内容=====》》》》', content);
onSubmit && onSubmit(JSON.stringify(content));
}
});

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-12-17 17:35:17
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-26 11:30:32
* @LastEditTime : 2019-12-27 11:05:17
*/
import './index.scss';
import 'quill/dist/quill.core.css'; // 核心样式
@ -36,6 +36,8 @@ function CommentItem ({
const [showItemCount, setShowItemCount] = useState(5);
// 箭头方向
const [arrow, setArrow] = useState(false);
// 上传图片的ulr
const [url, setUrl] = useState('');
const {
author = {}, // 作者
@ -85,6 +87,10 @@ function CommentItem ({
);
};
const handleShowUploadImage = (url) => {
// console.log('==============>>>>>>>>>>>>',url);
setUrl(url);
}
// 评论内容
const commentCtx = (ctx) => {
let _ctx = null;
@ -97,6 +103,7 @@ function CommentItem ({
<QuillForEditor
readOnly={true}
value={_ctx}
showUploadImage={handleShowUploadImage}
/>
)};
@ -181,6 +188,10 @@ function CommentItem ({
}
}
const handleClose = () => {
setUrl('');
}
return (
<li className="comment_item_area">
{commentAvatar(author)}
@ -225,11 +236,19 @@ function CommentItem ({
<div
style={{ display: showQuill ? 'block' : 'none'}}
className="comment_item_quill">
<CommentForm
<CommentForm
onCancel={handleClickCancel}
onSubmit={handleClickSubmit(id)}
/>
</div>
{/* 显示上传的图片信息 */}
<div className="show_upload_image" style={{ display: url ? 'block' : 'none'}}>
<Icon type="close" className="image_close" onClick={handleClose}/>
<div className="image_info">
<img className="image" src={url} alt=""/>
</div>
</div>
</div>
</li>
);

@ -87,6 +87,46 @@ $ml: 20px;
// .comment_item_quill{
// // margin-top: 10px;
// }
.show_upload_image{
position: fixed;
left: 0;
top: 0;
right: 0;
bottom: 0;
z-index: 1000;
&::before{
position: absolute;
height: 100%;
width:100%;
content: '';
background: #000;
opacity: .7;
}
.image_info{
display: flex;
position: absolute;
width: 80%;
height: 80%;
left: 10%;
top: 10%;
justify-content: center;
align-items: center;
// background: green;
.image{
display: block;
width: 100%;
}
}
.image_close{
position: absolute;
right: 20px;
top: 20px;
color: #fff;
cursor: pointer;
}
}
}
.comment_icon_count{
cursor: pointer;

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-12-16 15:50:45
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-24 09:44:03
* @LastEditTime : 2019-12-27 15:07:11
*/
import Quill from "quill";
@ -15,25 +15,38 @@ export default class ImageBlot extends BlockEmbed {
static create(value) {
const node = super.create();
node.setAttribute('alt', value.alt);
node.setAttribute('src', value.url);
// console.log('~~~~~~~~~~~', node, value);
node.addEventListener('click', function () {
value.onclick(value.url);
}, false);
if (value.width) {
node.setAttribute('width', value.width);
}
if (value.height) {
node.setAttribute('height', value.height);
}
if (value.id) {
node.setAttribute('id', value.id);
}
// 宽度和高度都不存在时,
if (!value.width && !value.height) {
node.setAttribute('display', 'block');
// node.setAttribute('display', 'block');
node.setAttribute('width', '100%');
}
// node.setAttribute('style', { cursor: 'pointer' });
// if (node.onclick) {
// console.log('image 有图片点击事件======》》》》》》');
// // node.setAttribute('onclick', node.onCLick);
// }
// 给图片添加点击事件
node.onclick = () => {
value.onClick && value.onClick(value.url);
}
// node.onclick = () => {
// value.onClick && value.onClick(value.url);
// }
return node;
}
@ -45,7 +58,9 @@ export default class ImageBlot extends BlockEmbed {
onclick: node.onclick,
width: node.width,
height: node.height,
display: node.getAttribute('display')
display: node.getAttribute('display'),
id: node.id,
// style: node.style
};
}
}

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-12-18 08:49:30
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-26 10:22:26
* @LastEditTime : 2019-12-27 10:36:11
*/
import './index.scss';
import 'quill/dist/quill.core.css'; // 核心样式
@ -116,9 +116,22 @@ function QuillForEditor ({
// 设置值
useEffect(() => {
if (!quill) return
// debugger;
const previous = quill.getContents()
const current = value
if (value && value.hasOwnProperty('ops')) {
// console.log(value.ops);
const ops = value.ops || [];
ops.forEach((item, i) => {
if (item.insert['image']) {
item.insert['image'] = Object.assign({}, item.insert['image'], {style: { cursor: 'pointer' }, onclick: (url) => showUploadImage(url)});
}
});
}
const current = value
// console.log('+++++', current);
if (!deepEqual(previous, current)) {
setSelection(quill.getSelection())
if (typeof value === 'string') {

@ -2,4 +2,9 @@
.ql-editing{
left: 0 !important;
}
.ql-editor{
img{
cursor: pointer;
}
}
}

@ -375,19 +375,19 @@ class CoursesBanner extends Component {
}
addTeacher = (isTeacher) => {
this.setState({ isTeacher }, () => {
this.refs.addTeacherModal.setVisible(true)
})
this.refs.addTeacherModal.setVisible(true)
})
}
addStudent = () => {
this.refs.addStudentModal.setVisible(true)
this.refs.addStudentModal.setVisible(true)
}
addTeacherSuccess = (params) => {
trigger('addTeacherSuccess', JSON.stringify(params))
this.updatabanner()
}
addStudentSuccess = (params) => {
trigger('addStudentSuccess', JSON.stringify(params))
trigger('addStudentSuccess', JSON.stringify(params))
this.updatabanner()
}
//退出课堂按钮
@ -728,7 +728,12 @@ class CoursesBanner extends Component {
<Breadcrumb.Item className={"pointer"}>
<Tooltip visible={coursedata.teacher_applies_count===undefined?false:coursedata.teacher_applies_count>0?true:false}
placement="topLeft"
title={<pre>{coursedata.teacher_applies_count===undefined?"":coursedata.teacher_applies_count>0?<span>您有{coursedata.teacher_applies_count}条新的加入申请<a className={"daishenp"} onClick={()=>this.setHistoryFun("/courses/"+this.props.match.params.coursesId+"/teachers?tab=2")}>待审批</a></span>:""}</pre>}>
title={<pre>{coursedata.teacher_applies_count===undefined?"":coursedata.teacher_applies_count>0?<span>您有{coursedata.teacher_applies_count}条新的加入申请<a className={"daishenp"} onClick={()=>this.setHistoryFun("/courses/"+this.props.match.params.coursesId+"/teachers?tab=2")}>
<span style={{
color:"#FFA804"
}}>
待审批
</span></a></span>:""}</pre>}>
<span className="color-grey-c font-16" onClick={()=>this.setHistoryFun("/courses/"+this.props.match.params.coursesId+"/teachers")}>
<span className={"mr10"}>教师</span>
<span className={"mr10"}>{coursedata.teacher_count}</span>

@ -34,6 +34,7 @@ class NewShixunModel extends Component{
getdatalist=(page,type,newstatus,keyword,order,diff,limit,pagetype,sorts)=>{
let newsort=sorts;
let no_jupyter=undefined;
if(this.props.type==="shixuns"&&type==="mine"){
if(this.props&&this.props.user.course_name===undefined){
newsort="created_at";
@ -41,6 +42,12 @@ class NewShixunModel extends Component{
newsort="publish_time";
}
}
if(this.props.type==="shixuns"){
if(this.props&&this.props.user.course_name===undefined){
}else{
no_jupyter=1;
}
}
this.setState({
isspinning:true
})
@ -51,6 +58,7 @@ class NewShixunModel extends Component{
}else{
url="/subject_lists.json";
}
axios.get(url,{params:{
page:page,
type:type,
@ -59,7 +67,8 @@ class NewShixunModel extends Component{
order:order,
diff:diff,
limit:limit,
sort:newsort
sort:newsort,
no_jupyter:no_jupyter
}}).then((response) => {
if(response.data){
if(pagetype===undefined){

@ -126,7 +126,6 @@ class Sendresource extends Component{
this.props.Cancel()
}
Saves=()=>{
let {fileList,description,is_public,datatime,Radiovalue} =this.state;
let newfileList=[];
@ -445,4 +444,4 @@ class Sendresource extends Component{
)
}
}
export default Sendresource;
export default Sendresource;

@ -285,10 +285,10 @@ class Bullsubdirectory extends Component{
const {getFieldDecorator} = this.props.form;
// console.log("Bullsubdirectory");
// console.log(this.props.isAdmin());
console.log(this.props);
console.log(whethertoeditysl);
console.log(this.state.eduintits);
console.log(this.state.description);
// console.log(this.props);
// console.log(whethertoeditysl);
// console.log(this.state.eduintits);
// console.log(this.state.description);
return(
<React.Fragment key={this.props.index} id={this.props.id}>

@ -9,7 +9,7 @@
import './index.scss';
import React from 'react';
import { Table, Button, Dropdown, Icon, Menu, Card, Input, Select, Tag, Modal } from 'antd';
import { Table, Button, Dropdown, Icon, Menu, Card, Input, Select, Tag } from 'antd';
import { connect } from 'react-redux';
import actions from '../../redux/actions';
import MultipTags from './components/multiptags';
@ -46,9 +46,24 @@ const maps = {
],
'languageMenu': [
{
'key': 'c',
'name': 'C语言',
'value': 'c'
'key': 'C',
'name': 'C',
'value': 'C'
},
{
'key': 'C++',
'name': 'C++',
'value': 'C++'
},
{
'key': 'Python',
'name': 'Python',
'value': 'Python'
},
{
'key': 'Java',
'name': 'Java',
'value': 'Java'
}
],
'difficultMenu': [
@ -254,7 +269,7 @@ class DeveloperHome extends React.PureComponent {
content: `确定要删除${record.name}吗?`,
onOk () {
// 调用删除接口
console.log(record.identifier);
// console.log(record.identifier);
deleteItem(record.identifier);
}
});
@ -491,7 +506,7 @@ class DeveloperHome extends React.PureComponent {
</div>
</div>
<div className={'card-table'}>
<div bordered={false} className={'filter_ctx_area'}>
<div className={'filter_ctx_area'}>
<div>
<Dropdown className={'dropdonw-style'} placement="bottomLeft" overlay={this.getMenuItems('categoryMenu', this.handleCategoryMenuClick)}>
<span className={'dropdown-span'}>分类 <Icon type="down"/></span>

@ -4,11 +4,11 @@
* @Github:
* @Date: 2019-11-27 16:02:36
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-26 15:17:28
* @LastEditTime : 2019-12-27 09:32:34
*/
import './index.scss';
import React, { useState, useRef, useEffect } from 'react';
import { Tabs, Button, Icon } from 'antd';
import { Tabs, Button, Icon, notification } from 'antd';
import { connect } from 'react-redux';
import InitTabCtx from '../initTabCtx';
import ExecResult from '../execResult';
@ -18,6 +18,7 @@ const { TabPane } = Tabs;
const ControlSetting = (props) => {
const {
hack,
inputValue,
loading,
submitLoading,
@ -57,6 +58,13 @@ const ControlSetting = (props) => {
// 调试代码
const handleTestCode = (e) => {
if (!hack.code) {
notification.warning({
message: '提示',
description: '代码块内容不能为空'
});
return;
}
// console.log(formRef.current.handleTestCodeFormSubmit);
// 调出控制台界面
setShowTextResult(true);
@ -137,8 +145,9 @@ const ControlSetting = (props) => {
const mapStateToProps = (state) => {
const {commonReducer, ojForUserReducer} = state;
const {loading, excuteState, submitLoading, showOrHideControl } = commonReducer;
const { commitTestRecordDetail } = ojForUserReducer;
const { commitTestRecordDetail, hack } = ojForUserReducer;
return {
hack,
loading,
submitLoading,
excuteState,

@ -3,8 +3,8 @@
* @Author: tangjiang
* @Github:
* @Date: 2019-11-27 19:46:14
* @LastEditors: tangjiang
* @LastEditTime: 2019-12-19 10:47:05
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-26 20:07:35
*/
import './index.scss';
import React, { useState, useEffect, useRef, useImperativeHandle, forwardRef } from 'react';
@ -26,7 +26,7 @@ function InitTabCtx (props, ref) {
const { inputValue, onDebuggerCode } = props;
console.log('default value', inputValue);
// console.log('default value', inputValue);
useImperativeHandle(ref, () => ({
handleTestCodeFormSubmit: (cb) => {
// console.log('父组件调用我啦~~~~~~~~~');
@ -34,9 +34,9 @@ function InitTabCtx (props, ref) {
}
}));
useEffect(() => {
console.log('初始值: ========', props);
}, [props]);
// useEffect(() => {
// console.log('初始值: ========', props);
// }, [props]);
// 渲染文本提示信息
const renderText = () => (<span className={'ctx_default'}>请在这里添加测试用例点击调试代码时将从这里读取输入来测试你的代码...</span>);

@ -3,8 +3,8 @@
* @Author: tangjiang
* @Github:
* @Date: 2019-11-25 17:50:33
* @LastEditors: tangjiang
* @LastEditTime: 2019-12-19 19:32:08
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-27 10:36:54
*/
import React, { useState } from 'react';
import { fromStore, toStore } from 'educoder';
@ -68,7 +68,7 @@ const SettingDrawer = (props) => {
);
} else if (Array.isArray(value)) {
const defaultValue = ctx.type === 'font' ? fontSize : theme;
console.log('++', defaultValue);
// console.log('++', defaultValue);
if (type === 'select') {
const child = ctx.value.map((opt, i) => {
return (

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-11-27 15:02:52
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-26 15:19:34
* @LastEditTime : 2019-12-27 10:32:25
*/
import './index.scss';
import React, { useState, useRef, useEffect } from 'react';
@ -28,7 +28,8 @@ const maps = {
function MyMonacoEditor (props, ref) {
const {
const {
code,
notice,
language,
identifier,
@ -41,7 +42,7 @@ function MyMonacoEditor (props, ref) {
} = props;
const [showDrawer, setShowDrawer] = useState(false); // 控制配置滑框
const [editCode, setEditCode] = useState('');
// const [editCode, setEditCode] = useState('');
// const [curLang, setCurLang] = useState('C');
const [fontSize, setFontSize] = useState(() => { // 字体
return +fromStore('oj_fontSize') || 14;
@ -52,11 +53,9 @@ function MyMonacoEditor (props, ref) {
const [ height, setHeight ] = useState('calc(100% - 56px)');
const editorRef = useRef(null);
useEffect(() => {
if (props.code) {
setEditCode(props.code);
}
}, [props]);
// useEffect(() => {
// setEditCode(props.code || '');
// }, [props]);
useEffect(() => {
setHeight(showOrHideControl ? 'calc(100% - 378px)' : 'calc(100% - 56px)');
@ -82,11 +81,11 @@ function MyMonacoEditor (props, ref) {
// 文本框内容变化时,记录文本框内容
const handleEditorChange = (origin, monaco) => {
editorRef.current = monaco; // 获取当前monaco实例
setEditCode(origin); // 保存编辑器初始值
// setEditCode(origin); // 保存编辑器初始值
editorRef.current.onDidChangeModelContent(e => { // 监听编辑器内容的变化
// TODO 需要优化 节流
const val = editorRef.current.getValue();
setEditCode(val);
// setEditCode(val);
onCodeChange(val);
// 值一变化保存当前代码值
// saveUserInputCode(val);
@ -125,9 +124,9 @@ function MyMonacoEditor (props, ref) {
}
}
const renderRestore = identifier ? (
<MyIcon type="iconzaicizairu" />
) : '';
// const renderRestore = identifier ? (
// <MyIcon type="iconzaicizairu" />
// ) : '';
// lex_has_save ${hadCodeUpdate} ? : ''
const _classnames = hadCodeUpdate ? `flex_strict flex_has_save` : 'flex_strict';
@ -181,7 +180,7 @@ function MyMonacoEditor (props, ref) {
height={height}
width="100%"
language={language && language.toLowerCase()}
value={editCode}
value={code || ''}
options={editorOptions}
theme={theme} // dark || light
editorDidMount={handleEditorChange}
@ -212,12 +211,12 @@ const mapStateToProps = (state) => {
}
};
const mapDispatchToProps = (dispatch) => ({
// saveUserInputCode: (code) => dispatch(actions.saveUserInputCode(code)),
});
// const mapDispatchToProps = (dispatch) => ({
// // saveUserInputCode: (code) => dispatch(actions.saveUserInputCode(code)),
// });
// MyMonacoEditor = React.forwardRef(MyMonacoEditor);
export default connect(
mapStateToProps,
mapDispatchToProps
// mapDispatchToProps
)(CNotificationHOC() (MyMonacoEditor));

@ -34,6 +34,7 @@ const NewOrEditTask = (props) => {
startProgramQuestion,
getUserInfoForNew,
handleCancelPublish,
validateOjForm,
// updateTestAndValidate,
} = props;
@ -69,14 +70,20 @@ const NewOrEditTask = (props) => {
// 模拟挑战
const imitationChallenge = () => {
// 调用 start 接口, 成功后跳转到模拟页面
identifier && startProgramQuestion(identifier, props);
// 先调用保存, 再调用 start 接口, 成功后跳转到模拟页面
// identifier && startProgramQuestion(identifier, props);
identifier && validateOjForm(props, 'challenge', () => {
startProgramQuestion(identifier, props);
});
}
// 开始挑战
const startChallenge = () => {
// 调用 start 接口, 成功后跳转到开启实战
// TODO
identifier && startProgramQuestion(identifier, props);
identifier && validateOjForm(props, 'challenge', () => {
startProgramQuestion(identifier, props);
});
// identifier && startProgramQuestion(identifier, props);
}
// 取消
@ -265,7 +272,8 @@ const mapDispatchToProps = (dispatch) => ({
// 开启模拟挑战
startProgramQuestion: (id, props) => dispatch(actions.startProgramQuestion(id, props)),
// 新建时获取信息
getUserInfoForNew: () => dispatch(actions.getUserInfoForNew())
getUserInfoForNew: () => dispatch(actions.getUserInfoForNew()),
validateOjForm: (props, type, cb) => dispatch(actions.validateOjForm(props, type, cb))
});
export default withRouter(connect(

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-11-21 09:19:38
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-26 15:33:01
* @LastEditTime : 2019-12-27 10:37:41
*/
import './index.scss';
import React from 'react';
@ -134,10 +134,10 @@ const AddTestDemo = (props) => {
// };
// const {input = {}, output = {}} = (testCasesValidate[index] = {});
const activePane = {
defaultActiveKey: [isOpen ? '1' : '']
};
console.log(activePane);
// const activePane = {
// defaultActiveKey: [isOpen ? '1' : '']
// };
// console.log(activePane);
// 切换手风琴
const handleChangeCollapse = () => {
@ -184,7 +184,7 @@ const AddTestDemo = (props) => {
const mapStateToProps = (state) => {
const {identifier, loading} = state.ojFormReducer;
console.log(state.ojFormReducer);
// console.log(state.ojFormReducer);
return {
identifier,
loading,

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-11-20 10:35:40
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-26 16:00:57
* @LastEditTime : 2019-12-27 14:30:55
*/
import './index.scss';
// import 'katex/dist/katex.css';
@ -175,11 +175,11 @@ class EditTab extends React.Component {
};
// 提交测试用例
const handleSubmitTest = (obj) => {
console.log('提交的测试用例: ', obj);
// console.log('提交的测试用例: ', obj);
};
// 删除测试用例
const handleDeleteTest = (obj) => {
console.log('删除的测试用例: ', obj);
// console.log('删除的测试用例: ', obj);
deleteTestCase(obj);
};
const renderTestCase = () => {
@ -223,10 +223,10 @@ class EditTab extends React.Component {
// 描述信息变化时
const handleContentChange = (content, quill) => {
console.log('描述信息为: ', content);
// if (quill.getText())
console.log('========>>>>>', quill.getText().length);
if (quill.getText().length === 1) {
// console.log('描述信息为: ', content);
const _text = quill.getText();
const reg = /^[\s\S]*.*[^\s][\s\S]*$/;
if (!reg.test(_text)) {
this.handleChangeDescription('');
} else {
// 保存获取的描述信息至redux中

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-12-01 10:18:35
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-26 13:51:40
* @LastEditTime : 2019-12-27 10:17:07
*/
import './index.scss';
import React from 'react';
@ -17,7 +17,8 @@ function RightPane (props, ref) {
const {
// identifier,
// code,
code,
language,
// onSubmitForm,
saveOjFormCode
} = props;
@ -44,8 +45,8 @@ function RightPane (props, ref) {
return (
<div className={'right_pane_code_wrap'}>
<MyMonacoEditor
language={props.language}
code={props.code}
language={language}
code={code}
onCodeChange={handleCodeChange}/>
{/* <ControlSetting
@ -65,7 +66,6 @@ const mapStateToProps = (state) => {
identifier,
language: ojForm.language,
input: (testCases[0] && testCases[0].input) || '',
}
};
const mapDispatchToProps = (dispatch) => ({

@ -75,11 +75,11 @@ class InitTabCtx extends PureComponent {
handleTestCodeFormSubmit = (cb) => {
const {form, debuggerCode} = this.props;
console.log(debuggerCode);
// console.log(debuggerCode);
form.validateFields((err, values) => {
if (!err) { // 表单验证通过时,调用测试接口
cb && cb(); // 调用回调函数,切换 tab
console.log('表单值:', values);
// console.log('表单值:', values);
debuggerCode(values);
}
});

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-12-04 08:36:21
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-26 14:04:16
* @LastEditTime : 2019-12-27 14:51:42
*/
import './index.scss';
import React, { useState, useEffect } from 'react';
@ -43,7 +43,7 @@ function RecordDetail (props) {
useEffect(() => {
setDetail(recordDetail);
console.log('详情: ', recordDetail);
// console.log('详情: ', recordDetail);
if (recordDetail) {
const { user, myproblem_identifier, code } = recordDetail;
setUser(user);
@ -99,6 +99,11 @@ function RecordDetail (props) {
<span className="status_label" style={{ visibility: detail.status === 0 ? 'visible' : 'hidden'}}>
执行用时: <span className="status_label_sub">{`${detail.execute_time && Number(detail.execute_time * 1000).toFixed(2)}ms`}</span>
</span>
<span className="status_label pass_case" style={{ display: [-1, 0, 2, 5].includes(detail.status) ? 'inline-block' : 'none'}}>
<span className="status_label_sub">{detail.pass_sets_count}</span>
<span className="pass_case_span"> / {detail.set_count}</span>
个通过测试用例
</span>
</div>
<div className="result_error_area">
<ErrorResult detail={detail}/>

@ -1,6 +1,7 @@
@import '../split_pane_resizer.scss';
.record_detail_area{
background: #fff;
.record_detail_ctx{
padding: 0 20px;
.detail_ctx_header{
@ -31,6 +32,13 @@
.status_label_sub{
color: #333333;
}
.pass_case{
float: right;
margin-right: 0;
}
.pass_case_span{
margin-right: 10px;
}
}
.result_code_area{
@ -39,6 +47,9 @@
}
.result_error_area{
margin-top: 15px;
background: rgba(250,250,250,1);
color: #E51C24;
border-radius: 3px;
}
}
}

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-11-23 10:53:19
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-26 15:02:12
* @LastEditTime : 2019-12-27 10:25:14
*/
import './index.scss';
import React, { useEffect, useState } from 'react';
@ -90,9 +90,9 @@ function StudentStudy (props) {
const handleClickEditor = (identifier) => {
if (!identifier) return;
changeShowOrHideControl(false);
props.saveEditorCodeForDetail();
props.history.push(`/problems/${identifier}/edit`);
props.saveEditorCodeForDetail('');
props.clearOjForUserReducer();
props.history.push(`/problems/${identifier}/edit`);
}
// 处理退出
const handleClickQuit = () => {
@ -100,7 +100,7 @@ function StudentStudy (props) {
props.clearOjForUserReducer();
// 将控制台关闭
changeShowOrHideControl(false);
props.saveEditorCodeForDetail();
props.saveEditorCodeForDetail('');
props.history.push('/problems');
}

@ -1,6 +1,52 @@
@import '../split_pane_resizer.scss';
.split-pane-area{
height: calc(100vh - 65px);
.right_pane_code_wrap{
position: relative;
.editor_nodte_area,
.student_notes{
position: absolute;
z-index: 100;
}
.student_notes{
right: 0px;
top: 50%;
width: 36px;
height: 36px;
margin-top: -18px;
border-radius: 50%;
background: #5091FF;
color: #fff;
font-size: 18px;
text-align: center;
transform: translateX(18px);
cursor: pointer;
opacity: 0.5;
transition: all .3s;
&:hover{
opacity: 1;
transform: translateX(-10px);
}
}
.editor_nodte_area{
right: 10px;
top: 50%;
width: 450px;
height: 200px;
margin-top: -100px;
background: #fff;
border-radius: 5px;
padding: 14px 10px 0;
// opacity: ;
transform: translateX(500px);
transition: all .3s;
&.active{
transform: translateX(0px);
}
}
}
}
.right_pane_code_wrap{

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-11-27 09:49:33
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-25 14:45:20
* @LastEditTime : 2019-12-27 10:39:00
*/
import './index.scss';
import React, { useState, useEffect } from 'react';
@ -105,7 +105,7 @@ const CommitRecord = (props) => {
// expected_output
} = commitRecordDetail;
if (Object.keys(commitRecordDetail).length > 0) {
console.log('当前状态====》》》', status);
// console.log('当前状态====》》》', status);
const classes = status === 0 ? 'record_result_suc' : 'record_result_err';
const showErrorCode = status !== 0 ? `ecord_error_info show_error_code` : `ecord_error_info`;
const showErrorCopy = status !== 0 ? `copy_error show_error_copy` : `copy_error`;

@ -3,15 +3,20 @@
* @Author: tangjiang
* @Github:
* @Date: 2019-11-27 14:59:51
* @LastEditors: tangjiang
* @LastEditTime: 2019-12-20 14:01:57
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-27 10:28:41
*/
import React, { useState, useEffect } from 'react';
import {connect} from 'react-redux';
import MyMonacoEditor from '../../components/myMonacoEditor';
import ControlSetting from '../../components/controlSetting';
import actions from '../../../../redux/actions';
// import QuillForEditor from '../../../../common/quillForEditor';
// import TextArea from 'antd/lib/input/TextArea';
import { Input, Form, Button } from 'antd';
// import FormItem from 'antd/lib/form/FormItem';
const { TextArea } = Input;
const FormItem = Form.Item;
const RightPane = (props) => {
const {
@ -20,6 +25,7 @@ const RightPane = (props) => {
submitUserCode,
input,
hack,
loading,
notice,
updateCode,
hadCodeUpdate,
@ -27,13 +33,18 @@ const RightPane = (props) => {
updateNotice,
saveUserInputCode,
restoreInitialCode,
saveOpacityType,
saveUserCodeForInterval
// saveOpacityType,
saveUserCodeForInterval,
addNotes,
changeLoadingState
} = props;
const [editorCode, setEditorCode] = useState('');
const [editorCode, setEditorCode] = useState(editor_code || hack.code);
const [noteClazz, setNoteClazz] = useState('editor_nodte_area');
const [noteCount] = useState(5000);
// const [code, setCode] = useState(editor_code || hack.code);
// let initFlag = true;
let initFlag = true;
useEffect(() => {
if (editor_code) {
setEditorCode(editor_code);
@ -52,24 +63,18 @@ const RightPane = (props) => {
let timer = null; // 定时器
// 代码块内容变化时
const handleCodeChange = (code) => {
// 保存用户提交的代码块
setEditorCode(code);
// 第一次回填代码内容时不更新;
if (initFlag) {
initFlag = false;
return;
}
const handleCodeChange = (value) => {
saveUserInputCode(value);
setEditorCode(value);
if (!timer) {
timer = setInterval(() => {
timer = setInterval(function () {
clearInterval(timer);
timer = null;
saveUserCodeForInterval && saveUserCodeForInterval(identifier, code);
saveUserCodeForInterval(identifier);
}, 3000);
}
// 保存用户代码块
saveUserInputCode(code);
}
// 代码调试
const handleDebuggerCode = (value) => {
// 调用保存代码块接口,成功后,调用调试接口
@ -86,6 +91,28 @@ const RightPane = (props) => {
updateNotice && updateNotice();
};
const handleClickNote = () => {
setNoteClazz('editor_nodte_area active');
}
const handleCancelNote = () => {
props.form.resetFields();
setNoteClazz('editor_nodte_area');
}
const handleSubmitNote = () => {
props.form.validateFields((err, values) => {
if (!err) {
changeLoadingState(true);
addNotes(identifier, values, function () {
setNoteClazz('editor_nodte_area');
props.form.resetFields();
});
}
});
}
const { getFieldDecorator } = props.form;
return (
<div className={'right_pane_code_wrap'}>
<MyMonacoEditor
@ -98,6 +125,40 @@ const RightPane = (props) => {
onUpdateNotice={handleUpdateNotice}
onRestoreInitialCode={handleRestoreInitialCode}
/>
<span
className="iconfont icon-biji student_notes"
onClick={handleClickNote}
></span>
{/* <div className="student_notes">
<TextArea rows={5} />
</div> */}
<div className={noteClazz}>
<Form>
<FormItem>
{
getFieldDecorator('notes',{
rules: [
{ required: true, message: '笔记不能为空' },
{ max: noteCount, message: `笔记最大字数为${noteCount}` }
],
initialValue: (hack && hack.notes) || ''
})(<TextArea
max={noteCount}
placeholder="请输入笔记内容"
rows="5"
/>)
}
</FormItem>
<FormItem style={{ textAlign: 'right' }}>
<Button loading={loading} style={{ marginRight: '10px' }} onClick={handleCancelNote}>取消</Button>
<Button type="primary" onClick={handleSubmitNote}>提交</Button>
</FormItem>
</Form>
</div>
<ControlSetting
identifier={identifier}
inputValue={input}
@ -117,10 +178,14 @@ const mapStateToProps = (state) => {
notice,
hadCodeUpdate
} = state.ojForUserReducer;
const {
loading
} = state.commonReducer;
// const { language, code } = hack;
return {
hack,
notice,
loading,
hadCodeUpdate,
editor_code,
input: userTestInput,
@ -141,9 +206,12 @@ const mapDispatchToProps = (dispatch) => ({
// 恢复初始代码
restoreInitialCode: (identifier, msg) => dispatch(actions.restoreInitialCode(identifier, msg)),
// saveOpacityType: (type) => dispatch(actions.saveOpacityType(type))
// 添加笔记
addNotes: (identifier, params, cb) => dispatch(actions.addNotes(identifier, params, cb)),
changeLoadingState: (flag) => dispatch(actions.changeLoadingState(flag))
});
export default connect(
mapStateToProps,
mapDispatchToProps
)(RightPane);
)(Form.create()(RightPane));

@ -0,0 +1,846 @@
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
} from "antd";
import Headplugselection from "./component/Headplugselection";
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 SiderBar from "../tpm/SiderBar";
class Question 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,
}
}
setdiscipline_id=(discipline_id)=>{
this.setState({
discipline_id:discipline_id,
sub_discipline_id:null,
tag_discipline_id: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: this.state.keywords,
page: this.state.page,
per_page:10,
};
this.getdata(data);
}
setsub_discipline_id=(sub_discipline_id)=>{
this.setState({
sub_discipline_id:sub_discipline_id,
tag_discipline_id: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: this.state.keywords,
page: this.state.page,
per_page:10,
};
this.getdata(data);
}
settag_discipline_id=(tag_discipline_id)=>{
this.setState({
tag_discipline_id:tag_discipline_id
})
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: this.state.keywords,
page: this.state.page,
per_page:10,
};
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,
};
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,
})
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: this.state.difficulty,
page: this.state.page,
per_page:10,
};
this.getdata(data);
}
getdata = (data) => {
const url = `/item_banks.json`;
this.setState({
booljupyterurls:true,
})
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,
})
}).catch((error) => {
////console.log(error)
this.setState({
booljupyterurls:false,
})
});
}
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,
};
this.getdata(data);
}
showDrawer = () => {
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,
})
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,
page: this.state.page,
per_page:10,
};
this.getdata(data);
}
setitem_types = (item_type) => {
this.setState({
item_type: item_type,
visiblemyss: false,
})
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: this.state.page,
per_page:10,
};
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
})
var data = {
discipline_id:this.state.discipline_id,
sub_discipline_id:this.state.sub_discipline_id,
tag_discipline_id:this.state.tag_discipline_id,
public: this.state.defaultActiveKey,
difficulty: this.state.difficulty,
item_type: this.state.item_type,
keywords: e.target.value,
page: this.state.page,
per_page:10,
};
this.getdata(data);
}
setdatafuns = (value) => {
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,
};
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,
};
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,
};
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="/item_baskets.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,
};
this.getdata(data);
this.getbasket_listdata();
this.setState({
visible:true
})
}
}).catch((error) => {
//console.log(error);
})
}
// 撤销
getitem_basketss=(id)=>{
//选用题型可以上传单个 或者多个题型
let url=`/item_baskets/${id}.json`;
axios.delete(url)
.then((result) => {
if (result.data.status == 0) {
this.props.showNotification(`撤销成功`);
var data = {
discipline_id:this.state.discipline_id,
sub_discipline_id:this.state.sub_discipline_id,
tag_discipline_id:this.state.tag_discipline_id,
public: this.state.defaultActiveKey,
difficulty: this.state.difficulty,
item_type: this.state.item_type,
keywords: this.state.keywords,
page: this.state.page,
per_page:10,
};
this.getdata(data);
this.getbasket_listdata();
}
}).catch((error) => {
//console.log(error);
})
}
//全选试题库
selectallquestionsonthispage=()=>{
var item_idsdata=[];
var arr= this.state.Contentdata.items;
for(let data of arr) {
item_idsdata.push(data.id);
}
const data={
item_ids:item_idsdata
}
this.getitem_baskets(data);
}
//删除大题型
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,
};
this.getdata(data);
this.getbasket_listdata();
}
})
.catch(function (error) {
//console.log(error);
});
}
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
} = 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>
:""}
<QuestionModals {...this.props}{...this.state} modalsTypes={modalsTypes} modalCancels={() => this.modalCancels()}
setDownloads={(e) => this.setDownloads(e)}></QuestionModals>
<QuestionModal {...this.props}{...this.state} modalsType={modalsType} modalCancel={() => this.modalCancel()}
setDownload={() => this.setDownload()}></QuestionModal>
<SiderBar
{...this.props}
{...this.state}
showDrawer={() => this.showDrawer()}
Headertop={Headertop}/>
{/*顶部*/}
<Headplugselection {...this.props} {...this.state}
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)}
></Headplugselection>
{/*头部*/}
<Contentpart {...this.state} {...this.props}
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)}
setitem_types={(e) => this.setitem_types(e)}
handleVisibleChange={(e) => this.handleVisibleChange(e)}
setdifficulty={(e) => this.setdifficulty(e)}
showmodels={(e) => this.showmodels(e)}
showmodelysl={(e) => this.showmodelysl(e)}
callback={(e) => this.callback(e)}></Contentpart>
{/*分页*/}
{/*<div className="clearfix mt5">*/}
{/*<div className="educontent mt10 pb20 w1200s">*/}
{/* fenye*/}
{
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>
}
{/*抽屉效果*/}
<style>
{
`
.ant-drawer-content-wrapper{
width: 200px !important;
overflowhidden;
margin-top: 62px;
}
.ant-drawer-body{
height: 100%;
background:rgba(234,234,234,1);
}
`
}
</style>
<Drawer
className="drawercontainer"
placement={placement}
closable={false}
onClose={() => this.onClose()}
visible={visible}
mask={false}
closable={true}
>
{Datacount && Datacount > 0 ?
<div>
<div className="mt25 mb26">
<Input placeholder="未命名试卷"/>
</div>
{
single_questions_count === 0 ?
""
: <div className="sortinxdirection" onClick={()=>this.showQuestionModals("SINGLE")} >
<p
className="w50s intermediatecenterysls sortinxdirection font-14">单选题{'('}{single_questions_count}{')'}</p>
<p className="w50s intermediatecenterysls xaxisreverseorder"><i
className="iconfont icon-shanchu1 font-14 lg lh30 icondrawercolor "></i></p>
</div>
}
{
multiple_questions_count === 0 ?
""
:
<div className="sortinxdirection" onClick={()=>this.showQuestionModals("MULTIPLE")}>
<p
className="w50s intermediatecenterysls sortinxdirection font-14">多选题{'('}{multiple_questions_count}{')'}</p>
<p className="w50s intermediatecenterysls xaxisreverseorder"><i
className="iconfont icon-shanchu1 font-14 lg lh30 icondrawercolor "></i></p>
</div>
}
{
judgement_questions_count === 0 ?
""
:
<div className="sortinxdirection" onClick={()=>this.showQuestionModals("JUDGMENT")}>
<p
className="w50s intermediatecenterysls sortinxdirection font-14">判断题{'('}{judgement_questions_count}{')'}</p>
<p className="w50s intermediatecenterysls xaxisreverseorder"><i
className="iconfont icon-shanchu1 font-14 lg lh30 icondrawercolor "></i></p>
</div>
}
{
completion_questions_count === 0 ?
""
:
<div className="sortinxdirection" onClick={()=>this.showQuestionModals("COMPLETION")}>
<p
className="w50s intermediatecenterysls sortinxdirection font-14">填空题{'('}{completion_questions_count}{')'}</p>
<p className="w50s intermediatecenterysls xaxisreverseorder"><i
className="iconfont icon-shanchu1 font-14 lg lh30 icondrawercolor "></i></p>
</div>
}
{
subjective_questions_count === 0 ?
""
:
<div className="sortinxdirection" onClick={()=>this.showQuestionModals("SUBJECTIVE")}>
<p
className="w50s intermediatecenterysls sortinxdirection font-14">简答题{'('}{subjective_questions_count}{')'}</p>
<p className="w50s intermediatecenterysls xaxisreverseorder"><i
className="iconfont icon-shanchu1 font-14 lg lh30 icondrawercolor "></i></p>
</div>
}
{
practical_questions_count === 0 ?
""
:
<div className="sortinxdirection">
<p
className="w50s intermediatecenterysls sortinxdirection font-14">实训题{'('}{practical_questions_count}{')'}</p>
<p className="w50s intermediatecenterysls xaxisreverseorder"><i
className="iconfont icon-shanchu1 font-14 lg lh30 icondrawercolor "></i></p>
</div>
}
{
program_questions_count === 0 ?
""
:
<div className="sortinxdirection" onClick={()=>this.showQuestionModals("PROGRAM")}>
<p
className="w50s intermediatecenterysls sortinxdirection font-14">编程题{'('}{program_questions_count}{')'}</p>
<p className="w50s intermediatecenterysls xaxisreverseorder"><i
className="iconfont icon-shanchu1 font-14 lg lh30 icondrawercolor "></i></p>
</div>
}
<div className="intermediatecenter verticallayout mt42">
<div className="drawerbutton">
试卷预览
</div>
</div>
</div>
:
<div className="drawernonedatadiv intermediatecenter">
<NoneData></NoneData>
</div>
}
</Drawer>
</div>
)
}
}
export default SnackbarHOC()(TPMIndexHOC(Question));

@ -0,0 +1,584 @@
import React, {Component} from "react";
import {Link, NavLink} from 'react-router-dom';
import {WordsBtn, ActionBtn, SnackbarHOC, getImageUrl} from 'educoder';
import axios from 'axios';
import {
notification,
Spin,
Table,
Pagination,
Drawer,
Input,
Button,
Breadcrumb
} from "antd";
import {TPMIndexHOC} from "../tpm/TPMIndexHOC";
import Itembankstop from "./component/Itembankstop";
import NoneData from './component/NoneData';
import './questioncss/questioncom.css';
import '../tpm/newshixuns/css/Newshixuns.css';
import Choicequestion from './component/Choicequestion';
import SingleEditor from "./component/SingleEditor";
import ChoquesEditor from "./component/ChoquesEditor"
import JudquestionEditor from "./component/JudquestionEditor";
import Bottomsubmit from "../../modules/modals/Bottomsubmit";
// var itembankstop=null;
// var singleEditor=null;
// var Judquestio=null;
// var Choques=null;
class Questionitem_banks extends Component {
constructor(props) {
super(props);
this.contentMdRef = React.createRef();
this.answerMdRef = React.createRef();
this.Choques = React.createRef();
this.Judquestio = React.createRef();
this.state = {
item_type: null,
item_banksedit: [],
myquestion_choicesco: [],
disciplinesdata: [],
knowledgepoints: [],
disciplmy:[]
}
}
//初始化
componentDidMount() {
// let {defaultActiveKey}= this.state;
// var data={
// public:defaultActiveKey
// };
// 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
// })
// }
// }
// });
const params = this.props && this.props.match && this.props.match.params;
if (JSON.stringify(params) === "{}") {
//新增
} else {
//编辑
const url = `/item_banks/${this.props.match.params.id}/edit.json`;
axios.get((url)).then((response) => {
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("Questionitem_banks");
//console.log(response.data);
this.setState({
item_banksedit: response.data,
})
}).catch((error) => {
//////console.log(error)
});
}
let urls = `/disciplines.json`;
axios.get(urls, {
params: {
source: "question"
}
}).then((response) => {
if (response) {
this.setState({
disciplinesdata: response.data.disciplines,
})
if (response.data) {
if (response.data.disciplines) {
const didata = response.data.disciplines;
for (var i = 0; i < didata.length; i++) {
const childern=[];
//方向
const fxdidata = didata[i].sub_disciplines;
for (var j = 0; j < fxdidata.length; j++) {
//课程
const zsddata = fxdidata[j].tag_disciplines;
childern.push(
{
value: fxdidata[j].id,
label: fxdidata[j].name,
}
)
for (var k = 0; k < zsddata.length; k++) {
//知识点
this.state.knowledgepoints.push(zsddata[k]);
}
}
const datakec={
value: didata[i].id,
label: didata[i].name,
children: childern,
}
this.state.disciplmy.push(datakec);
}
this.setState({
knowledgepoints: this.state.knowledgepoints,
disciplmy:this.state.disciplmy,
})
}
}
}
});
}
getdata = (data) => {
// const url=`/item_banks.json`;
// axios.get((url),{params:data}).then((response) => {
// 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);
// }).catch((error) => {
// //////console.log(error)
//
// });
}
getcontentMdRef = (Ref) => {
this.contentMdRef = Ref;
}
getanswerMdRef = (Ref) => {
this.answerMdRef = Ref;
}
getJudquestio = (Ref) => {
this.Judquestio = Ref;
}
getChoquesEditor = (Ref) => {
this.Choques = Ref;
}
//跳转道描点的地方
scrollToAnchor = (anchorName) => {
try {
if (anchorName) {
// 找到锚点
let anchorElement = document.getElementById(anchorName);
// 如果对应id的锚点存在就跳转到锚点
if (anchorElement) {
anchorElement.scrollIntoView();
}
}
} catch (e) {
}
}
preservation = () => {
//////console.log("preservation");
// //////console.log(this.contentMdRef);
// //////console.log(this.answerMdRef);
//////console.log("preservation222");
//////console.log(this.contentMdRef.Getdatas());
//////console.log("preservation3333");
//////console.log(this.answerMdRef.onSave());
const params = this.props && this.props.match && this.props.match.params;
var url = "";
var boolnew = true;
if (JSON.stringify(params) === "{}") {
// "新增"
url = "/item_banks.json";
boolnew = true;
} else {
url = `/item_banks/${params.id}.json`;
boolnew = false;
// "编辑"
}
if (this.contentMdRef.Getdatas().length === 0) {
this.scrollToAnchor("Itembankstopid");
return;
}
console.log("preservation");
console.log(this.contentMdRef.Getdatas());
var Getdatasdata=this.contentMdRef.Getdatas();
if (this.state.item_type === null) {
return
}
if (this.state.item_type === "SINGLE") {
if (this.answerMdRef != null) {
//单选题
// //console.log(this.answerMdRef.onSave());
if (this.answerMdRef.onSave().length === 0) {
return;
}
var anserdata = this.answerMdRef.onSave();
const choices = [];
// 1: [3]
// 2: (4) ["1", "2", "3", "4"]
for (var k = 0; k < anserdata[2].length; k++) {
const choicesdata = {
choice_text: anserdata[2][k],
is_answer: anserdata[1][0] === (k + 1) ? 1 : 0,
}
choices.push(choicesdata);
}
// repertoire_id:1,
// sub_repertoire_id:1,
// tag_repertoire_id:[1,3],
var myrbkc=[];
var Getdatasdatas=Getdatasdata[2].rbzsd;
for(let myda of Getdatasdatas) {
myrbkc.push(myda.id);
}
var data = {
discipline_id: Getdatasdata[3].rbkc[0],
sub_discipline_id: Getdatasdata[3].rbkc[1],
tag_discipline_id: myrbkc,
name: anserdata[0],
item_type: Getdatasdata[1].rbtx,
difficulty:Getdatasdata[0].rbnd,
analysis: anserdata[3],
choices: choices,
};
if (boolnew === true) {
axios.post(url, data)
.then((result) => {
if (result.data.status == 0) {
this.props.showNotification(`新增单选题成功`);
this.props.history.replace('/question');
}
}).catch((error) => {
//console.log(error);
})
} else {
axios.put(url, data)
.then((result) => {
if (result.data.status == 0) {
this.props.showNotification(`编辑单选题成功`);
this.props.history.replace('/question');
}
}).catch((error) => {
//console.log(error);
})
}
}
}
if (this.state.item_type === "MULTIPLE") {
if (this.Choques != null) {
//多选题
// //console.log(this.Choques.onSave());
if (this.Choques.onSave().length === 0) {
return;
}
var anserdata = this.Choques.onSave();
const choices = [];
// 1: [3]
// 2: (4) ["1", "2", "3", "4"]
//console.log("MULTIPLE");
//console.log(anserdata);
for (var k = 0; k < anserdata[2].length; k++) {
var bool = false
for (var y = 0; y < anserdata[1].length; y++) {
if (anserdata[1][y] === (k + 1)) {
bool = true
}
}
const choicesdata = {
choice_text: anserdata[2][k],
is_answer: bool === true ? 1 : 0,
}
choices.push(choicesdata);
}
var myrbkc=[];
var Getdatasdatas=Getdatasdata[2].rbzsd;
for(let myda of Getdatasdatas) {
myrbkc.push(myda.id);
}
var data = {
discipline_id: Getdatasdata[3].rbkc[0],
sub_discipline_id: Getdatasdata[3].rbkc[1],
tag_discipline_id: myrbkc,
name: anserdata[0],
item_type: Getdatasdata[1].rbtx,
difficulty:Getdatasdata[0].rbnd,
analysis: anserdata[3],
choices: choices,
};
if (boolnew === true) {
axios.post(url, data)
.then((result) => {
if (result.data.status == 0) {
this.props.showNotification(`新增多选题成功`);
this.props.history.replace('/question');
}
}).catch((error) => {
//console.log(error);
})
} else {
axios.put(url, data)
.then((result) => {
if (result.data.status == 0) {
this.props.showNotification(`编辑多选题成功`);
this.props.history.replace('/question');
}
}).catch((error) => {
//console.log(error);
})
}
}
}
if (this.state.item_type === "JUDGMENT") {
if (this.Judquestio != null) {
//判断题
// //console.log(this.Judquestio.onSave());
if (this.Judquestio.onSave().length === 0) {
return;
}
var anserdata = this.Judquestio.onSave();
const choices = [];
const choicesdata = {
choice_text: "正确",
is_answer: anserdata[1] === "0" ? 1 : 0,
}
choices.push(choicesdata);
const choicesdatas = {
choice_text: "错误",
is_answer: anserdata[1] === "1" ? 1 : 0,
}
choices.push(choicesdatas);
var myrbkc=[];
var Getdatasdatas=Getdatasdata[2].rbzsd;
for(let myda of Getdatasdatas) {
myrbkc.push(myda.id);
}
var data = {
discipline_id: Getdatasdata[3].rbkc[0],
sub_discipline_id: Getdatasdata[3].rbkc[1],
tag_discipline_id: myrbkc,
name: anserdata[0],
item_type: Getdatasdata[1].rbtx,
difficulty:Getdatasdata[0].rbnd,
analysis: anserdata[2],
choices: choices,
};
if (boolnew === true) {
axios.post(url, data)
.then((result) => {
if (result.data.status == 0) {
this.props.showNotification(`新增判断题成功`);
this.props.history.replace('/question');
}
}).catch((error) => {
//console.log(error);
})
} else {
axios.put(url, data)
.then((result) => {
if (result.data.status == 0) {
this.props.showNotification(`编辑判断题成功`);
this.props.history.replace('/question');
}
}).catch((error) => {
//console.log(error);
})
}
}
}
if (this.state.item_type === "PROGRAM") {
//编程题 跳转到 oj 中创建
}
}
setitem_type = (item_type) => {
this.setState({
item_type: item_type
})
}
render() {
let {page, limit, count, Headertop, visible, placement, modalsType, item_type} = this.state;
const params = this.props && this.props.match && this.props.match.params;
// //console.log(params);
return (
<div>
<div id={"Itembankstopid"} className="newMain clearfix intermediatecenter "
style={{}}
>
<style>
{
`
.newFooter{
display: none;
}
`
}
</style>
<div className="w1200mss">
<div className="w100s mt30">
<Breadcrumb separator=">">
<Breadcrumb.Item href="/question">试题库</Breadcrumb.Item>
<Breadcrumb.Item>{JSON.stringify(params) === "{}" ? "新增" : "编辑"}试题</Breadcrumb.Item>
</Breadcrumb>
</div>
{/*题目头部操作*/}
<Itembankstop
{...this.state}
{...this.props}
getcontentMdRef={(ref) => this.getcontentMdRef(ref)}
setitem_type={(item) => this.setitem_type(item)}
>
</Itembankstop>
{
item_type && item_type === "SINGLE" ?
<div className=" clearfix educontent w100s w1200fpx mt19">
<SingleEditor
{...this.state}
{...this.props}
getanswerMdRef={(ref) => this.getanswerMdRef(ref)}
>
</SingleEditor>
</div>
: item_type && item_type === "MULTIPLE" ?
<div className=" clearfix educontent w100s w1200fpx mt19">
<ChoquesEditor
{...this.state}
{...this.props}
getanswerMdRef={(ref) => this.getChoquesEditor(ref)}
>
</ChoquesEditor>
</div>
: item_type && item_type === "JUDGMENT" ?
<div className=" clearfix educontent w100s w1200fpx mt19">
<JudquestionEditor
{...this.state}
{...this.props}
item_banksedit={this.state.item_banksedit}
getanswerMdRef={(ref) => this.getJudquestio(ref)}
>
</JudquestionEditor>
</div>
: item_type && item_type === "PROGRAM" ?
""
: ""
}
</div>
</div>
{
item_type === null ?
""
:
<Bottomsubmit {...this.props} {...this.state} bottomvalue={item_type === "PROGRAM" ? "创建" : "保存"}
onSubmits={() => this.preservation()} url={item_type === "PROGRAM" ?'/problems':'/question'}></Bottomsubmit>
}
</div>
)
}
}
export default SnackbarHOC()(TPMIndexHOC(Questionitem_banks));

@ -0,0 +1,51 @@
import React, {Component} from "react";
import {Link, NavLink} from 'react-router-dom';
import {WordsBtn, ActionBtn,SnackbarHOC,getImageUrl} from 'educoder';
import axios from 'axios';
import {
notification,
Spin,
Table,
Pagination,
Radio,
Checkbox,
Form,
Input,
Select,
Cascader,
Col, Row, InputNumber, DatePicker, AutoComplete,Button,Tag
} from "antd";
import './../questioncss/questioncom.css';
import SingleEditor from './../component/SingleEditor';
class Choicequestion extends Component {
constructor(props) {
super(props);
this.state = {
page:1,
Knowpoints:[]
}
}
//初始化
componentDidMount(){
}
render() {
let {page}=this.state;
const { getFieldDecorator } = this.props.form;
return (
<div className=" clearfix educontent Contentquestionbankstyle w100s w1200fpx mt19" >
<SingleEditor>
</SingleEditor>
</div>
)
}
}
const Choicequestions = Form.create({ name: 'Choicequestions' })(Choicequestion);
export default Choicequestions;

@ -0,0 +1,384 @@
import React,{ Component } from "react";
import {
Form, Input, InputNumber, Switch, Radio,
Slider, Button, Upload, Icon, Rate, Checkbox, message,
Row, Col, Select, Modal, Tooltip
} from 'antd';
import TPMMDEditor from '../../../modules/tpm/challengesnew/TPMMDEditor';
import axios from 'axios'
import update from 'immutability-helper'
import './../questioncss/questioncom.css';
import {getUrl, ActionBtn, DMDEditor, ConditionToolTip} from 'educoder';
const { TextArea } = Input;
const confirm = Modal.confirm;
const $ = window.$
const { Option } = Select;
const tagArray = [
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
]
//题库的试卷 多选题 组件
class ChoquesEditor extends Component{
constructor(props){
super(props);
/**
choice_id: 32076
choice_position: 1
choice_text: "1"
standard_boolean: true
*/
const {question_choices} = this.props;
let _standard_answers = undefined;
let _question_choices = undefined;
if (question_choices) {
_standard_answers = []
_question_choices = []
question_choices.forEach((item, index) => {
_standard_answers.push(item.standard_boolean)
_question_choices.push(item.choice_text)
})
}
const choicescomy=[];
try {
if(this.props.item_banksedit){
if(this.props.item_banksedit.choices){
this.props.item_banksedit.choices.forEach((item, index) => {
choicescomy.push({
choice_text:item.choice_text,
standard_boolean:item.is_answer,
})
})
_standard_answers = []
_question_choices = []
choicescomy.forEach((item, index) => {
_standard_answers.push(item.standard_boolean)
_question_choices.push(item.choice_text)
})
}
}
}catch (e) {
}
this.state = {
question_choices: _question_choices || ['', '', '', ''],
standard_answers: _standard_answers || [false, false, false, false],
question_title: this.props.question_title || '',
question_type: this.props.question_type || 0,
question_score: this.props.question_score || this.props.init_question_score,
question_titles:this.props.question_titles||'',
}
}
addOption = () => {
const { question_choices, standard_answers } = this.state;
// ////console.log("addOption");
// ////console.log(question_choices);
// ////console.log(standard_answers);
question_choices.push('')
standard_answers.push(false)
this.setState({ question_choices, standard_answers })
}
deleteOption = (index) => {
let {question_choices}=this.state;
// ////console.log("deleteOption");
// ////console.log(question_choices);
if(question_choices[index]===""){
// repeat code
this.toMDMode(null)
this.setState(
(prevState) => ({
question_choices : update(prevState.question_choices, {$splice: [[index, 1]]}),
standard_answers : update(prevState.standard_answers, {$splice: [[index, 1]]})
})
)
}else{
// this.props.confirm({
// content: `确认要删除这个选项吗?`,
// onOk: () => {
this.toMDMode(null)
this.setState(
(prevState) => ({
question_choices : update(prevState.question_choices, {$splice: [[index, 1]]}),
standard_answers : update(prevState.standard_answers, {$splice: [[index, 1]]})
})
)
// }
// })
}
}
onSave = () => {
var editordata=[];
const {question_title, question_score, question_type,question_titles, question_choices, standard_answers } = this.state;
const { question_id_to_insert_after, question_id } = this.props
// TODO check
const answerArray = standard_answers.map((item, index) => { return item == true ? index+1 : -1 }).filter(item => item != -1);
if(!question_title) {
this.refs['titleEditor'].showError()
this.props.showNotification('请您输入题干');
return editordata;
}
if(!answerArray || answerArray.length == 0) {
this.props.showNotification('请先点击选择本选择题的正确选项');
return editordata;
}
if(!answerArray || answerArray.length < 2) {
this.props.showNotification('多选题最小正确选项为2个');
return editordata;
}
for(let i = 0; i < question_choices.length; i++) {
if (!question_choices[i]) {
this.refs[`optionEditor${i}`].showError()
this.props.showNotification(`请先输入 ${tagArray[i]} 选项的内容`);
return editordata;
}
}
if(!question_titles) {
this.refs['titleEditor2'].showError()
this.props.showNotification('请您输入题目解析');
return editordata;
}
/**
{
"question_title":"同学朋友间常用的沟通工具是什么?",
"question_type":1,
"question_score":5,
"question_choices":["a答案","b答案","c答案","d答案"],
"standard_answers":[1]
}*/
editordata=[question_title,answerArray,question_choices,question_titles];
// question_title,
// question_type: answerArray.length > 1 ? 1 : 0,
// question_score,
// question_choices,
// standard_answers: answerArray,
// insert_id: question_id_to_insert_after || undefined
return editordata;
}
onCancel = () => {
this.props.onEditorCancel()
}
componentDidMount = () => {
try {
this.props.getanswerMdRef(this);
}catch (e) {
}
try {
this.setState({
item_banksedit:this.props.item_banksedit,
question_title:this.props.item_banksedit.name,
question_titles:this.props.item_banksedit.analysis,
mychoicess:this.props.item_banksedit.choices,
})
}catch (e) {
}
}
componentDidUpdate(prevProps) {
//console.log("componentDidUpdate");
// //console.log(prevProps);
// //console.log(this.props.item_banksedit);
if(prevProps.item_banksedit !== this.props.item_banksedit) {
this.setState({
item_banksedit: this.props.item_banksedit,
question_title: this.props.item_banksedit.name,
question_titles: this.props.item_banksedit.analysis,
mychoicess: this.props.item_banksedit.choices,
})
}
}
onOptionClick = (index) => {
let standard_answers = this.state.standard_answers.slice(0)
standard_answers[index] = !standard_answers[index]
this.setState({ standard_answers })
}
onOptionContentChange = (value, index) => {
if (index >= this.state.question_choices.length) {
// TODO 新建然后删除CD选项再输入题干会调用到这里且index是3
return;
}
let question_choices = this.state.question_choices.slice(0);
question_choices[index] = value;
this.setState({ question_choices })
}
on_question_score_change = (e) => {
this.setState({ question_score: e })
}
toMDMode = (that) => {
if (this.mdReactObject) {
let mdReactObject = this.mdReactObject;
this.mdReactObject = null
mdReactObject.toShowMode()
}
this.mdReactObject = that;
}
toShowMode = () => {
}
render() {
let { question_title, question_score, question_type, question_choices, standard_answers,question_titles} = this.state;
let { question_id, index, exerciseIsPublish,
// question_title,
// question_type,
// question_score,
isNew } = this.props;
// const { getFieldDecorator } = this.props.form;
// const isAdmin = this.props.isAdmin()
// const courseId=this.props.match.params.coursesId;
// const isEdit = !!this.props.question_id
const qNumber = `question_`;
// TODO show模式 isNew为false isEdit为false
// [true, false, true] -> [0, 2]
const answerTagArray = standard_answers.map((item, index) => { return item == true ? tagArray[index] : -1 }).filter(item => item != -1);
// ////console.log("xuanzheshijuan");
// ////console.log(answerTagArray);
// ////console.log(!exerciseIsPublish);
return(
<div className="padding20-30 signleEditor duoxuano" id={qNumber}>
<style>{`
.optionMdEditor {
flex:1
}
.optionRow {
margin:0px!important;
/* margin-bottom: 20px!important; */
}
.signleEditor .content_editorMd_show{
display: flex;
margin-top:0px!important;
border-radius:2px;
max-width: 1056px;
word-break:break-all;
}
#e_tips_mdEditor_question_undefined4{
display: none;
}
`}</style>
<p className="mb10 clearfix">
{/* {!question_id ? '新建' : '编辑'} */}
<span className="xingcolor font-16 fl mr4">*</span>
<span className="xingtigan fl">题干</span>
</p>
<TPMMDEditor mdID={qNumber} placeholder="请您输入题干" height={155} className=" mt10"
initValue={question_title} onChange={(val) => this.setState({ question_title: val})}
ref="titleEditor"
></TPMMDEditor>
<div className="mb10 sortinxdirection">
{/* {!question_id ? '新建' : '编辑'} */}
<span className="xingcolor font-16 fl mr4">*</span>
<span className="xingtigans fl"><span className="xingtigan">答案选项</span></span>
</div>
{question_choices.map( (item, index) => {
const bg = standard_answers[index] ? 'check-option-bg' : ''
return <div className="df optionRow " >
{/* 点击设置答案 */}
{/* TODO 加了tooltip后会丢失掉span的class */}
{/* <Tooltip title={standard_answers[index] ? '点击取消标准答案设置' : '点击设置为标准答案'}> */}
<span class={`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>
</ConditionToolTip>
</span>
{/* </Tooltip> */}
<div style={{ flex: '0 0 1038px'}}>
<DMDEditor
ref={`optionEditor${index}`}
toMDMode={this.toMDMode} toShowMode={this.toShowMode}
height={166} className={'optionMdEditor'} noStorage={true}
mdID={qNumber + index} placeholder="" onChange={(value) => this.onOptionContentChange(value, index)}
initValue={item}
></DMDEditor>
</div>
{exerciseIsPublish || index<=2?
<i className=" font-18 ml15 mr20"></i>
:<Tooltip title="删除">
<i className="iconfont icon-htmal5icon19 font-18 color-grey-c ml15" onClick={() => this.deleteOption(index)}></i>
</Tooltip> }
{ !exerciseIsPublish && index<7 && <Tooltip title={`新增参考答案`}>
<i className="color-green font-16 iconfont icon-roundaddfill ml6"
onClick={() => this.addOption()}
style={{float: 'right', visibility: index == question_choices.length - 1 ? '' : 'hidden', marginTop: '2px'}}
></i>
</Tooltip>}
</div>
}) }
<div>
<p className="mb10 clearfix">
{/* {!question_id ? '新建' : '编辑'} */}
<span className="xingcolor font-16 fl mr4">*</span>
<span className="xingtigan fl">题目解析</span>
</p>
<style>{`
.optionMdEditor {
flex:1
}
.optionRow {
margin:0px!important;
/* margin-bottom: 20px!important; */
}
.signleEditor .content_editorMd_show{
display: flex;
margin-top:0px!important;
border-radius:2px;
max-width: 1056px;
word-break:break-all;
}
`}</style>
<TPMMDEditor mdID={qNumber+question_choices.length} placeholder="请您输入题目解析" height={155} className=" mt10"
initValue={question_titles} onChange={(val) => this.setState({ question_titles: val})}
ref="titleEditor2"
></TPMMDEditor>
</div>
</div>
)
}
}
// RouteHOC()
export default (ChoquesEditor);

@ -0,0 +1,237 @@
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,
Tabs,
Input,
Popover
} from "antd";
import './../questioncss/questioncom.css';
import NoneDatas from '../component/NoneDatas';
import LoadingSpin from '../../../common/LoadingSpin';
import Contentquestionbank from "./Contentquestionbank";
import Listjihe from "./Listjihe";
const { TabPane } = Tabs;
const Search = Input.Search;
class Contentpart extends Component {
constructor(props) {
super(props);
this.state = {
page:1,
}
}
//初始化
componentDidMount(){
}
render() {
let {page}=this.state;
let {defaultActiveKey}=this.props;
const content = (
<div className="questiontypes" style={{
width:'93px',
height:'161px',
}}>
<p className="questiontype " onClick={()=>this.props.setitem_types("SINGLE")}>单选题</p>
<p className="questiontypeheng" ></p>
<p className="questiontype " onClick={()=>this.props.setitem_types("MULTIPLE")}>多选题</p>
<p className="questiontypeheng"></p>
<p className="questiontype " onClick={()=>this.props.setitem_types("JUDGMENT")}>判断题</p>
<p className="questiontypeheng"></p>
<p className="questiontype " onClick={()=>this.props.setitem_types("PROGRAM")}>编程题</p>
<p className="questiontypeheng"></p>
</div>
);
const contents = (
<div className="questiontypes" style={{
width:'93px',
height:'120px',
}}>
<p className="questiontype " onClick={()=>this.props.setdifficulty(1)}>简单</p>
<p className="questiontypeheng"></p>
<p className="questiontype " onClick={()=>this.props.setdifficulty(2)}>适中</p>
<p className="questiontypeheng"></p>
<p className="questiontype " onClick={()=>this.props.setdifficulty(3)}>困难</p>
<p className="questiontypeheng"></p>
</div>
);
const buttonWidth = 70;
//console.log("Contentpart");
//console.log(this.props);
return (
<div className=" clearfix mt40">
<div className="educontent mt10 pb20 w1200s">
<div className="w1200ms contentparttit" style={{
position: "relative",
}}>
<style>
{
`
.contentparttit .ant-tabs-nav .ant-tabs-tab{
margin: 10px 10px 10px 0 !important;
}
.contentparttit .ant-tabs-nav .ant-tabs-ink-bar{
width: 31px !important;
left: 14px;
}
`
}
</style>
<Tabs defaultActiveKey={defaultActiveKey} onChange={(e)=>this.props.callback(e)}>
<TabPane tab="公共" key="1">
</TabPane>
<TabPane tab="我的" key="0">
</TabPane>
</Tabs>
<div className=" mt19" style={{
position:"absolute",
top: "0px",
right:" 0px",
paddingRight: "20px",
}}>
<style>
{
`
.xaxisreverseorder .ant-input-group-addon{
width: 60px !important;
}
.xaxisreverseorder .ant-input-lg {
height: 41px;}
.xaxisreverseorder .ant-popover{
top: 348px !important;
}
.ant-popover-inner-content {
padding:0px !important;
}
`
}
</style>
<div className="xaxisreverseorder">
{
defaultActiveKey===0||defaultActiveKey==="0"?
<a href={'/question/newitem'}>
<div className="newbutoon">
<p className="newbutoontes" >新增</p>
</div>
</a>
:""
}
<Popover placement="bottom" content={contents} trigger="click" visible={this.props.visiblemys} onVisibleChange={()=>this.props.handleVisibleChange(true)}>
<div className=" sortinxdirection mr10">
<div className="subjecttit">
难度
</div>
<i className="iconfont icon-sanjiaoxing-down font-12 lg ml7 icondowncolor"></i>
</div>
</Popover>
<Popover placement="bottom" content={content} trigger="click" visible={this.props.visiblemyss} onVisibleChange={()=>this.props.handleVisibleChanges(true)}>
<div className="sortinxdirection mr40">
<div className="subjecttit">
题型
</div>
<i className="iconfont icon-sanjiaoxing-down font-12 lg ml7 icondowncolor"></i>
</div>
</Popover>
<Search
style={{ width: "347px",marginRight:"60px",}}
placeholder="请输入题目名称、内容"
enterButton
size="large"
onInput={(e)=>this.props.setdatafunsval(e)}
onSearch={ (value)=>this.props.setdatafuns(value)} />
</div>
</div>
</div>
{/*内容*/}
{
this.props.Contentdata.items === undefined ||this.props.Contentdata.items === null||this.props.Contentdata.items.length===0 ?
<div className=" w100s mb10"></div>
:
<div className=" w100s mb10">
{
defaultActiveKey===1||defaultActiveKey==="1"?
<Contentquestionbank {...this.props} {...this.state} selectallquestionsonthispage={()=>this.props.selectallquestionsonthispage()}></Contentquestionbank>
:""
}
{
defaultActiveKey===0||defaultActiveKey==="0"?
<Contentquestionbank {...this.props} {...this.state} selectallquestionsonthispage={()=>this.props.selectallquestionsonthispage()}></Contentquestionbank>
:""
}
</div>
}
<div className="minheight">
{/*列表集合*/}
<div className=" w100s">
{
this.props.booljupyterurls===true?
<LoadingSpin></LoadingSpin>
:
this.props.Contentdata.items === undefined ||this.props.Contentdata.items === null||this.props.Contentdata.items.length===0?
<NoneDatas></NoneDatas>
: this.props.Contentdata.items.map((object, index) => {
return (
<Listjihe {...this.state} {...this.props} items={object}
getitem_basketss={(id)=>this.props.getitem_basketss(id)}
getitem_baskets={(e)=>this.props.getitem_baskets(e)}
showmodels={(e)=>this.props.showmodels(e)}
showmodelysl={(e)=>this.props.showmodelysl(e)}>
</Listjihe>
)
})}
</div>
</div>
</div>
</div>
)
}
}
export default Contentpart

@ -0,0 +1,70 @@
import React, {Component} from "react";
import {Link, NavLink} from 'react-router-dom';
import {WordsBtn, ActionBtn,SnackbarHOC,getImageUrl} from 'educoder';
import axios from 'axios';
import {
notification,
Spin,
Table,
Pagination,
Radio,
Checkbox
} from "antd";
import './../questioncss/questioncom.css';
class Contentquestionbank extends Component {
constructor(props) {
super(props);
this.state = {
page:1,
}
}
//初始化
componentDidMount(){
////console.log("componentDidMount");
////console.log(this.state);
////console.log(this.props);
// let homeworkid = this.props.match.params.homeworkid;
// let url = "/homework_commons/" + homeworkid + "/end_groups.json";
// axios.get(url).then((response) => {
// if (response.status === 200) {
// this.setState({})
// }
// }).catch((error) => {
// ////console.log(error)
// });
}
onChange=(e)=> {
////console.log(`checked = ${e.target.checked}`);
}
render() {
let {page}=this.state;
return (
<div className=" clearfix mt5 Contentquestionbankstyle">
<div className="educontent mt10 w100s">
<div className="sortinxdirection w100s" >
<div className="sortinxdirection w50s">
<Checkbox onChange={()=>this.props.selectallquestionsonthispage()}></Checkbox>
<p className="setequesbank ml20">选用本页全部试题</p>
</div>
<div className="xaxisreverseorder testpaper w50s">
{this.props.items_count?this.props.items_count:0}个试题
</div>
</div>
</div>
</div>
)
}
}
export default Contentquestionbank ;

@ -0,0 +1,277 @@
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,
} from "antd";
import './../questioncss/questioncom.css';
class Headplugselection extends Component {
constructor(props) {
super(props);
this.state = {
page:1,
titlestting:"全部",
titlesttingid:null,
titlesttings:null,
titlesttingss:null,
}
}
//初始化
componentDidMount(){
}
//
// setdiscipline_id={(e)=>this.setdiscipline_id(e)}
// setsub_discipline_id={(e)=>this.setsub_discipline_id(e)}
// settag_discipline_id={(e)=>this.settag_discipline_id(e)}
settitlestting=(name,id)=>{
//如果全部其他的选项重置
this.setState({
titlestting:name,
titlesttingid:id,
titlesttings:null,
titlesttingsid:null,
titlesttingss:null,
titlesttingssid:null
})
if(name==="全部"){
this.props.setdiscipline_id(null);
}else{
this.props.setdiscipline_id(id);
}
}
settitlesttings=(name,id)=>{
//课程选项
this.setState({
titlesttings:name,
titlesttingsid:id,
titlesttingss:null,
})
this.props.setsub_discipline_id(id);
}
settitlesttingss=(name,id)=>{
//知识点
if(this.state.titlesttings===null){
this.props.showNotification('请先选择课程');
return
}
this.setState({
titlesttingss:name,
titlesttingssid:id
})
this.props.settag_discipline_id(id);
}
render() {
let {page,titlestting,titlesttings,titlesttingss}=this.state;
// console.log("Headplugselection");
// console.log(this.props.disciplinesdata);
// disciplinesdatakc:kc,
// disciplinesdatazsd:zsd,
var kc=0;
var zsd=0;
if(this.props.disciplinesdata){
const didata = this.props.disciplinesdata;
for (var i = 0; i < didata.length; i++) {
//方向
const fxdidata = didata[i].sub_disciplines;
if(titlestting===didata[i].name){
for (var j = 0; j < fxdidata.length; j++) {
kc=kc+1;
//课程
const zsddata = fxdidata[j].tag_disciplines;
for (var k = 0; k < zsddata.length; k++) {
//知识点
zsd=zsd+1;
}
}
}else if(titlestting==="全部"){
kc=kc+1;
zsd=zsd+1;
}else{
}
}
}
return (
<div className=" clearfix mt21 ">
<div className="educontent w1200dbl">
<div className="clearfix edu-back-white tophoms">
{/*课程*/}
<div className=" sortinxdirection">
<div className="w60 tophomsembolds">
方向
</div>
<div className="sortinxdirection minleng40">
<div className={titlestting==="全部"?" titlesttingcss xiaoshou":" titlesttingcssmy xiaoshou"} onClick={()=>this.settitlestting("全部",null)}>
全部
</div>
{this.props.disciplinesdata&&this.props.disciplinesdata.map((object, index) => {
return (
<div className={titlestting===object.name?" xiaoshou titlesttingcss":" titlesttingcssmy xiaoshou"} onClick={()=>this.settitlestting(object.name,object.id)}>
{object.name}
</div>
)
})}
</div>
</div>
{/*课程*/}
{
kc===0?
""
:
<div className="mt30 sortinxdirection">
<div className="w60 tophomsembolds">
课程
</div>
<div className="sortinxdirection minleng40">
{this.props.disciplinesdata&&this.props.disciplinesdata.map((objectn, index) => {
return (
titlestting==="全部"?
objectn.sub_disciplines&&objectn.sub_disciplines.map((object, indexs) => {
return (
<div className={index===0&&indexs===0&&titlesttings===object.name?"titlesttingcss xiaoshou":index===0&&indexs===0&&titlesttings!==object.name?"titlesttingcssmy xiaoshou"
:titlesttings===object.name?" titlesttingcss xiaoshou":"titlesttingcssmy xiaoshou"} onClick={()=>this.settitlesttings(object.name,object.id)}>
{object.name}
</div>
)
})
:
objectn.name===titlestting?
objectn.sub_disciplines&&objectn.sub_disciplines.map((object, indexs) => {
return (
<div className={index===0&&indexs===0&&titlesttings===object.name?"titlesttingcss xiaoshou":index===0&&indexs===0&&titlesttings!==object.name?"titlesttingcssmy xiaoshou"
:titlesttings===object.name?" titlesttingcss xiaoshou":"titlesttingcssmy xiaoshou"} onClick={()=>this.settitlesttings(object.name,object.id)}>
{object.name}
</div>
)
})
: ""
)
})}
</div>
</div>
}
{/*知识点*/}
{
zsd===0?
""
:<div className="mt30 sortinxdirection">
<div className="w60 tophomsembolds">
知识点
</div>
<div className="sortinxdirection minleng40">
{this.props.disciplinesdata&&this.props.disciplinesdata.map((objecta, index) => {
return (
titlestting==="全部"&&titlesttings===null?
objecta.sub_disciplines&&objecta.sub_disciplines.map((objectb, indexs) => {
return (
objectb.tag_disciplines&&objectb.tag_disciplines.map((object, indexss) => {
return (
<div className={index===0&&indexs===0&&indexss===0&&titlesttingss===object.name?"titlesttingcss xiaoshou":
index===0&&indexs===0&&indexss===0&&titlesttingss!==object.name?"titlesttingcssmy xiaoshou"
:titlesttingss===object.name?" titlesttingcss xiaoshou":" titlesttingcssmy xiaoshou"} onClick={()=>this.settitlesttingss(object.name)}>
{object.name}
</div>
)
})
)
})
:titlestting==="全部"&&titlesttings!==null?
objecta.sub_disciplines&&objecta.sub_disciplines.map((objectb, indexs) => {
return (
titlesttings===objectb.name?
objectb.tag_disciplines&&objectb.tag_disciplines.map((object, indexss) => {
return (
<div className={index===0&&indexs===0&&indexss===0&&titlesttingss===object.name?"titlesttingcss xiaoshou":
index===0&&indexs===0&&indexss===0&&titlesttingss!==object.name?"titlesttingcssmy xiaoshou"
:titlesttingss===object.name?" titlesttingcss xiaoshou":" titlesttingcssmy xiaoshou"} onClick={()=>this.settitlesttingss(object.name)}>
{object.name}
</div>
)
}):""
)
})
: titlestting!=="全部"&&titlesttings!==null?
titlestting===objecta.name?
objecta.sub_disciplines&&objecta.sub_disciplines.map((objectb, indexs) => {
return (
titlesttings===objectb.name?
objectb.tag_disciplines&&objectb.tag_disciplines.map((object, indexss) => {
return (
<div className={index===0&&indexs===0&&indexss===0&&titlesttingss===object.name?"titlesttingcss xiaoshou":
index===0&&indexs===0&&indexss===0&&titlesttingss!==object.name?"titlesttingcssmy xiaoshou"
:titlesttingss===object.name?" titlesttingcss xiaoshou":" titlesttingcssmy xiaoshou"} onClick={()=>this.settitlesttingss(object.name)}>
{object.name}
</div>
)
}):""
)
})
:""
: titlestting!=="全部"&&titlesttings===null?
titlestting===objecta.name?
objecta.sub_disciplines&&objecta.sub_disciplines.map((objectb, indexs) => {
return (
objectb.tag_disciplines&&objectb.tag_disciplines.map((object, indexss) => {
return (
<div className={index===0&&indexs===0&&indexss===0&&titlesttingss===object.name?"titlesttingcss xiaoshou":
index===0&&indexs===0&&indexss===0&&titlesttingss!==object.name?"titlesttingcssmy xiaoshou"
:titlesttingss===object.name?" titlesttingcss xiaoshou":" titlesttingcssmy xiaoshou"} onClick={()=>this.settitlesttingss(object.name)}>
{object.name}
</div>
)
})
)
})
:""
:""
)
})}
</div>
</div>
}
</div>
</div>
</div>
)
}
}
export default Headplugselection ;

@ -0,0 +1,604 @@
import React, {Component} from "react";
import {Link, NavLink} from 'react-router-dom';
import {WordsBtn, ActionBtn, SnackbarHOC, getImageUrl} from 'educoder';
import axios from 'axios';
import {
notification,
Spin,
Table,
Pagination,
Radio,
Checkbox,
Form,
Input,
Select,
Cascader,
Col, Row, InputNumber, DatePicker, AutoComplete, Button, Tag
} from "antd";
import './../questioncss/questioncom.css';
const InputGroup = Input.Group;
const {Option} = Select;
const options = [
{
value: '方向',
label: '方向',
children: [
{
value: '课程',
label: '课程',
},
],
},
{
value: 'jiangsu',
label: 'Jiangsu',
children: [
{
value: 'nanjing',
label: 'Nanjing',
},
],
},
];
class Itembankstop extends Component {
constructor(props) {
super(props);
this.contentMdRef = React.createRef()
this.state = {
page: 1,
Knowpoints: [],
rbtx: undefined,
rbkc: undefined,
knowledgepoints: [],
options: [],
}
}
//初始化
componentDidMount() {
try {
this.props.getcontentMdRef(this);
} catch (e) {
}
this.setState({
options: this.props.disciplmy
})
// knowledgepoints:this.props.knowledgepoints,
////console.log("componentDidMount");
////console.log(this.state);
////console.log(this.props);
// let homeworkid = this.props.match.params.homeworkid;
// let url = "/homework_commons/" + homeworkid + "/end_groups.json";
// axios.get(url).then((response) => {
// if (response.status === 200) {
// this.setState({})
// }
// }).catch((error) => {
// ////console.log(error)
// });()
// 题型
}
componentDidUpdate(prevProps) {
if (prevProps.item_banksedit !== this.props.item_banksedit) {
if (this.props.item_banksedit.item_type) {
this.handleFormtixing(this.props.item_banksedit.item_type);
}
if (this.props.item_banksedit.difficulty) {
this.handleFormLayoutChange(this.props.item_banksedit.difficulty);
}
if (this.props.item_banksedit.tag_disciplines) {
this.handletag_disciplinesChange(this.props.item_banksedit.tag_disciplines);
}
if (this.props.item_banksedit.discipline &&this.props.item_banksedit.sub_discipline) {
this.handdisciplinesChange(this.props.item_banksedit.discipline,this.props.item_banksedit.sub_discipline);
}
}
if (prevProps.disciplmy !== this.props.disciplmy) {
this.setState({
options: this.props.disciplmy
})
}
}
handdisciplinesChange =(name,title)=>{
this.setState({
rbkc:[name.id,title.id]
})
this.props.form.setFieldsValue({
rbkc: [name.id,title.id],
});
if(this.props.item_banksedit.tag_disciplines.length===0){
const didata = this.props.disciplinesdata;
const knowledgepointsdata = [];
for (var i = 0; i < didata.length; i++) {
//方向
if (name.id === didata[i].id) {
const fxdidata = didata[i].sub_disciplines;
for (var j = 0; j < fxdidata.length; j++) {
//课程
if (title.id === fxdidata[j].id) {
const zsddata = fxdidata[j].tag_disciplines;
for (var k = 0; k < zsddata.length; k++) {
//知识点
knowledgepointsdata.push(zsddata[k]);
}
}
}
}
}
this.setState({
Knowpoints: [],
knowledgepoints: knowledgepointsdata,
})
}
}
handletag_disciplinesChange = (data) => {
try {
var sju=data[data.length-1].name;
this.setState({
rbzsd:sju,
Knowpoints:data,
})
this.props.form.setFieldsValue({
rbzsd: sju,
});
}catch (e) {
}
}
onChange = (e) => {
}
Getdatas = () => {
return this.handleSubmits();
}
handleSubmits = () => {
var data = [];
this.props.form.validateFields((err, values) => {
data = []
if (!err) {
// ////console.log("获取的form 数据");
// ////console.log(values);
data.push({
rbnd: parseInt(values.rbnd)
})
data.push({
rbtx: values.rbtx
})
data.push({
rbzsd: this.state.Knowpoints
})
data.push({
rbkc: values.rbkc
})
}
});
return data;
}
handleSubmit = (e) => {
e.preventDefault();
this.props.form.validateFields((err, values) => {
if (!err) {
////console.log("获取的form 数据");
////console.log(values);
}
});
}
handleFormLayoutChange = (value) => {
//难度塞选
////console.log("难度塞选");
////console.log(value);
this.props.form.setFieldsValue({
rbnd: value + "",
});
this.setState({
rbnd: value + "",
})
}
handleFormkechen = (value) => {
//课程
////console.log("课程");
////console.log(value);
var valuename = undefined;
this.props.form.setFieldsValue({
rbzsd: value,
});
var arr = this.state.knowledgepoints;
for (let data of arr) {
if (data.id === value) {
this.state.Knowpoints.push(data);
valuename = data.name;
}
}
var tmp = JSON.parse(JSON.stringify(this.state.knowledgepoints));
for (var i = 0; i < tmp.length; i++) {
if (tmp[i].id === value) {
this.state.knowledgepoints.splice(i, 1);
}
}
this.setState({
rbzsd: valuename,
Knowpoints: this.state.Knowpoints,
knowledgepoints: this.state.knowledgepoints,
})
}
handleFormzhishidian = (value) => {
console.log("handleFormzhishidian 课程");
console.log(value);
//课程
this.props.form.setFieldsValue({
rbkc: value,
});
this.setState({
rbkc:value,
})
// console.log("handleFormzhishidian");
// console.log(this.props.disciplinesdata);
const didata = this.props.disciplinesdata;
const knowledgepointsdata = [];
for (var i = 0; i < didata.length; i++) {
//方向
if (value[0] === didata[i].id) {
const fxdidata = didata[i].sub_disciplines;
for (var j = 0; j < fxdidata.length; j++) {
//课程
if (value[1] === fxdidata[j].id) {
const zsddata = fxdidata[j].tag_disciplines;
for (var k = 0; k < zsddata.length; k++) {
//知识点
knowledgepointsdata.push(zsddata[k]);
}
}
}
}
}
this.setState({
Knowpoints: [],
knowledgepoints: knowledgepointsdata,
})
this.props.form.setFieldsValue({
rbzsd: undefined,
});
this.setState({
rbzsd: undefined,
})
}
handleFormtixing = (value) => {
//题型
//console.log("题型");
//console.log(value);
this.setState({
rbtx: value + "",
})
this.props.form.setFieldsValue({
rbtx: value + "",
});
this.props.setitem_type(value);
}
preventDefault = (e) => {
e.preventDefault();
////console.log('Clicked! But prevent default.');
}
deletesobject = (item, index) => {
var arr = this.state.Knowpoints;
for (let data of arr) {
if (data.id === item.id) {
this.state.knowledgepoints.push(data);
}
}
var tmp = JSON.parse(JSON.stringify(this.state.Knowpoints));
for (var i = 0; i < tmp.length; i++) {
if (i >= index) {
var pos = this.state.Knowpoints.indexOf(tmp[i]);
this.state.Knowpoints.splice(pos, 1);
}
}
this.props.form.setFieldsValue({
rbzsd: this.state.Knowpoints,
});
this.setState({
Knowpoints: this.state.Knowpoints,
})
if (this.state.Knowpoints.length === 0) {
this.setState({
rbzsd: undefined,
})
} else if (this.state.Knowpoints.length > 0) {
try {
const myknowda = this.state.Knowpoints;
this.setState({
rbzsd: myknowda[this.state.Knowpoints.length - 1].name,
})
} catch (e) {
}
}
}
render() {
let {page, options} = this.state;
const {getFieldDecorator} = this.props.form;
//console.log("renderrenderrender");
//console.log(this.props.item_banksedit);
//console.log("renderrenderrendersssss");
//console.log(this.state.rbtx);
return (
<div className=" clearfix educontent Contentquestionbankstyle w100s w1200fpx mt19">
<style>
{
`
.ant-form-item{
margin-bottom: 0px !important;
}
.ant-form-explain{
padding-left:0px !important;
margin-top: 3px !important;
}
.ant-select-selection{
height: 33px !important;
}
.ant-input-group{
width:258px !important;
}
.ant-input {
height: 33px !important;
}
.ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled):focus-within {
outline: 0px solid rgba(24, 144, 255, 0.06) !important;
}
`
}
</style>
<div className="h12"></div>
<Form.Item
label="课程"
>
{getFieldDecorator("rbkc",
{
rules: [{required: true, message: '请选择课程'}],
}
)(
<div className="sortinxdirection">
<InputGroup compact>
<Cascader style={{width: '258px'}} value={this.state.rbkc} options={options} onChange={this.handleFormzhishidian}
placeholder="请选择..."/>
</InputGroup>
{/*<div className="sortinxdirection" style={{*/}
{/* height: "33px",*/}
{/* lineHeight: "28px",*/}
{/*}}>*/}
{/* {this.state.Knowpoints === undefined ? "" : this.state.Knowpoints.map((object, index) => {*/}
{/* return (*/}
{/* <div className="mytags" style={{*/}
{/* position: "relative",*/}
{/* }}>*/}
{/* <p className="w100s stestcen lh32">{object}</p>*/}
{/* <i className="iconfont icon-roundclose font-25 lg ml7 icondowncolorss" onClick={()=>this.deletesobject(object,index)}></i>*/}
{/* </div>*/}
{/* )*/}
{/* })}*/}
{/*</div>*/}
</div>
)}
</Form.Item>
<Form onSubmit={this.handleSubmit}>
<Form.Item
label="知识点"
>
{getFieldDecorator("rbzsd"
)(
<div className="sortinxdirection">
<InputGroup compact>
<Select style={{width: '258px'}} value={this.state.rbzsd} onChange={this.handleFormkechen}
placeholder="请选择...">
{this.state.knowledgepoints && this.state.knowledgepoints.map((object, index) => {
return (
<Option value={object.id}>{object.name}</Option>
)
})}
</Select>
</InputGroup>
<div className="sortinxdirection" style={{
height: "33px",
lineHeight: "28px",
}}>
{this.state.Knowpoints === undefined ? "" : this.state.Knowpoints.map((object, index) => {
return (
<div className="mytags" style={{
position: "relative",
}}>
<p className="w100s stestcen lh32">{object.name}</p>
<i className="iconfont icon-roundclose font-25 lg ml7 icondowncolorss"
onClick={() => this.deletesobject(object, index)}></i>
</div>
)
})}
</div>
</div>
)}
</Form.Item>
<Form.Item
label="题型"
>
{getFieldDecorator("rbtx",
{
rules: [{required: true, message: '请选择题型'}],
}
)(
<InputGroup compact>
<Select style={{width: '258px'}} value={this.state.rbtx} onChange={this.handleFormtixing}
placeholder="请选择...">
<Option value="SINGLE">单选题</Option>
<Option value="MULTIPLE">多选题</Option>
<Option value="JUDGMENT">判断题</Option>
<Option value="PROGRAM">编程题</Option>
</Select>
</InputGroup>
)}
</Form.Item>
<style>
{
`
.rbndclass .ant-radio-button-wrapper{
width:106px !important;
height:33px !important;
background:#EEEEEE;
border-radius:17px !important;
color:#333333;
text-align: center !important;
border:0px !important;
margin-right: 27px !important;
margin-top: 6px !important;
}
.rbndclass .ant-radio-button-wrapper-checked {
width: 106px !important;
height: 33px !important;
background: #4CACFF !important;
border-radius: 17px !important;
text-align: center !important;
border:0px !important;
color: #ffffff !important;
margin-right: 27px !important;
margin-top: 6px!important;
}
.rbndclass .ant-radio-button-wrapper:not(:first-child)::before{
border:0px !important;
width:0px !important;
}
.rbndclass .ant-radio-button-wrapper{
border:0px !important;
}
.rbndclass .ant-radio-group{
border:0px !important;
}
.rbndclass .ant-radio-group label{
border:0px !important;
}
.rbndclass .ant-radio-group span{
border:0px !important;
}
ant-radio-button-wrapper:focus-within {
outline: 0px solid #ffffff;
}
`
}
</style>
<div className="rbndclass">
<Form.Item label="难度">
{getFieldDecorator('rbnd',
{
rules: [{required: true, message: '请选择难度'}],
}
)(
<Radio.Group value={this.state.rbnd} onChange={this.handleFormLayoutChange}>
<Radio.Button value="1">简单</Radio.Button>
<Radio.Button value="2">适中</Radio.Button>
<Radio.Button value="3">困难</Radio.Button>
</Radio.Group>,
)}
</Form.Item>
</div>
{/*<Form.Item>*/}
{/* <Button type="primary" htmlType="submit" className="login-form-button">*/}
{/* 提交*/}
{/* </Button>*/}
{/*</Form.Item>*/}
</Form>
<div className="h20"></div>
</div>
)
}
}
const Itembankstops = Form.create({name: 'Itembankstops'})(Itembankstop);
export default Itembankstops;

@ -0,0 +1,402 @@
import React,{ Component } from "react";
import {
Form, Input, InputNumber, Switch, Radio,
Slider, Button, Upload, Icon, Rate, Checkbox, message,
Row, Col, Select, Modal, Tooltip
} from 'antd';
import TPMMDEditor from '../../../modules/tpm/challengesnew/TPMMDEditor';
import axios from 'axios'
import update from 'immutability-helper'
import './../questioncss/questioncom.css';
import {getUrl, ActionBtn, DMDEditor, ConditionToolTip} from 'educoder';
const { TextArea } = Input;
const confirm = Modal.confirm;
const $ = window.$
const { Option } = Select;
const tagArray = [
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
]
//题库的试卷 判断题 组件
class JudquestionEditor extends Component{
constructor(props){
super(props);
/**
choice_id: 32076
choice_position: 1
choice_text: "1"
standard_boolean: true
*/
const {question_choices} = this.props;
let _standard_answers = undefined;
let _question_choices = undefined;
if (question_choices) {
_standard_answers = []
_question_choices = []
question_choices.forEach((item, index) => {
_standard_answers.push(item.standard_boolean)
_question_choices.push(item.choice_text)
})
}
this.state = {
question_choices: _question_choices || ['', '', '', ''],
standard_answers: _standard_answers || [false, false, false, false],
question_title: this.props.question_title || '',
question_type: this.props.question_type || 0,
question_score: this.props.question_score || this.props.init_question_score,
question_titles:this.props.question_titles||'',
zqda:null,
item_banksedit:[],
mychoicess:[],
}
}
addOption = () => {
const { question_choices, standard_answers } = this.state;
// //////console.log("addOption");
// //////console.log(question_choices);
// //////console.log(standard_answers);
question_choices.push('')
standard_answers.push(false)
this.setState({ question_choices, standard_answers })
}
deleteOption = (index) => {
let {question_choices}=this.state;
// //////console.log("deleteOption");
// //////console.log(question_choices);
if(question_choices[index]===""){
// repeat code
this.toMDMode(null)
this.setState(
(prevState) => ({
question_choices : update(prevState.question_choices, {$splice: [[index, 1]]}),
standard_answers : update(prevState.standard_answers, {$splice: [[index, 1]]})
})
)
}else{
this.props.confirm({
content: `确认要删除这个选项吗?`,
onOk: () => {
this.toMDMode(null)
this.setState(
(prevState) => ({
question_choices : update(prevState.question_choices, {$splice: [[index, 1]]}),
standard_answers : update(prevState.standard_answers, {$splice: [[index, 1]]})
})
)
}
})
}
}
onSave = () => {
var editordata=[];
const {question_title, question_score, question_type,question_titles, zqda,question_choices, standard_answers } = this.state;
const { question_id_to_insert_after, question_id } = this.props
// TODO check
const answerArray = standard_answers.map((item, index) => { return item == true ? index+1 : -1 }).filter(item => item != -1);
if(!question_title) {
this.refs['titleEditor'].showError()
this.props.showNotification('请您输入题干');
return editordata;
}
if(zqda===null) {
this.props.showNotification('请先点击选择本选择题的正确选项');
return editordata;
}
if(!question_titles) {
this.refs['titleEditor2'].showError()
this.props.showNotification('请您输入题目解析');
return editordata;
}
/**
{
"question_title":"同学朋友间常用的沟通工具是什么?",
"question_type":1,
"question_score":5,
"question_choices":["a答案","b答案","c答案","d答案"],
"standard_answers":[1]
}*/
editordata=[question_title,zqda,question_titles];
// question_title,
// question_type: answerArray.length > 1 ? 1 : 0,
// question_score,
// question_choices,
// standard_answers: answerArray,
// insert_id: question_id_to_insert_after || undefined
return editordata;
}
onCancel = () => {
this.props.onEditorCancel()
}
componentDidMount = () => {
try {
this.props.getanswerMdRef(this);
}catch (e) {
}
try {
this.setState({
item_banksedit:this.props.item_banksedit,
question_title:this.props.item_banksedit.name,
question_titles:this.props.item_banksedit.analysis,
mychoicess:this.props.item_banksedit.choices,
})
if(this.props.item_banksedit){
if(this.props.item_banksedit.choices){
for(var ik=0;ik<this.props.item_banksedit.choices.length;ik++ ){
if( this.props.item_banksedit.choices[ik].choice_text==="正确"){
if( this.props.item_banksedit.choices[ik].is_answer===true){
this.setState({
zqda:"0"
})
}
}else{
if( this.props.item_banksedit.choices[ik].is_answer===true){
this.setState({
zqda:"1"
})
}
}
}
}
}
}catch (e) {
}
}
componentDidUpdate(prevProps) {
//console.log("componentDidUpdate");
//console.log(prevProps);
//console.log(this.props.item_banksedit);
if(prevProps.item_banksedit !== this.props.item_banksedit){
this.setState({
item_banksedit:this.props.item_banksedit,
question_title:this.props.item_banksedit.name,
question_titles:this.props.item_banksedit.analysis,
mychoicess:this.props.item_banksedit.choices,
})
if(this.props.item_banksedit){
if(this.props.item_banksedit.choices){
for(var ik=0;ik<this.props.item_banksedit.choices.length;ik++ ){
if( this.props.item_banksedit.choices[ik].choice_text==="正确"){
if( this.props.item_banksedit.choices[ik].is_answer===true){
this.setState({
zqda:"0"
})
}
}else{
if( this.props.item_banksedit.choices[ik].is_answer===true){
this.setState({
zqda:"1"
})
}
}
}
}
}
}
}
onOptionClick = (index) => {
let standard_answers = this.state.standard_answers.slice(0);
// //////console.log("onOptionClick");
// //////console.log(standard_answers);
// //////console.log(standard_answers[index]);
// //////console.log(!standard_answers[index]);
for (var i=0;i<standard_answers.length;i++){
if(index===i){
standard_answers[index] = true;
}else{
standard_answers[i] = false;
}
}
// standard_answers[index] = !standard_answers[index];
this.setState({ standard_answers })
}
onOptionContentChange = (value, index) => {
if (index >= this.state.question_choices.length) {
// TODO 新建然后删除CD选项再输入题干会调用到这里且index是3
return;
}
let question_choices = this.state.question_choices.slice(0);
question_choices[index] = value;
this.setState({ question_choices })
}
on_question_score_change = (e) => {
this.setState({ question_score: e })
}
toMDMode = (that) => {
if (this.mdReactObject) {
let mdReactObject = this.mdReactObject;
this.mdReactObject = null
mdReactObject.toShowMode()
}
this.mdReactObject = that;
}
toShowMode = () => {
}
handleFormLayoutChange=(e)=>{
//////console.log("难度塞选");
//////console.log(value);
this.setState({
zqda:e.target.value,
})
}
render() {
let { question_title, question_score, question_type, question_choices, standard_answers,question_titles} = this.state;
let { question_id, index, exerciseIsPublish,
// question_title,
// question_type,
// question_score,
isNew } = this.props;
// const { getFieldDecorator } = this.props.form;
// const isAdmin = this.props.isAdmin()
// const courseId=this.props.match.params.coursesId;
// const isEdit = !!this.props.question_id
const qNumber = `question_`;
// TODO show模式 isNew为false isEdit为false
// [true, false, true] -> [0, 2]
const answerTagArray = standard_answers.map((item, index) => { return item == true ? tagArray[index] : -1 }).filter(item => item != -1);
// //////console.log("xuanzheshijuan");
// //////console.log(answerTagArray);
// //////console.log(!exerciseIsPublish);
const params= this.props&&this.props.match&&this.props.match.params;
return(
<div className="padding20-30 signleEditor danxuano" id={qNumber}>
<style>{`
.optionMdEditor {
flex:1
}
.optionRow {
margin:0px!important;
/* margin-bottom: 20px!important; */
}
.signleEditor .content_editorMd_show{
display: flex;
margin-top:0px!important;
border-radius:2px;
max-width: 1056px;
word-break:break-all;
}
#e_tips_mdEditor_question_undefined4{
display: none;
}
`}</style>
<p className="mb10 clearfix">
{/* {!question_id ? '新建' : '编辑'} */}
<span className="xingcolor font-16 fl mr4">*</span>
<span className="xingtigan fl">题干</span>
</p>
<TPMMDEditor mdID={qNumber} placeholder="请您输入题干" height={155} className=" mt10"
initValue={question_title} onChange={(val) => this.setState({ question_title: val})}
ref="titleEditor"
></TPMMDEditor>
<div className="mb10 sortinxdirection">
{/* {!question_id ? '新建' : '编辑'} */}
<span className="xingcolor font-16 fl mr4">*</span>
<span className="xingtigans fl"><span className="xingtigan">答案选项</span></span>
</div>
<style>
{
`
.choice_textcsss {
border-radius:2px !important;
}
.choice_textcss {
margin-left: 40px !important;
border-radius:2px !important;
}
`
}
</style>
<div className="mb15 sortinxdirection ">
<Radio.Group buttonStyle="solid" value={this.state.zqda} onChange={this.handleFormLayoutChange}>
<Radio.Button value="0" className={"choice_textcsss"}>正确</Radio.Button>
<Radio.Button value="1" className={"choice_textcss"}>错误</Radio.Button>
</Radio.Group>
</div>
<div>
<p className="mb10 clearfix">
{/* {!question_id ? '新建' : '编辑'} */}
<span className="xingcolor font-16 fl mr4">*</span>
<span className="xingtigan fl">题目解析</span>
</p>
<style>{`
.optionMdEditor {
flex:1
}
.optionRow {
margin:0px!important;
/* margin-bottom: 20px!important; */
}
.signleEditor .content_editorMd_show{
display: flex;
margin-top:0px!important;
border-radius:2px;
max-width: 1056px;
word-break:break-all;
}
`}</style>
<TPMMDEditor mdID={qNumber+question_choices.length} placeholder="请您输入题目解析" height={155} className=" mt10"
initValue={question_titles} onChange={(val) => this.setState({ question_titles: val})}
ref="titleEditor2"
></TPMMDEditor>
</div>
</div>
)
}
}
// RouteHOC()
export default (JudquestionEditor);

@ -0,0 +1,179 @@
import React, {Component} from "react";
import {Link, NavLink} from 'react-router-dom';
import {WordsBtn, ActionBtn,SnackbarHOC,getImageUrl,markdownToHTML} from 'educoder';
import axios from 'axios';
import {
notification,
Spin,
Table,
Pagination,
Radio
} from "antd";
import './../questioncss/questioncom.css';
const tagArray = [
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
]
class Listjihe extends Component {
constructor(props) {
super(props);
this.state = {
page:1,
name:"单选题",
nd:"简单",
chakanjiexibool:false,
}
}
//初始化
componentDidMount(){
}
chakanjiexibool=()=>{
if(this.state.chakanjiexibool===true){
this.setState({
chakanjiexibool:false
})
}else{
this.setState({
chakanjiexibool:true
})
}
}
//选用
Selectingpracticaltraining=(id)=>{
let data={
item_ids:[id]
}
this.props.getitem_baskets(data);
}
//撤销
Selectingpracticaltrainings=(id)=>{
this.props.getitem_basketss(id);
}
render() {
let {page,name,nd,chakanjiexibool}=this.state;
let {defaultActiveKey,items}=this.props;
////console.log("Listjihe");
////console.log(this.props);
return (
<div className={chakanjiexibool===true?"w100s borderwds283 pd20 mb20":"w100s borderwds pd20 mb20"}>
{/*顶部*/}
<div className="w100s sortinxdirection">
<div className="w70s listjihetixingstit markdown-body" style={{wordBreak: "break-word"}} dangerouslySetInnerHTML={{__html: markdownToHTML(items&&items.name).replace(/▁/g, "▁▁▁")}}>
</div>
<div className="w30s xaxisreverseorder">
<p className="listjihetixing">难度<span className="listjihetixings">{items.difficulty===1?"简单":items.difficulty===2?"适中":items.difficulty===3?"困难":""}</span></p>
<p className="mr30 listjihetixing">题型<span className="listjihetixings">{items.item_type==="SINGLE"?"单选题":items.item_type==="MULTIPLE"?"多选题":items.item_type==="JUDGMENT"?"判断题":items.item_type==="PROGRAM"?"编程题":""}</span></p>
</div>
</div>
{/*内容*/}
<div className="w100s sortinxdirection">
<p className="w100s listjihetixingstits sortinxdirection ">
{
items.item_type==="JUDGMENT"?
items === undefined ||items === null? "" : items.choices.map((object, index) => {
return (
<p className={index===1? "sortinxdirection ml10":"sortinxdirection " } >
<Radio checked={object.is_answer}>
{object.choice_text}
</Radio>
</p>
)
})
:
items === undefined ||items === null? "" : items.choices.map((object, index) => {
return (
<p className="sortinxdirection ml10" >
{tagArray[index]}
<p style={{wordBreak: "break-word"}} dangerouslySetInnerHTML={{__html: markdownToHTML(object.choice_text).replace(/▁/g, "▁▁▁")}}></p>
</p>
)
})
}
</p>
</div>
{/*更新时间*/}
<div className="w100s sortinxdirection mt22">
<div className="w50s listjihetixingstit sortinxdirection">
<p className="updatetimes lh30">更新时间{items.update_time}</p>
{
this.props.defaultActiveKey==="0"||this.props.defaultActiveKey===0?
""
:
<p className="updatetimes lh30 ml45">创建者{items.author.name}</p>
}
</div>
<div className="w50s xaxisreverseorder">
{
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>
:
<p className="selection xiaoshou" onClick={()=>this.Selectingpracticaltraining(items.id)}>
<i className="iconfont icon-tianjiadaohang font-12 lg ml7 lh30 icontianjiadaohangcolor mr10"></i>
<span>选用</span></p>
}
{
defaultActiveKey===0||defaultActiveKey==="0"?
<div className="xaxisreverseorder">
<p className="viewparsings xiaoshou mr25" onClick={()=>this.props.showmodelysl(items.id)}>
<i className="iconfont icon-shanchu1 font-17 lg ml7 lh30 icontianjiadaohangcolors mr5"></i>
<span>删除</span>
</p>
<a href={`/question/edit/${items.id}`}>
<p className="viewparsings xiaoshou mr25" >
<i className="iconfont icon-bianji2 font-17 lg ml7 lh30 icontianjiadaohangcolors mr5"></i>
<span>编辑</span>
</p>
</a>
<p className="viewparsings xiaoshou mr25" onClick={()=>this.props.showmodels(items.id)}>
<i className="iconfont icon-gongkai font-17 lg ml7 lh30 icontianjiadaohangcolors mr5"></i>
<span>公开</span>
</p>
</div>
:""
}
<p className="viewparsings xiaoshou mr25" onClick={()=>this.chakanjiexibool()}>
<i className="iconfont icon-jiexi font-17 lg ml7 lh30 icontianjiadaohangcolors mr5"></i>
查看解析</p>
</div>
</div>
{
chakanjiexibool===true?<div>
<div className="w100s questiontypeheng mt23">
</div>
<p className="analysis mt22">解析</p>
<p className="mt15 testfondex"
style={{wordBreak: "break-word"}} dangerouslySetInnerHTML={{__html: markdownToHTML(items.analysis).replace(/▁/g, "▁▁▁")}}
>
</p>
</div>:""
}
</div>
)
}
}
export default Listjihe;

@ -0,0 +1,37 @@
import React, { Component } from 'react';
import { getImageUrl , getUrl } from 'educoder';
class NoneData extends Component{
constructor(props) {
super(props)
}
render(){
const { style } = this.props;
return(
<div className="edu-tab-con-box clearfix edu-txt-center intermediatecenter" style={ style || { width:"100%",height:"100%"}}>
<style>
{`
.edu-tab-con-box{
padding:100px 0px;
}
.ant-modal-body .edu-tab-con-box{
padding:0px!important;
}
img.edu-nodata-img{
margin: 40px auto 20px;
}
.zenwuxgsj{
font-size:17px;
font-family:MicrosoftYaHei;
color:rgba(136,136,136,1);
}
`}
</style>
<img className="edu-nodata-img mb20" src={getUrl("/images/educoder/nodata.png")}/>
<p className="edu-nodata-p mb10 zenwuxgsj">暂无相关数据</p>
<p className="edu-nodata-p mb20 mt4 zenwuxgsj">请选择试题进行组卷</p>
</div>
)
}
}
export default NoneData;

@ -0,0 +1,36 @@
import React, { Component } from 'react';
import { getImageUrl , getUrl } from 'educoder';
class NoneDatas extends Component{
constructor(props) {
super(props)
}
render(){
const { style } = this.props;
return(
<div className="edu-tab-con-box clearfix edu-txt-center intermediatecenter" style={ style || { width:"100%",height:"100%"}}>
<style>
{`
.edu-tab-con-box{
padding:100px 0px;
}
.ant-modal-body .edu-tab-con-box{
padding:0px!important;
}
img.edu-nodata-img{
margin: 40px auto 20px;
}
.zenwuxgsj{
font-size:17px;
font-family:MicrosoftYaHei;
color:rgba(136,136,136,1);
}
`}
</style>
<img className="edu-nodata-img mb20" src={getUrl("/images/educoder/nodata.png")}/>
<p className="edu-nodata-p mb10 zenwuxgsj">暂无相关数据</p>
</div>
)
}
}
export default NoneDatas;

@ -0,0 +1,43 @@
import React, { Component } from 'react';
import {getImageUrl} from 'educoder';
import { Modal} from 'antd';
import axios from 'axios';
import './../questioncss/questioncom.css'
//立即申请试用
class QuestionModal extends Component {
constructor(props) {
super(props);
this.state={
}
}
render() {
return(
<Modal
keyboard={false}
closable={false}
footer={null}
destroyOnClose={true}
title="提示"
centered={true}
visible={this.props.modalsType===undefined?false:this.props.modalsType}
width="442px"
>
<div className="educouddiv">
<div className={"tabeltext-alignleft mt10"}><p className="titiles">{this.props.titilesm}</p></div>
<div className={"tabeltext-alignleft mt10"}><p className="titiles">{this.props.titiless}</p></div>
<div className="clearfix mt30 edu-txt-center">
<a className="task-btn mr30 w80" onClick={()=>this.props.modalCancel()}>取消</a>
<a className="task-btn task-btn-orange w80" onClick={()=>this.props.setDownload()}>确定</a>
</div>
</div>
</Modal>
)
}
}
export default QuestionModal;

@ -0,0 +1,66 @@
import React, { Component } from 'react';
import {getImageUrl} from 'educoder';
import { Modal} from 'antd';
import axios from 'axios';
import './../questioncss/questioncom.css'
//立即申请试用
class QuestionModals extends Component {
constructor(props) {
super(props);
this.state={
}
}
render() {
return(
<Modal
keyboard={false}
closable={false}
footer={null}
destroyOnClose={true}
title="提示"
centered={true}
visible={this.props.modalsTypes===undefined?false:this.props.modalsTypes}
width="442px"
>
<div className="educouddiv">
<div className={"tabeltext-alignleft mt10"}><p className="titiles">是否删除试题栏中{
this.props.titilesms&&this.props.titilesms==="SINGLE"?
"单选题"
:
this.props.titilesms&&this.props.titilesms==="MULTIPLE"?
"多选题"
:
this.props.titilesms&&this.props.titilesms==="JUDGMENT"?
"判断题"
:
this.props.titilesms&&this.props.titilesms==="COMPLETION"?
"填空题"
:
this.props.titilesms&&this.props.titilesms==="SUBJECTIVE"?
"简答题"
:
this.props.titilesms&&this.props.titilesms==="PROGRAM"?
"编程题"
:
this.props.titilesms&&this.props.titilesms==="PRACTICAL"?
"实训题"
:""
}</p></div>
<div className="clearfix mt30 edu-txt-center">
<a className="task-btn mr30 w80" onClick={()=>this.props.modalCancels()}>取消</a>
<a className="task-btn task-btn-orange w80" onClick={()=>this.props.setDownloads(this.props.titilesms)}>确定</a>
</div>
</div>
</Modal>
)
}
}
export default QuestionModals;

@ -0,0 +1,395 @@
import React,{ Component } from "react";
import {
Form, Input, InputNumber, Switch, Radio,
Slider, Button, Upload, Icon, Rate, Checkbox, message,
Row, Col, Select, Modal, Tooltip
} from 'antd';
import TPMMDEditor from '../../../modules/tpm/challengesnew/TPMMDEditor';
import axios from 'axios'
import update from 'immutability-helper'
import './../questioncss/questioncom.css';
import {getUrl, ActionBtn, DMDEditor, ConditionToolTip} from 'educoder';
const { TextArea } = Input;
const confirm = Modal.confirm;
const $ = window.$
const { Option } = Select;
const tagArray = [
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
]
//题库的试卷 单选题 组件
class SingleEditor extends Component{
constructor(props){
super(props);
/**
choice_id: 32076
choice_position: 1
choice_text: "1"
standard_boolean: true
*/
const {question_choices} = this.props;
let _standard_answers = undefined;
let _question_choices = undefined;
if (question_choices) {
_standard_answers = []
_question_choices = []
question_choices.forEach((item, index) => {
_standard_answers.push(item.standard_boolean)
_question_choices.push(item.choice_text)
})
}
const choicescomy=[];
try {
if(this.props.item_banksedit){
if(this.props.item_banksedit.choices){
this.props.item_banksedit.choices.forEach((item, index) => {
//console.log("SingleEditor");
//console.log(item);
choicescomy.push({
choice_text:item.choice_text,
standard_boolean:item.is_answer,
})
})
_standard_answers = []
_question_choices = []
choicescomy.forEach((item, index) => {
_standard_answers.push(item.standard_boolean)
_question_choices.push(item.choice_text)
})
}
}
}catch (e) {
}
this.state = {
question_choices: _question_choices || ['', '', '', ''],
standard_answers: _standard_answers || [false, false, false, false],
question_title: this.props.question_title || '',
question_type: this.props.question_type || 0,
question_score: this.props.question_score || this.props.init_question_score,
question_titles:this.props.question_titles||'',
item_banksedit:[],
}
}
addOption = () => {
const { question_choices, standard_answers } = this.state;
// ////console.log("addOption");
// ////console.log(question_choices);
// ////console.log(standard_answers);
question_choices.push('')
standard_answers.push(false)
this.setState({ question_choices, standard_answers })
}
deleteOption = (index) => {
let {question_choices}=this.state;
// ////console.log("deleteOption");
// ////console.log(question_choices);
if(question_choices[index]===""){
// repeat code
this.toMDMode(null)
this.setState(
(prevState) => ({
question_choices : update(prevState.question_choices, {$splice: [[index, 1]]}),
standard_answers : update(prevState.standard_answers, {$splice: [[index, 1]]})
})
)
}else{
this.toMDMode(null)
this.setState(
(prevState) => ({
question_choices : update(prevState.question_choices, {$splice: [[index, 1]]}),
standard_answers : update(prevState.standard_answers, {$splice: [[index, 1]]})
})
)
}
}
onSave = () => {
var editordata=[];
const {question_title, question_score, question_type,question_titles, question_choices, standard_answers } = this.state;
const { question_id_to_insert_after, question_id } = this.props
// TODO check
const answerArray = standard_answers.map((item, index) => { return item == true ? index+1 : -1 }).filter(item => item != -1);
if(!question_title) {
this.refs['titleEditor'].showError()
this.props.showNotification('请您输入题干');
return editordata;
}
if(!answerArray || answerArray.length == 0) {
this.props.showNotification('请先点击选择本选择题的正确选项');
return editordata;
}
for(let i = 0; i < question_choices.length; i++) {
if (!question_choices[i]) {
this.refs[`optionEditor${i}`].showError()
this.props.showNotification(`请先输入 ${tagArray[i]} 选项的内容`);
return editordata;
}
}
if(!question_titles) {
this.refs['titleEditor2'].showError()
this.props.showNotification('请您输入题目解析');
return editordata;
}
/**
{
"question_title":"同学朋友间常用的沟通工具是什么?",
"question_type":1,
"question_score":5,
"question_choices":["a答案","b答案","c答案","d答案"],
"standard_answers":[1]
}*/
editordata=[question_title,answerArray,question_choices,question_titles];
// question_title,
// question_type: answerArray.length > 1 ? 1 : 0,
// question_score,
// question_choices,
// standard_answers: answerArray,
// insert_id: question_id_to_insert_after || undefined
return editordata;
}
onCancel = () => {
this.props.onEditorCancel()
}
componentDidMount = () => {
try {
this.props.getanswerMdRef(this);
}catch (e) {
}
try {
this.setState({
item_banksedit:this.props.item_banksedit,
question_title:this.props.item_banksedit.name,
question_titles:this.props.item_banksedit.analysis,
mychoicess:this.props.item_banksedit.choices,
})
}catch (e) {
}
}
componentDidUpdate(prevProps) {
//console.log("componentDidUpdate");
// //console.log(prevProps);
// //console.log(this.props.item_banksedit);
if(prevProps.item_banksedit !== this.props.item_banksedit) {
this.setState({
item_banksedit: this.props.item_banksedit,
question_title: this.props.item_banksedit.name,
question_titles: this.props.item_banksedit.analysis,
mychoicess: this.props.item_banksedit.choices,
})
}
}
onOptionClick = (index) => {
let standard_answers = this.state.standard_answers.slice(0);
// ////console.log("onOptionClick");
// ////console.log(standard_answers);
// ////console.log(standard_answers[index]);
// ////console.log(!standard_answers[index]);
for (var i=0;i<standard_answers.length;i++){
if(index===i){
standard_answers[index] = true;
}else{
standard_answers[i] = false;
}
}
// standard_answers[index] = !standard_answers[index];
this.setState({ standard_answers })
}
onOptionContentChange = (value, index) => {
if (index >= this.state.question_choices.length) {
// TODO 新建然后删除CD选项再输入题干会调用到这里且index是3
return;
}
let question_choices = this.state.question_choices.slice(0);
question_choices[index] = value;
this.setState({ question_choices })
}
on_question_score_change = (e) => {
this.setState({ question_score: e })
}
toMDMode = (that) => {
if (this.mdReactObject) {
let mdReactObject = this.mdReactObject;
this.mdReactObject = null
mdReactObject.toShowMode()
}
this.mdReactObject = that;
}
toShowMode = () => {
}
render() {
let { question_title, question_score, question_type, question_choices, standard_answers,question_titles} = this.state;
let { question_id, index, exerciseIsPublish,
// question_title,
// question_type,
// question_score,
isNew } = this.props;
// const { getFieldDecorator } = this.props.form;
// const isAdmin = this.props.isAdmin()
// const courseId=this.props.match.params.coursesId;
// const isEdit = !!this.props.question_id
const qNumber = `question_`;
// TODO show模式 isNew为false isEdit为false
// [true, false, true] -> [0, 2]
const answerTagArray = standard_answers.map((item, index) => { return item == true ? tagArray[index] : -1 }).filter(item => item != -1);
// ////console.log("xuanzheshijuan");
// ////console.log(answerTagArray);
// ////console.log(!exerciseIsPublish);
return(
<div className="padding20-30 signleEditor danxuano" id={qNumber}>
<style>{`
.optionMdEditor {
flex:1
}
.optionRow {
margin:0px!important;
/* margin-bottom: 20px!important; */
}
.signleEditor .content_editorMd_show{
display: flex;
margin-top:0px!important;
border-radius:2px;
max-width: 1056px;
word-break:break-all;
}
#e_tips_mdEditor_question_undefined4{
display: none;
}
`}</style>
<p className="mb10 clearfix">
{/* {!question_id ? '新建' : '编辑'} */}
<span className="xingcolor font-16 fl mr4">*</span>
<span className="xingtigan fl">题干</span>
</p>
<TPMMDEditor mdID={qNumber} placeholder="请您输入题干" height={155} className=" mt10"
initValue={question_title} onChange={(val) => this.setState({ question_title: val})}
ref="titleEditor"
></TPMMDEditor>
<div className="mb10 sortinxdirection">
{/* {!question_id ? '新建' : '编辑'} */}
<span className="xingcolor font-16 fl mr4">*</span>
<span className="xingtigans fl"><span className="xingtigan">答案选项</span></span>
</div>
{question_choices.map( (item, index) => {
const bg = standard_answers[index] ? 'check-option-bg' : ''
return <div className="df optionRow " >
{/* 点击设置答案 */}
{/* TODO 加了tooltip后会丢失掉span的class */}
{/* <Tooltip title={standard_answers[index] ? '点击取消标准答案设置' : '点击设置为标准答案'}> */}
<span class={`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>
</ConditionToolTip>
</span>
{/* </Tooltip> */}
<div style={{ flex: '0 0 1038px'}}>
<DMDEditor
ref={`optionEditor${index}`}
toMDMode={this.toMDMode} toShowMode={this.toShowMode}
height={166} className={'optionMdEditor'} noStorage={true}
mdID={qNumber + index} placeholder="" onChange={(value) => this.onOptionContentChange(value, index)}
initValue={item}
></DMDEditor>
</div>
{exerciseIsPublish || index<=1?
<i className=" font-18 ml15 mr20"></i>
:<Tooltip title="删除">
<i className="iconfont icon-htmal5icon19 font-18 color-grey-c ml15" onClick={() => this.deleteOption(index)}></i>
</Tooltip> }
{ !exerciseIsPublish && index<7 && <Tooltip title={`新增参考答案`}>
<i className="color-green font-16 iconfont icon-roundaddfill ml6"
onClick={() => this.addOption()}
style={{float: 'right', visibility: index == question_choices.length - 1 ? '' : 'hidden', marginTop: '2px'}}
></i>
</Tooltip>}
</div>
}) }
<div>
<p className="mb10 clearfix">
{/* {!question_id ? '新建' : '编辑'} */}
<span className="xingcolor font-16 fl mr4">*</span>
<span className="xingtigan fl">题目解析</span>
</p>
<style>{`
.optionMdEditor {
flex:1
}
.optionRow {
margin:0px!important;
/* margin-bottom: 20px!important; */
}
.signleEditor .content_editorMd_show{
display: flex;
margin-top:0px!important;
border-radius:2px;
max-width: 1056px;
word-break:break-all;
}
`}</style>
<TPMMDEditor mdID={qNumber+question_choices.length} placeholder="请您输入题目解析" height={155} className=" mt10"
initValue={question_titles} onChange={(val) => this.setState({ question_titles: val})}
ref="titleEditor2"
></TPMMDEditor>
</div>
</div>
)
}
}
// RouteHOC()
export default (SingleEditor);

@ -0,0 +1,611 @@
.w1200{
width:1062px;
height:177px;
background:rgba(255,255,255,1);
box-shadow:0px 6px 8px 0px rgba(0,0,0,0.03);
border-radius:2px;
}
.w1200dbl{
width:1062px;
min-height:60px;
background:rgba(255,255,255,1);
box-shadow:0px 6px 8px 0px rgba(0,0,0,0.03);
border-radius:2px;
}
.w1200fpx{
width:1200px;
background:rgba(255,255,255,1);
box-shadow:0px 6px 8px 0px rgba(0,0,0,0.03);
border-radius:2px;
}
.w1200mss{
width:1200px;
}
.w1200ms{
width:1062px;
}
.w1200s{
width:1062px;
background:rgba(255,255,255,1);
box-shadow:0px 6px 8px 0px rgba(0,0,0,0.03);
border-radius:2px;
}
.h177{
height: 177px;
}
/* 中间居中 */
.intermediatecenter{
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
/* 简单居中 */
.intermediatecenterysls{
display: flex;
align-items: center;
}
.spacearound{
display: flex;
justify-content: space-around;
}
.spacebetween{
display: flex;
justify-content: space-between;
}
/* 头顶部居中 */
.topcenter{
display: -webkit-flex;
flex-direction: column;
align-items: center;
}
/* x轴正方向排序 */
/* 一 二 三 四 五 六 七 八 */
.sortinxdirection{
display: flex;
flex-direction:row;
}
/* x轴反方向排序 */
/* 八 七 六 五 四 三 二 一 */
.xaxisreverseorder{
display: flex;
flex-direction:row-reverse;
}
/* 垂直布局 正方向*/
/*
*/
.verticallayout{
display: flex;
flex-direction:column;
}
/* 垂直布局 反方向*/
.reversedirection{
display: flex;
flex-direction:column-reverse;
}
.w100{
width: 100px;
}
.mt21{
margin-top: 21px;
}
.mt23{
margin-top: 23px;
}
.mt19{
margin-top: 19px;
}
.mt15{
margin-top: 10px;
}
.h40{
height: 40px;
}
.tophom{
padding-top: 33px;
padding-bottom: 40px;
padding-left: 26px;
padding-right: 26px;
}
.tophoms{
padding-top: 15px;
padding-left: 26px;
padding-right: 26px;
}
.borderwd{
border: 1px solid #000000;
}
.borderwds{
width: 1020px !important;
background: #FFFFFF;
border: 1px solid #DDDDDD;
margin-left: 20px;
min-height:150px;
}
.borderwds283{
width: 1020px !important;
min-height:283px;
background:#F9F9F9;
border:1px solid #DDDDDD;
margin-left: 20px;
}
.w64{
width: 64px;
}
.w70{
width: 70px !important;
}
.tophomsembold{
height:21px;
font-size:16px;
color:#333333;
line-height:21px;
}
.tophomsembolds{
width:42px;
height:19px;
font-size:14px;
font-family:MicrosoftYaHeiSemibold;
color:rgba(51,51,51,1);
line-height:31px;
}
/*Contentpart*/
.contentparttit{
padding-top: 10px;
padding-left: 20px;
padding-right: 20px;
}
.subjecttit{
width:28px;
height:19px;
font-size:14px;
color:rgba(51,51,51,1);
line-height: 42px;
cursor:pointer;
}
.ml55{
margin-right: 55px;
}
.lg{
line-height: 42px;
}
.ml7{
margin-left: 7px;
}
.icondowncolor{
color:#9E9E9E;
}
.icondowncolorss{
color: #9E9E9E;
position: absolute;
top: -20px;
right: -16px;
}
.questiontype{
width: 100%;
font-size: 12px;
color: #333333;
line-height: 17px;
text-align: center;
padding: 11px;
cursor:pointer;
}
.questiontypes{
width:37px;
height:17px;
font-size:12px;
color:rgba(51,51,51,1);
line-height:17px;
cursor:pointer;
}
.questiontypeheng{
width:100%;
height:1px;
background: #EEEEEE;
}
.questiontype:hover{
color: #4CACFF;
}
.questiontype:active{
color: #4CACFF;
}
.w100s{
width:100%;
}
.stestcen{
text-align: center;
}
.w70s{
width:70%;
}
.w30s{
width:70%;
}
.w50s{
width: 50%;
}
.testpaper{
font-size:12px;
color:#888888;
line-height:28px;
text-align: center;
}
.setequesbank{
font-size:14px;
color:#333333;
line-height:28px;
}
.Contentquestionbankstyle{
padding-left: 20px;
padding-right: 20px;
}
.pd20{
padding-top: 20px;
padding-bottom: 20px;
padding-left: 30px;
padding-right: 30px;
}
/*listjihe*/
.listjihetixing{
color: #888888;
font-size: 12px;
line-height: 17px;
}
.listjihetixings{
color: #333333;
font-size: 12px;
line-height: 17px;
}
.listjihetixingstit{
color: #333333;
font-size: 14px;
line-height: 17px;
}
.listjihetixingstits{
color: #333333;
font-size: 14px;
line-height:19px;
margin-top: 19px;
}
.updatetimes{
color: #BBBBBB;
font-size: 12px;
}
.mt22{
margin-top: 22px;
}
.viewparsings{
color:#4CACFF;
font-size:12px;
line-height: 30px;
}
.selection{
width:88px;
height:30px;
background:#33BD8C;
border-radius:4px;
text-align: center;
line-height: 30px;
color: #FFFFFF;
}
.selectionss{
width:88px;
height:30px;
background:#eeeeee;
border-radius:4px;
text-align: center;
line-height: 30px;
color: #FFFFFF;
}
.lh30{
line-height: 30px;
}
.analysis{
height:19px;
font-size:14px;
color:#333333;
line-height:19px;
}
.testfondex{
color: #808080;
font-size: 14px;
}
.pb20{
padding-bottom: 20px;
}
.icontianjiadaohangcolor{
color: #FFFFFF;
}
.icontianjiadaohangcolors{
color: #4CACFF;
}
.xiaoshou{
cursor:pointer
}
.mt40{
margin-top: 40px;
}
.mt42{
margin-top: 42px;
}
.drawerbutton{
width:88px;
height:30px;
background:#4CACFF;
border-radius:4px;
font-size:14px;
color:#ffffff;
line-height:30px;
text-align: center;
}
.icondrawercolor{
color: #979797;
}
.mt25{
margin-top: 25px;
}
.mb26{
margin-bottom: 26px;
}
.drawernonedatadiv{
height: 100%;
}
.font-17{
font-size: 17px;
}
.ml30{
margin-right: 30px;
}
.mr25{
margin-right: 25px;
}
.newbutoon{
width:88px;
height:42px;
background:#33BD8C;
line-height: 42px;
border-radius:4px;
}
.newbutoontes{
width:100%;
height:42px;
font-size:14px;
color:#ffffff;
line-height:42px;
text-align: center;
}
.educouddiv {
display: flex;
flex-direction: column;
}
.tabeltext-alignleftysl{
font-size:14px;
color:#000000;
line-height:19px;
}
.tabeltext-alignleftysltwo{
font-size:14px;
color:#848282;
line-height:19px;
}
.publictask-btn{
width:80px;
height:34px;
background:#CCCCCC;
border-radius:4px;
color: #ffffff;
}
.publictask-btns{
width:80px;
height:34px;
background:#4CACFF;
border-radius:4px;
color: #ffffff;
}
.w80{
width: 80px;
}
.titiles{
color: #333333;
font-size: 16px;
}
.h12{
height: 12px;
min-height: 12px;
}
.mt19{
margin-top: 19px;
}
.mytags{
width:106px;
height:32px;
border-radius:2px;
border:1px solid #DDDDDD;
margin-left: 20px;
}
.lh32{
line-height: 32px;
}
.h20{
height: 20px;
min-height: 20px;
line-height: 20px;
}
.xingcolor{
color: rgba(224, 64, 64, 1);
}
.xingtigan{
font-size:14px;
color:rgba(51, 51, 51, 1);
}
.mr4{
margin-right: 4px;
}
.xingtigans{
width:100%;
font-size:14px;
color:rgba(136,136,136,1);
}
.bottomdivs{
width:100%;
height:55px;
background:rgba(255,255,255,1);
box-shadow:0px -2px 7px 0px rgba(1,6,22,0.04);
}
.mt50{
margin-top: 50px;
}
.divquxiao{
width:88px;
height:32px;
background:rgba(255,255,255,1);
border-radius:4px;
border:1px solid rgba(204,204,204,1);
}
.divquxiaotest{
width:100%;
height:32px;
font-size:12px;
color:rgba(136,136,136,1);
line-height:32px;
text-align: center;
}
.divbaocuntests{
width:100%;
height:32px;
font-size:12px;
color:#ffffff;
line-height:32px;
text-align: center;
}
.divbaocun{
width:88px;
height:32px;
background:rgba(76,172,255,1);
border-radius:4px;
}
.sortzhenque{
width:49px;
height:33px;
border-radius:2px;
border:1px solid rgba(221,221,221,1);
}
.sortzhenquetest{
width:100%;
height:33px;
font-size:14px;
color:rgba(51,51,51,1);
line-height:33px;
}
.sortquxiao{
width:49px;
height:33px;
border-radius:2px;
border:1px solid rgba(221,221,221,1);
}
.sortquxiaotest{
width:100%;
height:33px;
font-size:14px;
color:rgba(51,51,51,1);
line-height:33px;
}
.ml45{
margin-left: 45px;
}
.programcss{
height: 251px;
min-height: 100%;
}
.titlesttingcss{
min-width: 100px;
height:32px;
line-height: 32px;
background:rgba(76,172,255,1);
border-radius:16px;
text-align: center;
color: #fff;
}
.titlesttingcssmy{
min-width: 100px;
height:32px;
line-height: 32px;
font-size:14px;
color:rgba(51,51,51,1);
text-align: center;
}
.minleng40{
min-height: 40px;
}
.w60{
width: 60px !important;
}
.h30{
min-height: 30px !important;
}
.minheight{
min-height: 500px !important;
}

@ -13,7 +13,7 @@ import { getImageUrl, toPath ,trigger,broadcastChannelPostMessage} from 'educode
import axios from 'axios';
import { Modal,Checkbox ,Radio,Input,message,notification } from 'antd';
import { Modal,Checkbox ,Radio,Input,message,notification,Popover} from 'antd';
import Addcourses from '../courses/coursesPublic/Addcourses';
@ -69,6 +69,7 @@ class NewHeader extends Component {
headtypesonClickbool:false,
headtypess:"/",
mygetHelmetapi2: null,
visiblemyss:false,
}
console.log("176")
// console.log(props);
@ -705,6 +706,15 @@ submittojoinclass=(value)=>{
document.head.appendChild(link);
}
handleVisibleChanges = (boll) => {
this.setState({
visiblemyss: boll,
})
}
getAppdata=()=>{
let url = "/setting.json";
axios.get(url).then((response) => {
@ -874,7 +884,17 @@ submittojoinclass=(value)=>{
})
}
const contents = (
<div className="questiontypes" style={{
width:'93px',
height:'80px',
}}>
<a href={'/question'} ><p className="questiontype">试题库</p></a>
<p className="questiontypeheng"></p>
<a href={'/question'} ><p className="questiontype">试卷库</p></a>
<p className="questiontypeheng"></p>
</div>
);
return (
<div className="newHeaders" id="nHeader" >
@ -948,10 +968,38 @@ submittojoinclass=(value)=>{
)
})
}
{/*<li className={`${activePaths === true ? 'pr active' : 'pr'}`}>*/}
{/* <Link to={this.props.Headertop===undefined?"":'/paths'}>实践课程</Link>*/}
{/*<style>*/}
{/* {*/}
{/* `*/}
{/* .queyppors {*/}
{/* top: 63px !important;*/}
{/* }*/}
{/* .ant-popover-inner-content {*/}
{/* padding:0px !important;*/}
{/* }*/}
{/* `*/}
{/* }*/}
{/*</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 `}>
<Link to={'/question'}>题库</Link>
</li>
{/*<li><a href={this.props.Headertop===undefined?"":'/courses'}>课堂</a></li>*/}
{/*<li className={`${coursestype === true ? 'pr active' : 'pr'}`}>*/}
{/* /!*<a href={this.props.Headertop===undefined?"":this.props.Headertop.course_url}>课堂</a>*!/*/}

@ -89,10 +89,13 @@ class SiderBar extends Component {
render() {
// console.log(this.props)
// console.log("SiderBar");
// console.log(this.props);
var mypath= this.props&&this.props.match&&this.props.match.path;
return (
<div className="-task-sidebar" >
<div className={"-task-sidebar"} >
{this.props.mygetHelmetapi&&this.props.mygetHelmetapi.main_site===true?<div>
<Tooltip placement="right" title={"返回顶部"}>
@ -103,6 +106,21 @@ class SiderBar extends Component {
</div>
</Tooltip>
{
mypath&&mypath==="/question"?
<Tooltip placement="right" title={"试题库"}>
<div className="feedback feedbackdivcolor xiaoshou" onClick={()=>this.props.showDrawer()} >
<a target="_blank" className="color_white xiaoshou" >
<i className="iconfont icon-shitilan color-white xiaoshou"></i>
</a>
<p className="color-white font-12 xiaoshou">试题库</p>
</div>
</Tooltip>
:""
}
<Tooltip placement="right" title={"意见反馈"}>
<div className="feedback">
<a target="_blank" className="color_white" href="/help/feedback">

@ -130,16 +130,19 @@ class TPMBanner extends Component {
if(this.props.status===0&&this.props.openknows===false){
if(this.props.shixunsDetails&&this.props.shixunsDetails.shixun_status === 0 && this.props.identity < 5){
if(shixunopenprocess===undefined||shixunopenprocess===false||shixunopenprocess===null){
this.setState({
openknow:true
})
}else{
this.setState({
openknow:false
})
if(this.props.user&&this.props.user.user_id){
if(shixunopenprocess===undefined||shixunopenprocess===false||shixunopenprocess===null){
this.setState({
openknow:true
})
}else{
this.setState({
openknow:false
})
}
}
}
}
}else{
this.setState({
openknow:false
@ -150,14 +153,16 @@ class TPMBanner extends Component {
if(this.props.public===0&&this.props.status>1&&this.props.openknows===false){
if(this.props.shixunsDetails&&this.props.shixunsDetails.shixun_status === 2 && this.props.shixunsDetails&&this.props.shixunsDetails.public===0 && this.props.identity < 5){
if(openopenpublictype===undefined||openopenpublictype===false||openopenpublictype===null){
this.setState({
openshowpublictype:true
})
}else{
this.setState({
openshowpublictype:false
})
if(this.props.user&&this.props.user.user_id) {
if (openopenpublictype === undefined || openopenpublictype === false || openopenpublictype === null) {
this.setState({
openshowpublictype: true
})
} else {
this.setState({
openshowpublictype: false
})
}
}
}
}else{

@ -1,6 +1,6 @@
import React, {Component} from 'react';
import {Redirect} from 'react-router';
import {List, Typography, Tag, Modal, Radio, Checkbox, Table, Pagination,Upload,Button} from 'antd';
import {List, Typography, Tag, Modal, Radio, Checkbox, Table,message, Pagination,Upload,Button} from 'antd';
import { NoneData } from 'educoder'
import TPMRightSection from './component/TPMRightSection';
@ -12,7 +12,29 @@ import moment from 'moment';
import Tpmdatasetmodel from "./tpmmodel/Tpmdatasetmodel";
const confirm = Modal.confirm;
function clearSlct() {
if("getSelection" in window){
window.getSelection().removeAllRanges();
}else{
document.selection.empty();
};
}
function jsCopy(s) {
clearSlct();
const copyEle = document.getElementById(s);
copyEle.select();
const copyStatus=document.execCommand("Copy");
// 对成功与否定进行提示
copyStatuss(copyStatus)
}
function copyStatuss(copyStatus){
if (copyStatus) {
message.success('复制成功');
} else {
message.error('复制失败');
}
}
class TPMDataset extends Component {
constructor(props) {
super(props)
@ -69,6 +91,33 @@ class TPMDataset extends Component {
</div>
)
},
{
title: '操作',
dataIndex: 'operation',
key: 'operation',
align: 'center',
className: "edu-txt-center font-14 ",
render: (text, record) => (
<div style={{
cursor:"pointer",
}} onClick={() => {
jsCopy("file_path"+record.id)
}}>
<i className="iconfont icon-fuzhi3 font-18 ml2 questiontype" style={{
color:"#A0A7B4"
}} ></i>
<div
style={{
overflow: 'hidden',
height: "1px",
width: "1px"
}}
>
<input id={"file_path"+record.id} value={record.file_path}/>
</div>
</div>
)
},
],
page: 1,
limit: 10,
@ -148,6 +197,7 @@ class TPMDataset extends Component {
filesize:datas[i].filesize,
id:datas[i].id,
title:datas[i].title,
file_path:datas[i].file_path,
})
}
this.setState({
@ -203,6 +253,7 @@ class TPMDataset extends Component {
filesize:datas[i].filesize,
id:datas[i].id,
title:datas[i].title,
file_path:datas[i].file_path,
})
}
this.setState({

@ -229,4 +229,41 @@ body>.-task-title {
}
.wechatcenter{
text-align: center;
}
}
.myrigthsiderbar{
right: 9% !important;
}
.feedbackdivcolor{
background: #33BD8C !important;
height: 49px !important;
line-height: 24px !important;
}
.xiaoshou{
cursor:pointer
}
.questiontypes{
width:37px;
height:17px;
font-size:12px;
color:rgba(51,51,51,1);
line-height:17px;
cursor:pointer;
}
.questiontype{
width: 100%;
font-size: 12px;
color: #333333;
line-height: 17px;
text-align: center;
padding: 11px;
cursor:pointer;
}
.questiontypeheng{
width:100%;
height:1px;
background: #EEEEEE;
}

@ -87,6 +87,11 @@ const TPMchallengesnew = Loadable({
loader: () => import('./challengesnew/TPMchallengesnew'),
loading: Loading,
})
//新建实训
// const TPMchallengesnew = Loadable({
// loader: () => import('./challengesnew/TpmTask/TpmTaskIndex'),
// loading: Loading,
// })
//新建tab2
const TPMevaluation = Loadable({
@ -383,8 +388,6 @@ class TPMIndex extends Component {
let url = window.location.href;
let flag = url.indexOf("add_file")>-1;
console.log(this.state.openknows)
return (
<div className="newMain clearfix">
{/*头部*/}

@ -35,14 +35,14 @@ if (!window['indexHOCLoaded']) {
// $('head').append($('<link rel="stylesheet" type="text/css" />')
// .attr('href', `${_url_origin}/stylesheets/educoder/antd.min.css?1525440977`));
$('head').append($('<link rel="stylesheet" type="text/css" />')
.attr('href', `${_url_origin}/stylesheets/css/edu-common.css?8`));
.attr('href', `${_url_origin}/stylesheets/css/edu-common.css?2020`));
$('head').append($('<link rel="stylesheet" type="text/css" />')
.attr('href', `${_url_origin}/stylesheets/educoder/edu-main.css?8`));
.attr('href', `${_url_origin}/stylesheets/educoder/edu-main.css?2020`));
// index.html有加载
$('head').append($('<link rel="stylesheet" type="text/css" />')
.attr('href', `${_url_origin}/stylesheets/educoder/edu-all.css?8`));
.attr('href', `${_url_origin}/stylesheets/educoder/edu-all.css?2020`));
// $('head').append($('<link rel="stylesheet" type="text/css" />')
@ -635,6 +635,18 @@ export function TPMIndexHOC(WrappedComponent) {
}
}
//跳转道描点的地方
scrollToAnchor = (anchorName) => {
if (anchorName) {
// 找到锚点
let anchorElement = document.getElementById(anchorName);
// 如果对应id的锚点存在就跳转到锚点
if (anchorElement) {
anchorElement.scrollIntoView();
}
}
}
render() {
let{Headertop,Footerdown, isRender, AccountProfiletype,AccountPhoneemailtype}=this.state;
const common = {
@ -670,11 +682,16 @@ export function TPMIndexHOC(WrappedComponent) {
hideGlobalLoading: this.hideGlobalLoading,
yslslowCheckresults:this.yslslowCheckresults,
yslslowCheckresultsNo:this.yslslowCheckresultsNo,
MdifHasAnchorJustScorll:this.MdifHasAnchorJustScorll
MdifHasAnchorJustScorll:this.MdifHasAnchorJustScorll,
scrollToAnchor:this.scrollToAnchor
};
// console.log("this.props.mygetHelmetapi");
// console.log(this.props.mygetHelmetapi);
// console.log("WrappedComponent");
// console.log(this.props);
// console.log(this.props.match.path);
var mypath= this.props&&this.props.match&&this.props.match.path;
return (
<div className="indexHOC">
{isRender===true ? <LoginDialog
@ -696,10 +713,17 @@ export function TPMIndexHOC(WrappedComponent) {
{...this.state}
{...this.dialogObj}
/>:""}
<SiderBar
{...this.props}
{...this.state}
Headertop={Headertop}/>
{
mypath&&mypath==="/question"?
""
:
<SiderBar
{...this.props}
{...this.state}
Headertop={Headertop}/>
}
{/* 注释掉了1440 影响到了手机屏幕的展示 */}
<style>{
`

@ -1,48 +1,21 @@
import React, {Component} from 'react';
import {Input, InputNumber, Select, Radio, Checkbox, Popconfirm, message, Modal, Tooltip} from 'antd';
import {Input, InputNumber, Button, Tooltip} from 'antd';
import {BrowserRouter as Router, Route, Link, Switch} from "react-router-dom";
// import "antd/dist/antd.css";
import { getImageUrl, toPath, getUrl } from 'educoder';
import axios from 'axios';
import './css/TPMchallengesnew.css';
import TPMMDEditor from './TPMMDEditor';
import Bottomsubmit from "../../modals/Bottomsubmit";
let origin = getUrl();
let path = getUrl("/editormd/lib/")
import './css/TPMchallengesnew.css';
const $ = window.$;
let timeout;
let currentValue;
const Option = Select.Option;
const RadioGroup = Radio.Group;
// const testAnswers = [{
// "id": 4337,
// "name": "解题思路1",
// "contents": "答案的解题思路1",
// "level": 1,
// "score": 25
// },
// {
// "id": 4338,
// "name": "解题思路2",
// "contents": "答案的解题思路2",
// "level": 2,
// "score": 25
// }]
export default class TPManswer extends Component {
constructor(props) {
super(props)
@ -94,7 +67,7 @@ export default class TPManswer extends Component {
}
}
this.setState({
answer:response.data.answer,
answer:response.data.answer,
power: response.data.power,
choice_url: newchoice_url, // 导航中的新建选择题url
practice_url: newpractice_url, //string 导航中新建实践题url
@ -102,10 +75,11 @@ export default class TPManswer extends Component {
position: response.data.position, //int 关卡位置,导航栏中的第几关
prev_challenge: newprev_challenge,
next_challenge: next_challenge,
responsedata:response.data,
})
if(response.data.power===false){
this.props.showSnackbar("没有权限修改");
this.props.showNotification("没有权限修改");
}
// if(response.data.answer===undefined||response.data.answer===null){
// this.answerMD("", "answerMD");
@ -133,7 +107,7 @@ export default class TPManswer extends Component {
// this.refs.md0
const { answers } = this.state;
const answersParams = answers.slice(0)
console.log(answersParams)
// console.log(answersParams)
let isValidate = true;
let totalScore = 0;
answersParams.forEach( (item, index) => {
@ -147,10 +121,10 @@ export default class TPManswer extends Component {
totalScore += item.score;
delete item.id;
if (!item.name) {
this.props.showSnackbar("请先填写参考答案名称");
this.props.showNotification("请先填写参考答案名称");
isValidate = false;
} else if (!mdContnet) {
this.props.showSnackbar("请先填写参考答案内容");
this.props.showNotification("请先填写参考答案内容");
isValidate = false;
}
if (!isValidate) {
@ -161,7 +135,7 @@ export default class TPManswer extends Component {
return;
}
if (answersParams.length != 0 && totalScore != 100) {
this.props.showSnackbar("请先保证占比和为100%");
this.props.showNotification("请先保证占比和为100%");
return;
}
let id = this.props.match.params.shixunId;
@ -174,7 +148,7 @@ export default class TPManswer extends Component {
).then((response) => {
if (response.data) {
if (response.data.message) {
this.props.showSnackbar(response.data.message);
this.props.showNotification(response.data.message);
}
if (response.data.status == 1) {
window.location.href=`/shixuns/${id}/challenges`;
@ -233,12 +207,16 @@ export default class TPManswer extends Component {
}
})
}
gotocheckpoint=(url)=>{
this.props.history.replace(url);
}
render() {
let {
choice_url,
practice_url,
go_back_url,
responsedata,
position,
task_pass_default,
submit_url,
@ -256,60 +234,51 @@ export default class TPManswer extends Component {
return (
<React.Fragment>
<div className="educontent mt30 mb30 tpmAnswer">
<div className="padding10-20 mb10 edu-back-white clearfix">
<span className="fl ring-blue mr10 mt7">
<img src={getImageUrl("images/educoder/icon/code.svg")} data-tip-down="实训任务" className="fl mt2 ml2"/>
</span>
<span className="font-16 task-hide fl TPMtaskName">{position}</span>
<Link to={go_back_url === undefined ? "" : go_back_url}
className="color-grey-6 fr font-15 mt3">返回</Link>
{prev_challenge === undefined ? "" :
<a href={prev_challenge} className="fr color-blue mr15 mt4">上一关</a>
}
{next_challenge === undefined ? "" :
<a href={next_challenge} className="fr color-blue mr15 mt4">下一关</a>
}
<a href={practice_url === undefined ? "" : practice_url}
className="fr color-blue mr15 mt4"
style={{display:this.props.status===2||this.props.status===1?'none':'block'}}
data-tip-down="新增代码编辑类型的任务">+&nbsp;实践类型</a>
<a href={choice_url === undefined ? "" : choice_url}
className="fr color-blue mr15 mt4"
style={{display:this.props.status===2||this.props.status===1?'none':'block'}}
data-tip-down="新增选择题类型的任务">+&nbsp;选择题类型</a>
<div className="TPMchallengesnewtitles edu-back-white clearfix borderbottomf4">
<span className="font-16 task-hide fl TPMtaskName">{position}{responsedata&&responsedata.st === 0 ?"实践题":responsedata&&responsedata.st === 1?"选择题":""}</span>
{this.props.identity>4||this.props.identity===undefined||this.props.status===2||this.props.status===1?"":<a href={practice_url === undefined ? "" : practice_url} className="fr ml15 mt13">
<Button type="primary" className="edu-default-btn edu-greenback-btn "
>新增实践任务</Button></a>}
{this.props.identity>4||this.props.identity===undefined||this.props.status===2||this.props.status===1?"":<Link to={choice_url === undefined ? "" : choice_url}
className="fr ml15 mt13">
<Button type="primary"
className="edu-default-btn edu-greenback-btn mr5"
>新增选择题任务</Button></Link>}
{next_challenge===undefined?"":
<Button type="primary" ghost onClick={()=>this.gotocheckpoint(next_challenge)}
className="edu-default-btn edu-greenback-btn mr5 fr ml15 mt13"
>下一关</Button> }
{prev_challenge===undefined?"":
<Button type="primary" ghost onClick={()=>this.gotocheckpoint(prev_challenge)}
className="edu-default-btn edu-greenback-btn mr5 fr ml15 mt13"
>上一关</Button>}
</div>
<div className="challenge_nav clearfix edu-back-white">
<li>
<Link to={tab1url}>本关任务</Link>
<Link to={tab1url}>1本关任务 </Link>
</li>
{tab2url === "" ? "":<li> > </li>}
<li >
<Link to={tab2url}>评测设置</Link>
<Link to={tab2url} >2评测设置</Link>
</li>
{tab3url === "" ? "":<li> > </li>}
<li className="active">
<Link to={tab3url}>参考答案</Link>
<Link to={tab3url} className={"color-blue"}> 3参考答案</Link>
</li>
</div>
<div className="edu-back-white mb10 clearfix">
<div className="padding30-20">
<p className=" font-12" style={{ paddingBottom: '5px'
, color: '#666666'}}>
可以将参考答案分级设置让学员自行选择级别每级查看后按照比例扣分值学员已完成任务再查看则不影响原因已获得的成绩
<p className=" font-14" style={{ paddingBottom: '5px'
, color: '#333'}}>
可以将参考答案分级设置让学员自行选择级别每级查看后按照比例扣分值学员已完成任务再查看则不影响学员已获得的成绩
</p>
<p className=" font-12 "
style={{ maxWidth: "782px"
, color: '#999999'}}>
示例级别1扣减分值占比25%级别2扣减分值占比35%级别3扣减分值占比40%则学员选择查看级别1的答案将被扣减25%的分值
选择查看级别2的答案将被扣减60%的分值选择查看级别3的答案将被扣减100%的分值
<p className=" font-14 mt15 "
style={{ color: '#888'}}>
<div>示例级别1扣减分值占比25%级别2扣减分值占比35%级别3扣减分值占比40%</div>
<div className={"mt5 ml41"}>若学员选择查看级别1的答案将被扣减25%的分值选择查看级别2的答案将被扣减60%的分值选择查看级别3的答案将被扣减100%的分值</div>
</p>
<style>{`
@ -320,25 +289,31 @@ export default class TPManswer extends Component {
{
answers.map((answer, index) => {
return <div className="levelSection" id={`levelSection${index}`} style={{ clear: 'both' }}>
return <div className="levelSection mt30" id={`levelSection${index}`} style={{ clear: 'both' }}>
<span className="mr4 color-orange pt10">*</span>
<p className="color-grey-6 font-16 mb30 mt10" style={{ display: "inline" }}>级别{index + 1}</p>
<p className="color-grey-6 font-16 mb30 mt10" style={{ display: "inline" }}>级别{index + 1}</p>
<Tooltip title="删除">
<a className="fr sample_icon_remove mr30 mt8" onClick={()=>this.delanswers(index)}>
<i className="fa fa-times-circle color-grey-c font-16 fl" ></i>
<a className="fr sample_icon_remove mr10 mt8" onClick={()=>this.delanswers(index)}>
<i className={"iconfont icon-shanchu_Hover font-16 fl"}></i>
</a>
</Tooltip>
<div className=" color-grey-6 font-16" style={{ marginLeft: "9px", margin: '8px 9px'}}>
<div className=" color-grey-6 font-16 bortopeeetpm pt20 mt20" style={{ marginLeft: "9px", margin: '8px 9px'}}>
<div className=" ">
<span>名称</span>
<Input value={answer.name} onChange={(e) => this.onNameChange(e, index)}></Input>
<span style={{ marginLeft: "20px"}} >扣减分值占比</span>
<InputNumber className="score" step={1} min={1} max={100} defaultValue={answer.score}
onChange={(e) => this.onScoreChange(e, index)} ></InputNumber>%
<div className={"wind500height45"}>
<div className={"fl"} style={{'width':'240px'}}>名称</div>
<div className={"fl"} style={{ marginLeft: "20px"}} >扣减分值占比</div>
</div>
<div className={"wind500height45"}>
<Input value={answer.name} onChange={(e) => this.onNameChange(e, index)}></Input>
<InputNumber className="score" step={1} min={1} max={100} defaultValue={answer.score}
style={{ marginLeft: "32px"}}
onChange={(e) => this.onScoreChange(e, index)} ></InputNumber> %
</div>
</div>
<div className="mt10">
<span>参考答案</span>
<span>内容</span>
<TPMMDEditor ref={`md${index}`} mdID={index} initValue={answer.contents}
onChange={(val) => this.answerOnChange(val, index)}></TPMMDEditor>
</div>
@ -348,19 +323,28 @@ export default class TPManswer extends Component {
}
<div className="clearfix mt20" style={{display:this.props.identity>4||this.props.identity===undefined||power===false?"none":"block"}}>
<a href={"javascript:void(0)"} className="defalutCancelbtn fl" onClick={this.addAnswer}>新增</a>
{/*<a href={"javascript:void(0)"} className="defalutCancelbtn fl" >新增参考答案</a>*/}
<Button type="primary" ghost className="edu-default-btn edu-greenback-btn mt20 mb20 newaddswermargin" onClick={this.addAnswer}>新增参考答案</Button>
</div>
</div>
</div>
<div className="clearfix mt20" style={{display:this.props.identity>4||this.props.identity===undefined||power===false?"none":"block"}}>
<a className="defalutSubmitbtn fl mr20"
onClick={this.challenge_answer_submit}>提交</a>
<a href={"/shixuns/" + shixunId + "/challenges"} className="defalutCancelbtn fl">取消</a>
</div>
</div>
{this.props.identity>4||this.props.identity===undefined||power===false?"":<div className="clearfix mt20" >
{/*<a className="defalutSubmitbtn fl mr20" onClick={this.challenge_answer_submit}>提交</a>*/}
{/*/!*<a href={"/shixuns/" + shixunId + "/challenges"} className="defalutCancelbtn fl">取消</a>*!/*/}
{/*<Link to={"/shixuns/" + shixunId + "/challenges"} className={"defalutCancelbtn fl"}>取消</Link>*/}
<Bottomsubmit url={"/shixuns/" + shixunId + "/challenges"}
bottomvalue={"提交"}
onSubmits={this.challenge_answer_submit}
{...this.props}
{...this.state}
loadings={false}
/>
</div>}
</React.Fragment>
)
}

@ -1,31 +1,19 @@
import React, {Component} from 'react';
import {Input, Select, Radio, Checkbox, Popconfirm, message, Modal} from 'antd';
import {Input, Select, Radio, Badge, message, Button} from 'antd';
import {BrowserRouter as Router, Route, Link, Switch} from "react-router-dom";
// import "antd/dist/antd.css";
import {Link} from "react-router-dom";
import TPMMDEditor from '../../tpm/challengesnew/TPMMDEditor';
import Bottomsubmit from "../../modals/Bottomsubmit";
import axios from 'axios';
import './css/TPMchallengesnew.css';
import { getImageUrl, toPath } from 'educoder';
import {getUrl} from 'educoder';
let origin = getUrl();
let path = getUrl("/editormd/lib/")
const $ = window.$;
let timeout;
let currentValue;
const Option = Select.Option;
const RadioGroup = Radio.Group;
@ -40,12 +28,12 @@ export default class TPMchallengesnew extends Component {
go_back_url: undefined,
task_pass_default: undefined,
submit_url: undefined,
shixunCreatePracticeGroup: 1,
shixunCreatePracticeGroup: undefined,
optionsums:[100,200],
activetype:0,
setopen: false,
shixunCreatePractice: undefined,
onshixunsmarkvalue: 100,
onshixunsmarkvalue: undefined,
shixunsskillvalue: undefined,
shixunsskillvaluelist: [],
tab2url: "",
@ -59,12 +47,13 @@ export default class TPMchallengesnew extends Component {
editPracticesendtype:false,
CreatePracticesendtype:false,
exec_time:20,
shixunExec_timeType:false
shixunExec_timeType:false,
onshixunsmarkvaluetype:false,
shixunCreatePracticeGrouptype:false
}
}
componentDidMount() {
getdatas=()=>{
let id = this.props.match.params.shixunId;
let checkpointId=this.props.match.params.checkpointId;
@ -83,10 +72,11 @@ export default class TPMchallengesnew extends Component {
task_pass_default: response.data.task_pass_default,
submit_url: response.data.submit_url,
checkpointId:checkpointId,
exercisememoMDRefval:response.data.task_pass_default
exercisememoMDRefval:response.data.task_pass_default,
responsedata:response.data
})
this.exercisememoMDRef.current.setValue(response.data.task_pass_default||'')
this.exercisememoMDRef.current.setValue(response.data.task_pass_default||'')
}).catch((error) => {
console.log(error)
});
@ -133,16 +123,18 @@ export default class TPMchallengesnew extends Component {
onshixunsmarkvalue:response.data.score,
shixunsskillvaluelist:response.data.tags,
checkpointId:checkpointId,
exec_time:response.data.exec_time,
tab2url: "/shixuns/" + id + "/challenges/"+checkpointId+"/tab=2",
tab3url: "/shixuns/" + id + "/challenges/"+checkpointId+"/tab=3",
exercisememoMDRefval:response.data.task_pass
exercisememoMDRefval:response.data.task_pass,
responsedata:response.data
})
// exec_time:response.data.exec_time,
if(response.data.power===false){
this.props.showSnackbar("你没有权限修改");
this.props.showNotification("你没有权限修改");
}
this.exercisememoMDRef.current.setValue(response.data.task_pass||'')
this.exercisememoMDRef.current.setValue(response.data.task_pass||'')
}).catch((error) => {
console.log(error)
});
@ -150,8 +142,24 @@ export default class TPMchallengesnew extends Component {
}
}
componentDidUpdate=(prevProps, prevState)=>{
if(prevProps!=this.props){
this.getdatas()
}
}
componentDidMount() {
this.getdatas()
}
onshixunCreatePracticeChange = (e) => {
if(e.target.value===undefined||e.target.value=== ""||e.target.value=== null){
}else{
this.setState({
shixunCreatePracticeGrouptype:false,
onshixunsmarkvaluetype:false
})
}
let optionsum;
let onshixunsmark;
if(e.target.value===1){
@ -172,9 +180,18 @@ export default class TPMchallengesnew extends Component {
}
shixunCreatePractice = (e) => {
if (e.target.value === undefined|| e.target.value== ""){
}else{
this.setState({
shixunCreatePracticetype:false
})
}
this.setState({
shixunCreatePractice: e.target.value
})
}
CreatePracticesend = () => {
@ -185,49 +202,92 @@ export default class TPMchallengesnew extends Component {
})
if(this.props.status===2){
this.props.showSnackbar("该实训已经发布不能新建")
this.props.showNotification("该实训已经发布不能新建")
this.setState({
CreatePracticesendtype:false
})
return
}
let {shixunCreatePractice, shixunCreatePracticeGroup, onshixunsmarkvalue, shixunsskillvaluelist,exec_time} = this.state;
if (shixunCreatePractice === undefined||shixunCreatePractice=="") {
this.setState({
shixunCreatePracticetype: true
shixunCreatePracticetype: true,
CreatePracticesendtype:false
})
this.props.showSnackbar("任务名称为空")
$('html').animate({
$('html').animate({
scrollTop: 10
}, 1000);
this.setState({
CreatePracticesendtype:false
})
return
}
if (shixunCreatePractice.match(/^[ ]*$/)) {
this.props.showNotification("任务名称为空,请勿输入空格");
this.setState({
shixunCreatePracticetype: true,
CreatePracticesendtype:false
})
$('html').animate({
scrollTop: 10
}, 1000);
return
}
if(shixunCreatePracticeGroup===undefined){
this.setState({
shixunCreatePracticeGrouptype:true,
CreatePracticesendtype:false
})
this.props.scrollToAnchor("shixunCreatePracticeGroupid");
return
}
if(onshixunsmarkvalue===undefined){
this.setState({
onshixunsmarkvaluetype:true,
CreatePracticesendtype:false
})
this.props.scrollToAnchor("input_task_tag");
return
}
if (shixunsskillvaluelist.length === 0) {
this.setState({
shixunsskillvaluelisttype: true,
CreatePracticesendtype:false
CreatePracticesendtype:false
})
this.props.showSnackbar("技能标签为空")
// this.props.showNotification("技能标签为空")
this.props.scrollToAnchor("input_task_tag");
return
}
if(exec_time===null||exec_time===undefined||exec_time===""){
this.setState({
shixunExec_timeType:false
})
return
}
// if(exec_time===null||exec_time===undefined||exec_time === ""){
// this.setState({
// shixunExec_timeType:true,
// CreatePracticesendtype:false
// })
// this.props.scrollToAnchor("exec_time");
// return
// }
// if (exec_time.match(/^[ ]*$/)) {
// this.props.showNotification("评测时限,请勿输入空格");
// this.setState({
// shixunExec_timeType:true,
// CreatePracticesendtype:false
// })
// this.props.scrollToAnchor("exec_time");
// return
// }
const exercise_editormdvalue = this.exercisememoMDRef.current.getValue().trim();
let id = this.props.match.params.shixunId;
let url = "/shixuns/" + id + "/challenges.json";
// exec_time:exec_time
axios.post(url, {
identifier:id,
subject: shixunCreatePractice,
@ -236,12 +296,12 @@ export default class TPMchallengesnew extends Component {
score: onshixunsmarkvalue,
challenge_tag: shixunsskillvaluelist,
st: 0,
exec_time:exec_time
}).then((response) => {
if (response.data.status === 1) {
// $("html").animate({ scrollTop: 0 })
//window.location.href=`/shixuns/${id}/challenges/${response.data.challenge_id}/editcheckpoint?tab=2`;
window.location.href=`/shixuns/${id}/challenges/${response.data.challenge_id}/tab=2`;
// window.location.href=`/shixuns/${id}/challenges/${response.data.challenge_id}/tab=2`;
this.props.history.replace(`/shixuns/${id}/challenges/${response.data.challenge_id}/tab=2`);
// this.setState({
// setopen: true,
// CreatePracticesendtype:false,
@ -250,7 +310,7 @@ export default class TPMchallengesnew extends Component {
// })
}
// this.props.showSnackbar(response.data.messages);
// this.props.showNotification(response.data.messages);
}).catch((error) => {
console.log(error)
});
@ -287,6 +347,12 @@ export default class TPMchallengesnew extends Component {
let list = shixunsskillvaluelist;
list.push(shixunsskillvalue);
if (list.length> 0) {
this.setState({
shixunsskillvaluelisttype: false,
})
}
this.setState({
shixunsskillvaluelist: list,
shixunsskillvalue: ""
@ -316,38 +382,77 @@ export default class TPMchallengesnew extends Component {
let url = "/shixuns/"+id+"/challenges/"+checkpointId+".json";
if (shixunCreatePractice === undefined||shixunCreatePractice=="") {
// this.setState({
// shixunCreatePracticetype: true
// })
this.props.showSnackbar("任务名称为空")
this.setState({
shixunCreatePracticetype: true,
editPracticesendtype:false
})
// this.props.showNotification("任务名称为空")
$('html').animate({
scrollTop: 10
}, 1000);
return
}
if (shixunCreatePractice.match(/^[ ]*$/)) {
this.props.showNotification("任务名称为空,请勿输入空格");
this.setState({
editPracticesendtype:false
shixunCreatePracticetype: true,
editPracticesendtype:false
})
$('html').animate({
scrollTop: 10
}, 1000);
return
}
if (shixunsskillvaluelist.length === 0) {
// this.setState({
// shixunsskillvaluelisttype: true
// })
this.props.showSnackbar("技能标签为空")
if(shixunCreatePracticeGroup===undefined){
this.setState({
editPracticesendtype:false
shixunCreatePracticeGrouptype:true,
editPracticesendtype:false
})
this.props.scrollToAnchor("shixunCreatePracticeGroupid");
return
}
if(onshixunsmarkvalue===undefined){
this.setState({
onshixunsmarkvaluetype:true,
editPracticesendtype:false
})
this.props.scrollToAnchor("input_task_tag");
return
}
if(exec_time===null||exec_time===undefined||exec_time===""){
if (shixunsskillvaluelist.length === 0) {
this.setState({
shixunsskillvaluelisttype: true,
editPracticesendtype:false,
})
this.props.scrollToAnchor("input_task_tag");
return
}
this.setState({
shixunExec_timeType:false
})
return
}
// if(exec_time===null||exec_time===undefined||exec_time === ""){
// this.setState({
// shixunExec_timeType:true,
// editPracticesendtype:false
// })
// this.props.scrollToAnchor("exec_time");
// return
// }
// if (exec_time.match(/^[ ]*$/)) {
// this.props.showNotification("评测时限,请勿输入空格");
// this.setState({
// shixunExec_timeType:true,
// editPracticesendtype:false
// })
// this.props.scrollToAnchor("exec_time");
// return
// }
// exec_time:exec_time
axios.put(url, {
tab:0,
identifier:id,
@ -357,19 +462,19 @@ export default class TPMchallengesnew extends Component {
task_pass: exercise_editormdvalue,
difficulty: shixunCreatePracticeGroup,
score: onshixunsmarkvalue,
exec_time:exec_time
},
challenge_tag:shixunsskillvaluelist
}).then((response) => {
this.props.showSnackbar(response.data.messages);
this.props.showNotification(response.data.messages);
if (response.data.status === 1) {
window.location.href=`/shixuns/${id}/challenges/${checkpointId}/tab=2`;
// window.location.href=`/shixuns/${id}/challenges/${checkpointId}/tab=2`;
this.setState({
setopen: true,
editPracticesendtype:false,
tab2url: "/shixuns/" + id + "/challenges/"+checkpointId+"/tab=2",
tab3url: "/shixuns/" + id + "/challenges/"+checkpointId+"/tab=3",
})
this.props.history.replace(`/shixuns/${id}/challenges/${checkpointId}/tab=2`);
// window.location.href = "/shixuns/" + id + "/challenges/"+response.data.challenge_id+"/tab=2"
}
}).catch((error) => {
@ -396,12 +501,16 @@ export default class TPMchallengesnew extends Component {
exec_time:e.target.value
})
}
gotocheckpoint=(url)=>{
this.props.history.replace(url);
}
render() {
let shixuntype = this.props.match.params.type;
let {marktype,
let {responsedata,
shixunCreatePracticetype, shixunsskillvaluelisttype,
choice_url, practice_url, go_back_url, position, task_pass_default, submit_url, setopen,checkpointId,prev_challenge,next_challenge,power,
shixunCreatePractice, shixunCreatePracticeGroup, onshixunsmarkvalue, shixunsskillvalue, shixunsskillvaluelist, tab2url, tab3url,optionsums,
@ -417,142 +526,143 @@ export default class TPMchallengesnew extends Component {
})
}
// console.log(this.props)
// console.log(this.state)
//a console.log(shixunCreatePractice)
return (
<React.Fragment>
<div className="educontent mt30 mb30">
<div className="padding10-20 mb10 edu-back-white clearfix">
<span className="fl ring-blue mr10 mt7">
<img src={getImageUrl("images/educoder/icon/code.svg")} data-tip-down="实训任务" className="fl mt2 ml2"/>
</span>
<span className="font-16 task-hide fl TPMtaskName">{position}</span>
<Link to={go_back_url === undefined ? "" : go_back_url}
className="color-grey-6 fr font-15 mt3">返回</Link>
{ next_challenge===undefined?"":
<a href={next_challenge}className="fr color-blue mr15 mt4">下一关</a>
}
{ prev_challenge===undefined?"":
<a href={prev_challenge} className="fr color-blue mr15 mt4">上一关</a>
}
<a href={practice_url === undefined ? "" : practice_url}
className="fr color-blue mr15 mt4"
style={{display:this.props.identity>4||this.props.identity===undefined||this.props.status===2||this.props.status===1?"none":'block'}}
data-tip-down="新增代码编辑类型的任务">+&nbsp;实践类型</a>
<a href={choice_url === undefined ? "" : choice_url}
className="fr color-blue mr15 mt4"
style={{display:this.props.identity>4||this.props.identity===undefined||this.props.status===2||this.props.status===1?"none":'block'}}
data-tip-down="新增选择题类型的任务">+&nbsp;选择题类型</a>
<div className="TPMchallengesnewtitles edu-back-white clearfix borderbottomf4">
<span className="font-16 task-hide fl TPMtaskName">{position}{responsedata&&responsedata.st === 0 ?"实践题":responsedata&&responsedata.st === 1?"选择题":""}</span>
{this.props.identity>4||this.props.identity===undefined||this.props.status===2||this.props.status===1?"":<a href={practice_url === undefined ? "" : practice_url} className="fr ml15 mt13">
<Button type="primary" className="edu-default-btn edu-greenback-btn "
>新增实践任务</Button></a>}
{this.props.identity>4||this.props.identity===undefined||this.props.status===2||this.props.status===1?"":<Link to={choice_url === undefined ? "" : choice_url}
className="fr ml15 mt13">
<Button type="primary"
className="edu-default-btn edu-greenback-btn mr5"
>新增选择题任务</Button></Link>}
{next_challenge===undefined?"":
<Button type="primary" ghost onClick={()=>this.gotocheckpoint(next_challenge)}
className="edu-default-btn edu-greenback-btn mr5 fr ml15 mt13"
>下一关</Button> }
{prev_challenge===undefined?"":
<Button type="primary" ghost onClick={()=>this.gotocheckpoint(prev_challenge)}
className="edu-default-btn edu-greenback-btn mr5 fr ml15 mt13"
>上一关</Button>}
</div>
<div className="challenge_nav clearfix edu-back-white">
<li className="active">
<a>本关任务</a>
<a className={"color-blue"}>1本关任务 </a>
</li>
{tab2url === "" ? "":<li> > </li>}
<li className="">
{tab2url === "" ? <span>评测设置</span> : <Link to={tab2url}></Link>}
{tab2url === "" ? <span></span> : <Link to={tab2url}>2</Link>}
</li>
{tab3url === "" ? "":<li> > </li>}
<li className="">
{tab3url === "" ? <span>参考答案</span> : <Link to={tab3url}></Link>}
{tab3url === "" ? <span></span> : <Link to={tab3url}> 3</Link>}
</li>
</div>
<div className="edu-back-white mb10 clearfix">
<div className="padding40-20">
<p className="color-grey-6 font-16 mb30">任务名称</p>
<div className="df">
<span className="mr30 color-orange pt10">*</span>
<div className="flex1 mr20">
<input type="text"
// className="input-100-45 greyInput"
className={shixunCreatePracticetype===true?"input-100-45 greyInpus wind100":"input-100-45 greyInput "}
maxLength="50"
name="challenge[subject]"
value={shixunCreatePractice}
<div className="edu-back-white clearfix">
<div className="newpadding1020">
<p className="color-grey-6 font-16 mb10"> <span className="mr5 color-red">*</span></p>
<div>
<div className="flex1">
<Input placeholder="请输入任务名称最大限制60个字符此信息将在实训发布后展示给学员计算学生的课程成绩绩点"
maxLength="60"
className={shixunCreatePracticetype === true ? "bor-red":"newViewAfter"}
onInput={this.shixunCreatePractice}
placeholder="请输入任务名称(此信息将提前展示给学员),例:计算学生的课程成绩绩点"/>
value={shixunCreatePractice}
addonAfter={`${String(!shixunCreatePractice? 0 : shixunCreatePractice.length)}/${60}`}
/>
</div>
<div style={{width: '57px'}}>
<span
className={shixunCreatePracticetype === true ? "color-orange mt8 fl block" : "color-orange mt8 fl none"}
id="new_shixun_name"><i
className="fa fa-exclamation-circle mr3"></i></span>
<div>
<span className={shixunCreatePracticetype === true ? "color-red mt8 fl block" : "color-red mt8 fl none"} id="new_shixun_name">必填项不能为空</span>
</div>
</div>
</div>
</div>
<div className="edu-back-white padding40-20 mb20">
<p className="color-grey-6 font-16 mb30">过关任务</p>
<TPMMDEditor ref={this.exercisememoMDRef} placeholder="请输入选择题的题干内容" mdID={'exercisememoMD'} refreshTimeout={1500}
watch={true} className="courseMessageMD" initValue={this.state.exercisememoMDRefval} height={700}></TPMMDEditor>
<div className="edu-back-white newpadding02020">
<p className="color-grey-6 font-16 mb10"><span className="mr5 color-red">*</span></p>
<style>
{
`
.markdown-body img {
max-width: 80%;
margin: 0 auto;
display: block;
width: auto;
height: auto;
max-height: 80%;
}
`
}
</style>
<TPMMDEditor ref={this.exercisememoMDRef} placeholder="请输入选择题的题干内容" mdID={'exercisememoMD'} refreshTimeout={1500}
watch={true} className="courseMessageMD" initValue={this.state.exercisememoMDRefval} height={800}></TPMMDEditor>
<p id="e_tip_Memochallengesnew" className="edu-txt-right color-grey-cd font-12"></p>
<p id="e_tips_Memochallengesnew" className="edu-txt-right color-grey-cd font-12"></p>
</div>
<div className="edu-back-white padding40-20 mb20">
<p className="color-grey-6 font-16 mb30">难度系数</p>
<div className="clearfix mb40">
<RadioGroup value={shixunCreatePracticeGroup} className="fl mr40"
disabled={this.props.status===2?true:false}
onChange={this.props.status===2?"":this.onshixunCreatePracticeChange}>
<div className="edu-back-white newpadding02020">
<p className="color-grey-6 font-16 mb20">
<span className="fl color-red mr5">*</span>
难度系数
<RadioGroup value={shixunCreatePracticeGroup}
className={"ml10"}
id={"shixunCreatePracticeGroupid"}
disabled={this.props.status===2?true:false}
onChange={this.props.status===2?"":this.onshixunCreatePracticeChange}>
<Radio value={1}>简单</Radio>
<Radio value={2}>中等</Radio>
<Radio value={3}>困难</Radio>
</RadioGroup>
</div>
<p className="color-grey-6 font-16 mb30">奖励经验值</p>
<div className="clearfix"
// onMouseLeave={this.props.status===2?"":this.onshixunsmarkss}
>
<span className="fl mr30 color-orange pt10">*</span>
<Select style={{width: 120}} className="winput-240-40 fl"
{this.state.shixunCreatePracticeGrouptype===true?<div className="color-red mt7 ml5 font-14" id="ex_value_notice">
必选项不能为空</div>:""}
</p>
<p className="color-grey-6 font-16 mb10"> <span className="fl mr5 color-red">*</span> <span className={"color-grey-8 font-14"}> (+100+100)</span></p>
<div className="clearfix">
{this.state.onshixunsmarkvaluetype===true?<style>
{
`
.ant-select-selection{
border:1px solid red;
}
`
}
</style>:""}
<Select style={{width: 252}}
className={"winput-240-40 ml3"}
id="challenge_score"
onChange={this.props.status===2?"":this.onshixunsmark}
// onMouseEnter={this.props.status===2?"":this.onshixunsmarks}
disabled={this.props.status===2?true:false}
// open={marktype}
value={onshixunsmarkvalue}
getPopupContainer={triggerNode => triggerNode.parentNode}
>
{options}
</Select>
<p className="fl color-grey-9 font-12 ml20">
如果学员答题错误则不能得到相应的经验值<br/>
如果学员成功得到经验值那么将同时获得等值的金币奖励+10经验值+10金币
</p>
<span className="color-orange mt7 fl ml20 none" id="ex_value_notice"><i
className="fa fa-exclamation-circle mr3"></i></span>
{this.state.onshixunsmarkvaluetype===true?<div className="color-red mt7 ml5" id="ex_value_notice">
必选项不能为空</div>:""}
</div>
</div>
<div className="edu-back-white padding40-20 mb20">
<p className="color-grey-6 font-16 mb30">技能标签</p>
<div className="clearfix df">
<span className="mr30 color-orange pt10">*</span>
<div className="edu-back-white newpadding02020">
<p className="color-grey-6 font-16 mb10"><span className="mr5 color-red">*</span><span className={"color-grey-8 font-14"}> ()</span></p>
<div className="clearfix">
<div className="flex1">
<Input type="text"
className="winput-240-40 fl mr20 winput-240-40s"
className={shixunsskillvaluelisttype === true ?"winput-240-40 fl mr20 winput-240-40s ml10 bor-red":"winput-240-40 fl mr20 winput-240-40s ml10"}
id="input_task_tag"
placeholder="添加标签"
onInput={this.shixunsskill}
@ -560,54 +670,59 @@ export default class TPMchallengesnew extends Component {
onPressEnter={this.clickshixunsskill}
onBlur={this.clickshixunsskill}
/>
{/*<a className="white-btn orange-btn fl mt1 use_scope-btn ml20 mt5 mr20"*/}
{/*onClick={this.clickshixunsskill}>+ 添加</a>*/}
<div className="ml15 color-grey-9 mt5">学员答题正确将获得技能否则不能获得技能</div>
<div className="ml15 color-grey-9 pt5 font-14">(回车添加标签)</div>
<div className="mt20 clearfix" id="task_tag_content">
{
shixunsskillvaluelist===undefined?"":shixunsskillvaluelist.length === 0 ? "" : shixunsskillvaluelist.map((itme, key) => {
return (
<li className="task_tag_span" key={key}><span>{itme}</span>
<a onClick={() => this.delshixunsskilllist(key)}>×</a>
</li>
<li key={key} className={"fl ml10 mr10"}>
<Badge className={"tpmpointer"} count={"x"} onClick={(key) => this.delshixunsskilllist(key)}>
<Button type="primary" ghost className={"Permanentban "}>
{itme}
</Button>
</Badge>
</li>
)
})
}
</div>
</div>
<span
className={shixunsskillvaluelisttype === true ? "color-orange mt7 fl ml20 block" : " color-orange mt7 fl ml20 none"}
id="stage_name_notice">
<i className="fa fa-exclamation-circle mr3"></i></span>
<div className={shixunsskillvaluelisttype === true ? "color-red ml10 mt5 block" : "none"}
id="stage_name_notice">必选项不能为空</div>
</div>
</div>
<div className="edu-back-white padding40-20 mb20">
<p className="color-grey-6 font-16 mb30">服务配置</p>
<div className="clearfix mb5">
<span className="color-orange pt10 fl">*</span>
<label className="panel-form-label fl">评测时限(S)</label>
<div className="pr fl with80 status_con">
<input value={this.state.exec_time} className="panel-box-sizing task-form-100 task-height-40" placeholder="请输入类别名称" onInput={this.setexec_time}/>
</div>
<span
className={this.state.shixunExec_timeType === true ? "color-orange mt8 fl block ml20" : "color-orange mt8 fl none"}
id="new_shixun_name"><i className="fa fa-exclamation-circle mr3"></i></span>
<div className="cl"></div>
</div>
</div>
<div className="clearfix mt30"
style={{display:this.props.identity>4||this.props.identity===undefined?"none":'block'}}
>
{checkpointId===undefined?<a className="defalutSubmitbtn fl mr20" onClick={CreatePracticesendtype===true?"":this.CreatePracticesend}>提交</a>:
<a className="defalutSubmitbtn fl mr20" onClick={editPracticesendtype===true?"":this.editPracticesend}>提交</a>}
<a href={go_back_url === undefined ? "" : go_back_url} className="defalutCancelbtn fl">取消</a>
</div>
{/*<div className="edu-back-white newpadding02020">*/}
{/* <p className="color-grey-6 font-16 mb20"> <span className="color-orange mr5 fl">*</span> 服务配置:评测时限(S)</p>*/}
{/* <div className="clearfix mb5 ml10">*/}
{/* <div className="pr status_con" id={"exec_timeid"}>*/}
{/* /!*<label className="panel-form-label fl"></label>*!/*/}
{/* <input value={this.state.exec_time}*/}
{/* className={this.state.shixunExec_timeType === true ?"panel-box-sizing task-form-100 task-height-40 bor-red":"panel-box-sizing task-form-100 task-height-40" }*/}
{/* placeholder="请输入类别名称" onInput={this.setexec_time}/>*/}
{/* </div>*/}
{/* <div*/}
{/* className={this.state.shixunExec_timeType === true ? "color-red mt8 block ml5" : " none"}*/}
{/* id="new_shixun_name">必填项:不能为空</div>*/}
{/* </div>*/}
{/*</div>*/}
</div>
{this.props.identity>4||this.props.identity===undefined?"":<div className="clearfix mt30"
// style={{display:this.props.identity>4||this.props.identity===undefined?"none":'block'}}
>
{/*{checkpointId===undefined?<a className="defalutSubmitbtn fl mr20" onClick={CreatePracticesendtype===true?"":this.CreatePracticesend}>提交</a>:*/}
{/*<a className="defalutSubmitbtn fl mr20" onClick={editPracticesendtype===true?"":this.editPracticesend}>提交</a>}*/}
{/*<a href={go_back_url === undefined ? "" : go_back_url} className="defalutCancelbtn fl">取消</a>*/}
{/*<Link to={go_back_url === undefined ? "" : go_back_url} className={"defalutCancelbtn fl"}>取消</Link>*/}
<Bottomsubmit url={go_back_url === undefined ? "" : go_back_url}
{...this.props}
{...this.state}
bottomvalue={"提交"}
onSubmits={checkpointId===undefined?()=>this.CreatePracticesend():()=>this.editPracticesend()}
loadings={CreatePracticesendtype===true?true:editPracticesendtype===true?true:false}/>
</div>}
</React.Fragment>
)
}

@ -1,97 +1,32 @@
import React, {Component} from 'react';
import {Input, Select, Radio, Checkbox, Popconfirm, message, Modal,Button,Icon,Tooltip} from 'antd';
import {Input, Select, Radio, Checkbox, Modal,Button,Tooltip} from 'antd';
import {BrowserRouter as Router, Route, Link, Switch} from "react-router-dom";
// import "antd/dist/antd.css";
import { Link} from "react-router-dom";
import axios from 'axios';
import { getImageUrl, toPath } from 'educoder';
import './css/TPMchallengesnew.css';
import Bottomsubmit from "../../modals/Bottomsubmit";
import {getUrl} from 'educoder';
import { getImageUrl } from 'educoder';
let origin = getUrl();
let path = getUrl("/editormd/lib/")
import './css/TPMchallengesnew.css';
const $ = window.$;
let timeout;
let currentValue;
const Option = Select.Option;
const RadioGroup = Radio.Group;
const { TextArea } = Input;
function create_editorMD(id, width, high, placeholder, imageUrl, callback) {
var editorName = window.editormd(id, {
width: width,
height: high,
path: path, // "/editormd/lib/"
syncScrolling: "single",
tex: true,
tocm: true,
emoji: true,
taskList: true,
codeFold: true,
searchReplace: true,
htmlDecode: "style,script,iframe",
sequenceDiagram: true,
autoFocus: false,
toolbarIcons: function () {
// Or return editormd.toolbarModes[name]; // full, simple, mini
// Using "||" set icons align right.
return ["bold", "italic", "|", "list-ul", "list-ol", "|", "code", "code-block", "|", "testIcon", "testIcon1", '|', "image", "table", '|', "watch", "clear"]
},
toolbarCustomIcons: {
testIcon: "<a type=\"inline\" class=\"latex\" ><div class='zbg'></div></a>",
testIcon1: "<a type=\"latex\" class=\"latex\" ><div class='zbg_latex'></div></a>"
},
//这个配置在simple.html中并没有但是为了能够提交表单使用这个配置可以让构造出来的HTML代码直接在第二个隐藏的textarea域中方便post提交表单。
saveHTMLToTextarea: true,
// 用于增加自定义工具栏的功能可以直接插入HTML标签不使用默认的元素创建图标
dialogMaskOpacity: 0.6,
placeholder: placeholder,
imageUpload: true,
imageFormats: ["jpg", "jpeg", "gif", "png", "bmp", "webp", "JPG", "JPEG", "GIF", "PNG", "BMP", "WEBP"],
imageUploadURL: imageUrl,//url
onload: function () {
// this.previewing();
$("#" + id + " [type=\"latex\"]").bind("click", function () {
editorName.cm.replaceSelection("```latex");
editorName.cm.replaceSelection("\n");
editorName.cm.replaceSelection("\n");
editorName.cm.replaceSelection("```");
var __Cursor = editorName.cm.getDoc().getCursor();
editorName.cm.setCursor(__Cursor.line - 1, 0);
});
$("#" + id + " [type=\"inline\"]").bind("click", function () {
editorName.cm.replaceSelection("`$$$$`");
var __Cursor = editorName.cm.getDoc().getCursor();
editorName.cm.setCursor(__Cursor.line, __Cursor.ch - 3);
editorName.cm.focus();
});
$("[type=\"inline\"]").attr("title", "行内公式");
$("[type=\"latex\"]").attr("title", "多行公式");
window.md_elocalStorage(editorName, `exercise__${id}`, "Memochallengesnew");
callback && callback()
}
});
return editorName;
function isNulltpm( str ){
if ( str == "" ) return true;
var regu = "^[ ]+$";
var re = new RegExp(regu);
return re.test(str);
}
export default class TPMevaluation extends Component {
constructor(props) {
super(props)
@ -127,39 +62,11 @@ export default class TPMevaluation extends Component {
scorevalue:false,
markvalue:true,
scoretype:undefined,
web_route:null
web_route:null,
exec_time:undefined
}
}
exerciseMD(initValue, id) {
this.contentChanged = false;
const placeholder = "";
// amp;
// 编辑时要传memoId
const imageUrl = `/api/attachments.json`;
// 创建editorMd
const exercise_editormd = create_editorMD(id, '100%', 400, placeholder, imageUrl, () => {
setTimeout(() => {
exercise_editormd.resize()
exercise_editormd.cm && exercise_editormd.cm.refresh()
}, 500)
if (initValue != undefined) {
exercise_editormd.setValue(initValue)
}
exercise_editormd.cm.on("change", (_cm, changeObj) => {
console.log('....contentChanged')
this.contentChanged = true;
})
});
this.exercise_editormd = exercise_editormd;
window.exercise_editormd = exercise_editormd;
}
componentDidMount() {
let id = this.props.match.params.shixunId;
let checkpointId=this.props.match.params.checkpointId;
@ -193,8 +100,7 @@ export default class TPMevaluation extends Component {
let newevaluationlist=[]
if(response.data.test_sets.length===0){
let newlist=[
{hidden:0,input:"",output:"",score:50},
{hidden:0,input:"",output:"",score:50}
{hidden:0,input:"",output:"",score:100},
]
newevaluationlist=newlist
}else{
@ -219,18 +125,16 @@ export default class TPMevaluation extends Component {
scorevalue:response.data.test_set_score,
markvalue:response.data.test_set_average,
web_route:response.data.web_route,
has_web_route:response.data.has_web_route
has_web_route:response.data.has_web_route,
responsedata:response.data,
exec_time:response.data.exec_time,
})
this.evaluationoninputvalueonload();
if(response.data.power===false){
this.props.showSnackbar("你没有权限修改");
}
if(response.data.answer===undefined){
this.answerMD("", "answerMD");
}else{
this.answerMD(response.data.answer, "answerMD");
this.props.showNotification("你没有权限修改");
}
}).catch((error) => {
console.log(error)
});
@ -379,34 +283,6 @@ export default class TPMevaluation extends Component {
}
// delesavegetfilepath=(value)=>{
// let {selectpatharr} = this.state
// let newarr =selectpatharr;
// let newselectpath="";
// for(var i=0; i<newarr.length;i++){
// if(newarr[i]===value){
//
// newarr.splice(i,1);
// console.log(newarr)
// console.log(value)
// }
// }
//
//
//
//
// for(var z=0; z<newarr.length;z++){
// newselectpath=newselectpath+newarr[z]+ ""
// }
// this.setState({
// selectpatharr:newarr,
// selectpath: newselectpath
// })
// }
savegetfilepath=(value)=>{
let {selectpath,saveshixunfilepath,pathtype} = this.state
@ -438,30 +314,6 @@ export default class TPMevaluation extends Component {
})
}
// let newarr =selectpatharr;
// let arrtype=false;
// let arrsum=0;
// let newselectpath="";
// newarr.push(value)
// if(newarr.length>1&&arrtype===false){
// for(var i=0; i<newarr.length;i++){
// if(newarr[i]===value){
// arrsum=arrsum+1;
// if(arrsum===2){
// newarr.splice(i,1);
// arrtype=true;
// }
// }
// }
// }
// for(var z=0; z<newarr.length;z++){
// newselectpath=newselectpath+newarr[z]+ ""
// }
}
evaluationenter=()=>{
@ -505,12 +357,6 @@ export default class TPMevaluation extends Component {
}else{
newtype=1;
}
// newevaluationlist[key].is_public=newtype;
// for(var i=0; i<newevaluationlist.length; i++){
// if(i===key){
//
// }
// }
newevaluationlist[key].hidden=newtype;
this.setState({
@ -597,7 +443,7 @@ export default class TPMevaluation extends Component {
$('textarea[autoHeight]').autoHeight();
}
submitarbitrationevaluation=()=>{
let{evaluationlist,shixunfilepath,shixunfilepathplay,shixunfileexpectpicturepath,shixunfilestandardpicturepath,shixunfilepicturepath,pathoptionvalue,scorevalue,markvalue,web_route}=this.state;
let{exec_time,evaluationlist,shixunfilepath,shixunfilepathplay,shixunfileexpectpicturepath,shixunfilestandardpicturepath,shixunfilepicturepath,pathoptionvalue,scorevalue,markvalue,web_route}=this.state;
let newscorevalue;
@ -610,7 +456,7 @@ export default class TPMevaluation extends Component {
let sum=0;
for(var i=0; i<evaluationlist.length; i++){
if(evaluationlist[i].score>100){
this.props.showSnackbar("测试集的评分占比不能大于100");
this.props.showNotification("测试集的评分占比不能大于100");
this.setState({
scoretype:i
})
@ -620,36 +466,52 @@ export default class TPMevaluation extends Component {
}
if(sum>100||sum<100){
this.props.showSnackbar("测试集的评分占比之和必须等于100");
this.props.showNotification("测试集的评分占比之和必须等于100");
return
}
}
if(exec_time===null||exec_time===undefined||exec_time === ""){
this.setState({
shixunExec_timeType:true,
})
this.props.scrollToAnchor("exec_timeid");
return
}
if (isNulltpm(exec_time)) {
this.props.showNotification("评测时长,请勿输入空格");
this.setState({
shixunExec_timeType:true,
})
this.props.scrollToAnchor("exec_timeid");
return
}
if(shixunfilepath===undefined||shixunfilepath===""||shixunfilepath===null){
this.props.showSnackbar("学员任务文件路径为空");
// this.props.showSnackbar("学员任务文件路径为空");
this.setState({
StudentTaskPapers:true
})
$('html').animate({
scrollTop: 120
}, 1000);
this.props.scrollToAnchor("Studenttaskfile");
return
}
if(shixunfilepathplay===undefined||shixunfilepathplay===""||shixunfilepathplay===null){
this.props.showSnackbar("评测执行文件路径为空");
// this.props.showSnackbar("评测执行文件路径为空");
this.setState({
StudentTaskDocs:true
})
$('html').animate({
scrollTop: 130
}, 1000);
this.props.scrollToAnchor("Benchmarkexecutable");
return
}
if(evaluationlist.length===0){
this.props.showSnackbar("测试集不能为空");
this.props.scrollToAnchor("Thetestset");
return
}
let id = this.props.match.params.shixunId;
@ -664,7 +526,8 @@ export default class TPMevaluation extends Component {
picture_path:pathoptionvalue===-1?undefined:shixunfilepicturepath===undefined?null:shixunfilepicturepath,
test_set_score:newscorevalue,
test_set_average:markvalue,
web_route:web_route===null?undefined:web_route
web_route:web_route===null?undefined:web_route,
exec_time:exec_time
}
axios.put(url,{
tab:1,
@ -672,7 +535,7 @@ export default class TPMevaluation extends Component {
test_set:evaluationlist
}
).then((response) => {
this.props.showSnackbar(response.data.messages);
this.props.showNotification(response.data.messages);
window.location.href=`/shixuns/${id}/challenges/${response.data.challenge_id}/tab=3`;
// if(response.data.status===1){
// window.location.href = "/shixuns/" + id + "/challenges/"+response.data.challenge_id+"/tab=3"
@ -681,16 +544,7 @@ export default class TPMevaluation extends Component {
console.log(error)
});
}
handpathoptionvalues=()=>{
this.setState({
handpathopt:true
})
}
handpathoptionvaluess=()=>{
this.setState({
handpathopt:false
})
}
saveselectpath=(e)=>{
this.setState({
@ -768,6 +622,24 @@ export default class TPMevaluation extends Component {
web_route:e.target.value
})
}
gotocheckpoint=(url)=>{
this.props.history.replace(url);
}
setexec_time=(e)=>{
if(e.target.value===null||e.target.value===undefined||e.target.value === ""||e.target.value.match(/^[ ]*$/)){
}else{
this.setState({
shixunExec_timeType:false,
})
}
this.setState({
exec_time:e.target.value
})
}
render() {
let {
@ -799,7 +671,8 @@ export default class TPMevaluation extends Component {
scorevalue,
markvalue,
scoretype,
has_web_route
has_web_route,
responsedata
} = this.state;
let tab1url="/shixuns/" + shixunId + "/challenges/"+checkpointId+"/editcheckpoint";
@ -812,64 +685,115 @@ export default class TPMevaluation extends Component {
lineHeight: '30px',
marginLeft: '20px',
};
return (
<React.Fragment>
<div className="educontent mt30 mb30">
<div className="padding10-20 mb10 edu-back-white clearfix">
<span className="fl ring-blue mr10 mt7">
<img src={getImageUrl("images/educoder/icon/code.svg")} data-tip-down="实训任务" className="fl mt2 ml2"/>
</span>
<span className="font-16 task-hide fl TPMtaskName">{position}</span>
<Link to={go_back_url === undefined ? "" : go_back_url}
className="color-grey-6 fr font-15 mt3">返回</Link>
{prev_challenge === undefined ? "" :
<a href={prev_challenge} className="fr color-blue mr15 mt4">上一关</a>
}
{next_challenge === undefined ? "" :
<a href={next_challenge} className="fr color-blue mr15 mt4">下一关</a>
}
<a href={practice_url === undefined ? "" : practice_url}
className="fr color-blue mr15 mt4"
style={{display:this.props.identity>4||this.props.identity===undefined||this.props.status===2||this.props.status===1? "none":'block'}}
data-tip-down="新增代码编辑类型的任务">+&nbsp;实践类型</a>
<a href={choice_url === undefined ? "" : choice_url}
className="fr color-blue mr15 mt4"
style={{display:this.props.identity>4||this.props.identity===undefined||this.props.status===2||this.props.status===1?"none":'block'}}
data-tip-down="新增选择题类型的任务">+&nbsp;选择题类型</a>
<div className="TPMchallengesnewtitles edu-back-white clearfix borderbottomf4">
<span className="font-16 task-hide fl TPMtaskName">{position}{responsedata&&responsedata.st === 0 ?"实践题":responsedata&&responsedata.st === 1?"选择题":""}</span>
{this.props.identity>4||this.props.identity===undefined||this.props.status===2||this.props.status===1?"":<a href={practice_url === undefined ? "" : practice_url} className="fr ml15 mt13">
<Button type="primary" className="edu-default-btn edu-greenback-btn "
>新增实践任务</Button></a>}
{this.props.identity>4||this.props.identity===undefined||this.props.status===2||this.props.status===1?"":<Link to={choice_url === undefined ? "" : choice_url}
className="fr ml15 mt13">
<Button type="primary"
className="edu-default-btn edu-greenback-btn mr5"
>新增选择题任务</Button></Link>}
{next_challenge===undefined?"":
<Button type="primary" ghost onClick={()=>this.gotocheckpoint(next_challenge)}
className="edu-default-btn edu-greenback-btn mr5 fr ml15 mt13"
>下一关</Button> }
{prev_challenge===undefined?"":
<Button type="primary" ghost onClick={()=>this.gotocheckpoint(prev_challenge)}
className="edu-default-btn edu-greenback-btn mr5 fr ml15 mt13"
>上一关</Button>}
</div>
<div className="challenge_nav clearfix edu-back-white">
<li>
<Link to={tab1url}>本关任务</Link>
<Link to={tab1url}>1本关任务 </Link>
</li>
{tab2url === "" ? "":<li> > </li>}
<li className="active">
<Link to={tab2url}>评测设置</Link>
<Link to={tab2url} className={"color-blue"}>2评测设置</Link>
</li>
{tab3url === "" ? "":<li> > </li>}
<li className="">
<Link to={tab3url}>参考答案</Link>
<Link to={tab3url}> 3参考答案</Link>
</li>
</div>
<p className="color-orange-tip font-12 padding20">
请先上传本关任务的所有代码文件标准图片等所有必要的文件到
<a href={"/shixuns/" + shixunId + "/repository"} className="color-bule-tip decoration" target="_blank">版本库</a>
<p className="color-orange-tip font-14 padding10 edu-back-white text-centers">
<div className={"bor25510211"}>
请先上传本关任务的所有代码文件标准图片等所有必要的文件到
<a href={"/shixuns/" + shixunId + "/repository"} className="color-bule-tip decoration" target="_blank">版本库</a>
</div>
</p>
<div className="edu-back-white newpadding02020" id={"exec_timeid"} >
<p className="color-grey-6 font-16 mb20"> <span className="color-red mr5 fl">*</span> <span className={"color-grey-8 font-14"}></span></p>
<div className="clearfix mb5">
<div className="pr status_con" style={{'width':'233px'}}>
<Input value={this.state.exec_time}
className={this.state.shixunExec_timeType === true ?"panel-box-sizing task-form-100 task-height-40 bor-red":"panel-box-sizing task-form-100 task-height-40" }
placeholder="请输入评测时长" onInput={this.setexec_time}/>
</div>
<div
className={this.state.shixunExec_timeType === true ? "color-red mt8 block ml5" : " none"}
id="new_shixun_name">必填项不能为空</div>
</div>
</div>
<div className="edu-back-white mb10 clearfix">
<div className="padding40-20">
<p className="color-grey-6 font-16 mb20">学员任务文件</p>
<div className="df">
<span className="mr30 color-orange pt10">*</span>
<div className="flex1 mr20">
<input type="text" className="input-100-45 greyInput change" id="shixun_file_path"
<div className="edu-back-white clearfix">
<div className="padding1020tpms mb10">
<p className="color-grey-6 font-16 mb20"><span className="color-red mr5 fl">*</span> <span className={"color-grey-8 font-14"}></span></p>
<div className="pr">
<Select className="winput-240-40"
value={pathoptionvalue}
onChange={this.handpathoptionvalue}>
<Option value={-1}></Option>
<Option value={1}>图片</Option>
<Option value={2}>apk/exe</Option>
<Option value={3}>txt</Option>
<Option value={4}>html</Option>
<Option value={5}>mp3</Option>
<Option value={6}>mp4</Option>
</Select>
<a className="ml10" onClick={()=>this.showrepositoryurltip(1)}><img src={getImageUrl("images/educoder/problem.png")}/></a>
<div className="invite-tip clearfix repository_url_tippostion" style={{display:showrepositoryurltiptype===true?"block":"none"}} id="repository_url_tip"
>
<span className="top-black-trangleft"></span>
<div className="padding20 invitecontent clearfix">
<p className="font-12 edu-txt-left">
图片处理或输出图片类型的任务请选填此项<br/>
可以通过设置图片路径和学员答案文件路径展示代码对应的图片效果<br/><br/>
apk/exe写可执行文件的任务请选填此项<br/>
可以通过设置学员答案文件路径展示二维码以供扫码下载<br/><br/>
txt输出txt文档类型的任务请选填此项<br/>
可以通过学员答案文件路径设置展示txt文件内容<br/><br/>
htmlweb类型的任务请选填此项<br/>
可以通过Web路由设置展示html效果预览页<br/><br/>
mp3/mp4mp3/mp4文件类型的任务请选填此项<br/>
可以通过学员答案文件路径设置展示mp3/mp4文件内容<br/><br/>
</p></div>
<p className="inviteTipbtn with100"><a onClick={()=>this.showrepositoryurltip(2)}
>知道了</a>
</p>
</div>
</div>
</div>
</div>
<div className="edu-back-white clearfix">
<div className="padding1020tpms mb10" id={"Studenttaskfile"}>
<p className="color-grey-6 font-16 mb20"><span className="color-red mr5 fl">*</span> <span className={"color-grey-8 font-14"}></span></p>
<div>
<div className="flex1">
<input type="text"
className={StudentTaskPapers===true?"input-100-45 greyInput change bor-red":"input-100-45 greyInput change"}
id="shixun_file_path"
name="challenge[path]" autoComplete="off"
placeholder="请选择版本库中的代码文件。例: src/step1/HelloWorld.java"
value={shixunfilepath}
@ -877,15 +801,16 @@ export default class TPMevaluation extends Component {
onInput={(e)=>this.updatepath(e,"shixunfilepath",1)}
onClick={(e)=>this.getfilepath(e,"shixunfilepath",1)}
/>
<p className="color-grey-9 mt15">该文件将直接显示给学生需要学生在其中填写代码</p>
</div>
<div style={{width: '57px'}}>
<span className={StudentTaskPapers===true?"color-orange mt8 fl":"color-orange mt8 fl none"} id="student_task_name"><i
className="fa fa-exclamation-circle mr3"></i></span>
<div>
<span className={StudentTaskPapers===true?"color-red mt8 fl":" none"} id="student_task_name"> 必选项不能为空</span>
</div>
</div>
</div>
</div>
<Modal
keyboard={false}
title="文件路径"
@ -914,9 +839,6 @@ export default class TPMevaluation extends Component {
{path+item.name}</a>:<a data-remote="true">
<i className="iconfont icon-zuoye color-blue mr2"></i>
<span onClick={()=>this.savegetfilepath(path+item.name,item.type)}>{path+item.name}</span>
{/*<Tooltip placement="bottom" title={"点击删除下方所选文件路径"}>*/}
{/*<Icon className={"fr mt4"} type="close-circle" onClick={()=>this.delesavegetfilepath(path+item.name)}/>*/}
{/*</Tooltip>*/}
</a>
}
</div>
@ -942,13 +864,12 @@ export default class TPMevaluation extends Component {
</div>
</Modal>
<div className="edu-back-white mb10 clearfix">
<div className="padding40-20">
<p className="color-grey-6 font-16 mb20">评测执行文件</p>
<div className="df">
<span className="mr30 color-orange pt10">*</span>
<div className="flex1 mr20">
<input type="text" className="input-100-45 greyInput" id="shixun_file_path_play"
<div className="edu-back-white clearfix">
<div className="padding1020tpms mb10" id={"Benchmarkexecutable"}>
<p className="color-grey-6 font-16 mb20"><span className="color-red mr5 fl">*</span><span className={"color-grey-8 font-14"}>使</span></p>
<div>
<div className="flex1">
<input type="text" className={StudentTaskDocs===true?"bor-red input-100-45 greyInput":"input-100-45 greyInput"} id="shixun_file_path_play"
name="challenge[exec_path]" autoComplete="off"
placeholder="请选择版本库中的代码文件。例src/step1/HelloWorldTest.java"
value={shixunfilepathplay}
@ -956,59 +877,19 @@ export default class TPMevaluation extends Component {
onInput={(e)=>this.updatepath(e,"shixunfilepathplay",1)}
onClick={(e)=>this.getfilepath(e,"shixunfilepathplay",1)}
/>
<p className="color-grey-9 mt15">该文件由平台执行用来测试平台学员代码是否正确</p>
</div>
<div style={{width: '57px'}}>
<span className={StudentTaskDocs===true?"color-orange mt8 fl":"color-orange mt8 fl none"} id="student_task_name"><i
className="fa fa-exclamation-circle mr3"></i></span>
</div>
</div>
</div>
</div>
<div className="edu-back-white mb10 clearfix">
<div className="padding40-20">
<p className="color-grey-6 font-16 mb20">效果展现方式</p>
<div className="pr">
<Select className="winput-240-40"
value={pathoptionvalue}
onChange={this.handpathoptionvalue}>
<Option value={-1}>请选择效果展现方式</Option>
<Option value={1}>图片</Option>
<Option value={2}>apk/exe</Option>
<Option value={3}>txt</Option>
<Option value={4}>html</Option>
<Option value={5}>mp3</Option>
<Option value={6}>mp4</Option>
</Select>
<a className="ml10" onClick={()=>this.showrepositoryurltip(1)}><img src={getImageUrl("images/educoder/problem.png")}/></a>
<div className="invite-tip clearfix repository_url_tippostion" style={{display:showrepositoryurltiptype===true?"block":"none"}} id="repository_url_tip"
>
<span className="top-black-trangleft"></span>
<div className="padding20 invitecontent clearfix">
<p className="font-12 edu-txt-left">
图片处理或输出图片类型的任务请选填此项<br/>
可以通过设置图片路径和学员答案文件路径展示代码对应的图片效果<br/><br/>
apk/exe写可执行文件的任务请选填此项<br/>
可以通过设置学员答案文件路径展示二维码以供扫码下载<br/><br/>
txt输出txt文档类型的任务请选填此项<br/>
可以通过学员答案文件路径设置展示txt文件内容<br/><br/>
htmlweb类型的任务请选填此项<br/>
可以通过Web路由设置展示html效果预览页
</p></div>
<p className="inviteTipbtn with100"><a onClick={()=>this.showrepositoryurltip(2)}
>知道了</a>
</p>
<div>
<span className={StudentTaskDocs===true?"color-red mt8 fl":"none"} id="student_task_name">
必选项不能为空
</span>
</div>
</div>
<p className="color-grey-9 mt15">该选项用来配置学员评测本关任务时查看效果页上需要展现的文件类型</p>
</div>
</div>
{pathoptionvalue===4&&web_route!=null||pathoptionvalue===4&&has_web_route===true?<div className="edu-back-white mb10 clearfix">
<div className="padding40-20">
<p className="color-grey-6 font-16 mb20">Web路由</p>
{pathoptionvalue===4&&web_route!=null||pathoptionvalue===4&&has_web_route===true?<div className="edu-back-white clearfix">
<div className="padding1020tpms mb10">
<p className="color-grey-6 font-16 mb20">Web路由<span className={"color-grey-8 font-14"}>请注意将服务器程序的端口号映射到8080端口</span></p>
<div className="df">
<div className="flex1 mr20">
<input type="text" className="input-100-45 change" autoComplete="off"
@ -1021,9 +902,9 @@ export default class TPMevaluation extends Component {
</div>
</div>:""}
{pathoptionvalue===1||pathoptionvalue===5||pathoptionvalue===6?<div className="edu-back-white mb10 clearfix">
<div className="padding40-20">
<p className="color-grey-6 font-16 mb20">待处理文件路径</p>
{pathoptionvalue===1||pathoptionvalue===5||pathoptionvalue===6?<div className="edu-back-white clearfix">
<div className="padding1020tpms mb10">
<p className="color-grey-6 font-16 mb20">待处理文件路径<span className={"color-grey-8 font-14"}>该路径下的文件将在学员评测本关任务时作为原始文件显示在查看效果页供学员参考请注意与程序文件所在文件夹分开</span></p>
<div className="df">
<div className="flex1 mr20">
<input type="text" className="input-100-45" autoComplete="off"
@ -1033,9 +914,6 @@ export default class TPMevaluation extends Component {
onInput={(e)=>this.updatepath(e,"shixunfileexpectpicturepath",2)}
onClick={(e)=>this.getfilepath(e,"shixunfileexpectpicturepath",2)}
/>
<p className="color-grey-9 mt15">
该路径下的文件将在学员评测本关任务时作为原始文件显示在查看效果页供学员参考任务为文件处理时请指定该路径并注意与程序文件所在文件夹分开
</p>
</div>
<div></div>
</div>
@ -1043,9 +921,9 @@ export default class TPMevaluation extends Component {
</div>:""}
{pathoptionvalue===1||pathoptionvalue===5||pathoptionvalue===6? <div className="edu-back-white mb10 clearfix">
<div className="padding40-20">
<p className="color-grey-6 font-16 mb20">标准答案文件路径</p>
{pathoptionvalue===1||pathoptionvalue===5||pathoptionvalue===6? <div className="edu-back-white clearfix">
<div className="padding1020tpms mb10">
<p className="color-grey-6 font-16 mb20">标准答案文件路径<span className={"color-grey-8 font-14"}>该路径下的文件将在学员评测本关任务时作为参考答案显示在查看效果页供学员参考请注意与程序文件所在文件夹分开</span></p>
<div className="df">
<div className="flex1 mr20">
<input type="text" className="input-100-45" autoComplete="off"
@ -1055,9 +933,6 @@ export default class TPMevaluation extends Component {
onInput={(e)=>this.updatepath(e,"shixunfilestandardpicturepath",2)}
onClick={(e)=>this.getfilepath(e,"shixunfilestandardpicturepath",2)}
/>
<p className="color-grey-9 mt15">
该路径下的文件将在学员评测本关任务时作为参考答案显示在查看效果页供学员参考任务输出结果为文件时请指定该路径并注意与程序文件所在文件夹分开
</p>
</div>
<div></div>
</div>
@ -1065,9 +940,9 @@ export default class TPMevaluation extends Component {
</div>:""}
{pathoptionvalue===-1?"":<div className="edu-back-white mb10 clearfix">
<div className="padding40-20">
<p className="color-grey-6 font-16 mb20">学员答案文件路径</p>
{pathoptionvalue===-1?"":<div className="edu-back-white clearfix">
<div className="padding1020tpms mb10">
<p className="color-grey-6 font-16 mb20">学员答案文件路径<span className={"color-grey-8 font-14"}>学员评测本关任务时生成的文件将保存在该路径下并作为实际输出显示在查看效果页供学员确认请注意与程序文件所在文件夹分开</span></p>
<div className="df">
<div className="flex1 mr20">
<input type="text" className="input-100-45 change" autoComplete="off"
@ -1076,9 +951,6 @@ export default class TPMevaluation extends Component {
onInput={(e)=>this.updatepath(e,"shixunfilepicturepath",2)}
onClick={(e)=>this.getfilepath(e,"shixunfilepicturepath",2)}
placeholder="请在版本库中指定用来保存学员代码实际输出结果的路径。例src/step1/outputfiles"/>
<p className="color-grey-9 mt15">
学员评测本关任务时生成的文件将保存在该路径下并作为实际输出显示在查看效果页供学员确认任务输出结果为文件时请指定该路径并注意与程序文件所在文件夹分开
</p>
</div>
<div></div>
</div>
@ -1086,10 +958,10 @@ export default class TPMevaluation extends Component {
</div>}
<div className="edu-back-white mb10 clearfix">
<div className="padding40-20">
<div className="edu-back-white clearfix" id={"Thetestset"}>
<div className="padding1020tpms mb20">
{/*<p className="color-grey-6 font-16">测试集</p>*/}
<p className="color-grey-6 font-16">测试集和系统评分规则</p>
<p className="color-grey-6 font-16 height40pxtpm borbottomeeetpm">测试集和系统评分规则</p>
<p className="color-grey-9 mt20"
style={{width:'100%',height:'60px'}}
>
@ -1132,9 +1004,9 @@ export default class TPMevaluation extends Component {
{evaluationlist===undefined?"":evaluationlist.length===0?"":evaluationlist.map((item,key)=>{
return(
<div className="test_array_item mt30" key={key}>
<div className="test_array_item mt30 borbottomeeetpm pb20" key={key}>
<p className="clearfix pr mb20">
<span className="fl mt5 mr10 color-orange">*</span>
<span className="fl mr10 color-red">*</span>
<span className="color-blue font-16 fl" name="sample_inputs_label">{key+1}</span>
<span className="fl ml20 color-grey-6">
{/*checked={item.is_public===1?false:true}*/}
@ -1143,19 +1015,19 @@ export default class TPMevaluation extends Component {
style={{width: '25%',display:scorevalue===true?'inline-block':'none'}}
onInput={(e)=>this.editpercentage(e,key)}
value={item.score} />
<span className="mr15"
<span className="mr15 ml10"
style={{display:scorevalue===true?'inline-block':'none'}}
>%</span>
<Checkbox onChange={()=>this.evaluationonChange(item.hidden,key)} checked={item.hidden===1?true:false}>隐藏</Checkbox>
<Checkbox onChange={()=>this.evaluationonChange(item.hidden,key)} checked={item.hidden===1?true:false}>隐藏<span className={"color-grey-8 font-14"}>选中则对学员隐藏本测试集内容</span></Checkbox>
</span>
<Tooltip placement="bottom" title={"删除"}>
<a className="fr del_array sample_icon_remove mr30" style={{display:key===0?"none":"block"}}
<div className="fr sample_icon_remove " style={{display:key===0?"none":"block"}}
onClick={()=>this.del_test_array(key)}>
<i className="fa fa-times-circle color-grey-c font-16 fl"></i>
</a>
<i className={"iconfont icon-shanchu_Hover font-16 fl"}></i>
</div>
</Tooltip>
</p>
<TextArea className="textareavalue mb15" name="test_set[input][]"
@ -1174,11 +1046,11 @@ export default class TPMevaluation extends Component {
rows={5}
onInput={(e)=>this.evaluationoninputvalue(e,key,"yq")}
></TextArea>
<div className="clearfix lineh-30">
<div className="clearfix lineh-30 mt20">
<span className="fl mr10 color-grey-6">匹配规则</span>
<RadioGroup className="fl" value={item.match_rule} onChange={(e)=>this.changeEvaluationRule(e,key)}>
<Radio value='full'>完全匹配</Radio>
<Radio value='last'>末尾匹配</Radio>
<Radio value='full'>完全匹配<span className={"color-grey-8 font-14"}>实际输出与预期输出完全相同</span></Radio>
<Radio value='last'>末尾匹配<span className={"color-grey-8 font-14"}>实际输出的末尾内容与预期输出完全相同</span></Radio>
</RadioGroup>
</div>
</div>
@ -1189,23 +1061,28 @@ export default class TPMevaluation extends Component {
</div>
<p className="clearfix" onClick={this.addevaluationon}>
<a className="fl edu-default-btn edu-greyline-btn mt20 mb20 sample_icon_add">
新增测试集
</a>
<Button type="primary" ghost className="edu-default-btn edu-greenback-btn mt20 mb20">新增测试集</Button>
</p>
<p className="color-grey-9">温馨提示建议公开测试集和隐藏测试集结合使用降低作弊的几率隐藏测试集提交评测时也将被自动检测</p>
<p className="color-grey-9">温馨提示公开测试集和隐藏测试集结合使用可以降低作弊的几率隐藏测试集提交评测时也将被系统自动检测</p>
</div>
</div>
</div>
<div className="clearfix mt30" style={{display:this.props.identity>4||this.props.identity===undefined||power===false?"none":"block"}}>
<a className="defalutSubmitbtn fl mr20" onClick={this.submitarbitrationevaluation}>提交</a>
<a href={"/shixuns/" + shixunId + "/challenges"} className="defalutCancelbtn fl">取消</a>
</div>
</div>
{this.props.identity>4||this.props.identity===undefined||power===false?"":<div className="clearfix mt30">
{/*<a className="defalutSubmitbtn fl mr20" onClick={this.submitarbitrationevaluation}>提交</a>*/}
{/*/!*<a href={"/shixuns/" + shixunId + "/challenges"} className="defalutCancelbtn fl">取消</a>*!/*/}
{/*<Link to={"/shixuns/" + shixunId + "/challenges"} className="defalutCancelbtn fl">取消</Link>*/}
<Bottomsubmit url={"/shixuns/" + shixunId + "/challenges"}
bottomvalue={"提交"}
onSubmits={this.submitarbitrationevaluation}
{...this.props}
{...this.state}
loadings={false}
/>
</div>}
</React.Fragment>
)
}

@ -212,9 +212,9 @@ export default class TpmQuestionEdit extends Component {
<div className="clearfix mt30" style={{display:this.props.identity>4||this.props.identity===undefined||this.props.power===false?"none":"block"}}>
<a className="defalutSubmitbtn fl mr20"
onClick={()=>this.props.answer_subit()}>提交</a>
<a href={this.props.go_back_url}
className="defalutCancelbtn fl">取消</a>
{/*<a href={this.props.go_back_url}*/}
{/* className="defalutCancelbtn fl">取消</a>*/}
<Link to={this.props.go_back_url} className="defalutCancelbtn fl">取消</Link>
<a onClick={()=>this.delecbtns()}
className="delectshixuncdbtn fr">删除</a>
</div>

@ -69,9 +69,9 @@ export default class TpmQuestionMain extends Component {
style={{display: this.props.identity > 4 || this.props.identity === undefined || this.props.power === false ? "none" : "block"}}>
<a className="defalutSubmitbtn fl mr20"
onClick={this.props.sumittype === true ? "" : this.props.clickquestionsumit}>提交</a>
<a href={this.props.go_back_url}
className="defalutCancelbtn fl">取消</a>
{/*<a href={this.props.go_back_url}*/}
{/* className="defalutCancelbtn fl">取消</a>*/}
<Link to={this.props.go_back_url} className="defalutCancelbtn fl">取消</Link>
</div>
</div>

@ -205,8 +205,10 @@ export default class TpmQuestionNew extends Component {
<div className="clearfix mt30" style={{display:this.props.identity>4||this.props.identity===undefined||this.props.power===false?"none":"block"}}>
<a className="defalutSubmitbtn fl mr20"
onClick={this.props.answer_subit}>提交</a>
<a href={this.props.go_back_url}
className="defalutCancelbtn fl">取消</a>
<Link to={this.props.go_back_url}
className="defalutCancelbtn fl">取消</Link>
{/*<a href={this.props.go_back_url}*/}
{/* className="defalutCancelbtn fl">取消</a>*/}
</div>
</div>

@ -0,0 +1,55 @@
import React, {Component} from 'react';
import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
import Loadable from 'react-loadable';
import Loading from "../../../../Loading";
import Bottomsubmit from "../../../modals/Bottomsubmit";
const TPMchallengestask = Loadable({
loader: () => import('../../challengesnew/TPMchallengesnew'),
loading: Loading,
})
export default class TpmTaskIndex extends Component {
constructor(props) {
super(props)
this.state = {
}
}
componentDidMount() {
}
render() {
// console.log(a.indexOf("vnc"))
// console.log(b.indexOf("vnc"))
return (
<div>
<Switch {...this.props}>
{/*新建关卡*/}
<Route path="/shixuns/:shixunId/challenges/new" render={
(props) => (<TPMchallengestask {...this.props} {...props} {...this.state}/>)
}></Route>
{/*编辑关卡*/}
<Route path="/shixuns/:shixunId/challenges/:checkpointId/editcheckpoint" render={
(props) => (<TPMchallengestask {...this.props} {...props} {...this.state} />)
}></Route>
</Switch>
</div>
);
}
}

@ -266,4 +266,66 @@ a{
height: 32px;
line-height: 20px;
font-family: "微软雅黑","宋体";
}
.borderbottomf4{
border-bottom:1px solid #F4F4F4;
}
.TPMchallengesnewtitles{
height: 76px;
line-height: 56px;
padding: 10px 20px;
}
.newpadding1020{
padding: 20px 20px 20px;
box-sizing: border-box;
}
.newpadding02020{
padding: 0px 20px 20px;
}
.mb10 {
margin-bottom: 10px !important;
}
.tpmpointer{
cursor: pointer;
}
.text-centers{text-align:center}
.bor25510211{
width: 1180px;
height: 34px;
border: 1px solid rgba(255,102,1,1);
line-height: 34px;
}
.padding1020tpms{
padding: 10px 20px;
box-sizing: border-box;
}
.bortopeeetpm{
border-top: 1px solid #eee;
}
.borbottomeeetpm {
border-bottom: 1px solid #eee;
}
.height40pxtpm{
height:40px
}
.ml41{
margin-left: 41px;
}
.wind500height45{
width: 500px;
height: 45px;
}
.newaddswermargin{
margin: 0 auto;
}

@ -10,7 +10,7 @@ import { getImageUrl, toPath, getUrl } from 'educoder';
import axios from 'axios';
import './css/TPMchallengesnew.css';
import '../css/TPMchallengesnew.css';
let origin = getUrl();
@ -355,7 +355,8 @@ export default class TPManswer extends Component {
<div className="clearfix mt20" style={{display:this.props.identity>4||this.props.identity===undefined||power===false?"none":"block"}}>
<a className="defalutSubmitbtn fl mr20"
onClick={this.challenge_answer_submit}>提交</a>
<a href={"/shixuns/" + shixunId + "/challenges"} className="defalutCancelbtn fl">取消</a>
{/*<a href={"/shixuns/" + shixunId + "/challenges"} className="defalutCancelbtn fl">取消</a>*/}
<Link to={"/shixuns/" + shixunId + "/challenges"} className={"defalutCancelbtn fl"}>取消</Link>
</div>
</div>
</React.Fragment>

@ -0,0 +1,617 @@
import React, {Component} from 'react';
import {Input, Select, Radio, Checkbox, Popconfirm, message, Modal} from 'antd';
import {BrowserRouter as Router, Route, Link, Switch} from "react-router-dom";
// import "antd/dist/antd.css";
import TPMMDEditor from '../TPMMDEditor';
import axios from 'axios';
import '../css/TPMchallengesnew.css';
import { getImageUrl, toPath } from 'educoder';
import {getUrl} from 'educoder';
let origin = getUrl();
let path = getUrl("/editormd/lib/")
const $ = window.$;
let timeout;
let currentValue;
const Option = Select.Option;
const RadioGroup = Radio.Group;
export default class TPMchallengesnew extends Component {
constructor(props) {
super(props)
this.exercisememoMDRef=React.createRef();
this.state = {
choice_url: undefined,
practice_url: undefined,
go_back_url: undefined,
task_pass_default: undefined,
submit_url: undefined,
shixunCreatePracticeGroup: 1,
optionsums:[100,200],
activetype:0,
setopen: false,
shixunCreatePractice: undefined,
onshixunsmarkvalue: 100,
shixunsskillvalue: undefined,
shixunsskillvaluelist: [],
tab2url: "",
tab3url: "",
prev_challenge:undefined,
next_challenge:undefined,
power: false,
shixunCreatePracticetype: false,
shixunsskillvaluelisttype: false,
marktype:false,
editPracticesendtype:false,
CreatePracticesendtype:false,
exec_time:20,
shixunExec_timeType:false
}
}
componentDidMount() {
let id = this.props.match.params.shixunId;
let checkpointId=this.props.match.params.checkpointId;
let newchoice_url= "/shixuns/"+id+"/challenges/newquestion";
let newpractice_url= "/shixuns/"+id+"/challenges/new";
let newgo_back_url="/shixuns/"+id+"/challenges"
if(checkpointId===undefined){
//新建模式
let url = "/shixuns/" + id + "/challenges/new.json"
axios.get(url).then((response) => {
this.setState({
choice_url: newchoice_url,
practice_url: newpractice_url,
go_back_url: newgo_back_url,
position: response.data.position,
task_pass_default: response.data.task_pass_default,
submit_url: response.data.submit_url,
checkpointId:checkpointId,
exercisememoMDRefval:response.data.task_pass_default
})
this.exercisememoMDRef.current.setValue(response.data.task_pass_default||'')
}).catch((error) => {
console.log(error)
});
}else{
//编辑模式
let url="/shixuns/"+id+"/challenges/"+checkpointId+".json?tab=0";
axios.get(url).then((response) => {
let optionsum;
if(response.data.difficulty===1){
optionsum=[100,200];
}else if(response.data.difficulty===2){
optionsum=[300,400,500,600];
}else if(response.data.difficulty===3){
optionsum=[700,800,900,1000]
}
let newprev_challenge=response.data.prev_challenge;
let next_challenge=response.data.next_challenge;
if (newprev_challenge != undefined) {
if(newprev_challenge.st===0){
newprev_challenge = "/shixuns/" + id + "/challenges/" + newprev_challenge.id + "/editcheckpoint";
}else{
newprev_challenge = "/shixuns/" + id + "/challenges/" + newprev_challenge.id + "/editquestion";
}
}
if (next_challenge != undefined) {
if(next_challenge.st===0){
next_challenge = "/shixuns/" + id + "/challenges/" + next_challenge.id+ "/editcheckpoint";
}else{
next_challenge = "/shixuns/" + id + "/challenges/" + next_challenge.id+ "/editquestion";
}
}
this.setState({
power: response.data.power,
prev_challenge:newprev_challenge,
next_challenge:next_challenge,
choice_url: newchoice_url,
practice_url: newpractice_url,
go_back_url: newgo_back_url,
shixunCreatePractice:response.data.subject,
position:response.data.position,
shixunCreatePracticeGroup:response.data.difficulty,
optionsums:optionsum,
onshixunsmarkvalue:response.data.score,
shixunsskillvaluelist:response.data.tags,
checkpointId:checkpointId,
exec_time:response.data.exec_time,
tab2url: "/shixuns/" + id + "/challenges/"+checkpointId+"/tab=2",
tab3url: "/shixuns/" + id + "/challenges/"+checkpointId+"/tab=3",
exercisememoMDRefval:response.data.task_pass
})
if(response.data.power===false){
this.props.showSnackbar("你没有权限修改");
}
this.exercisememoMDRef.current.setValue(response.data.task_pass||'')
}).catch((error) => {
console.log(error)
});
}
}
onshixunCreatePracticeChange = (e) => {
let optionsum;
let onshixunsmark;
if(e.target.value===1){
optionsum=[100,200];
onshixunsmark=100;
}else if(e.target.value===2){
optionsum=[300,400,500,600];
onshixunsmark=300;
}else if(e.target.value===3){
optionsum=[700,800,900,1000]
onshixunsmark=700;
}
this.setState({
shixunCreatePracticeGroup: e.target.value,
optionsums:optionsum,
onshixunsmarkvalue:onshixunsmark
})
}
shixunCreatePractice = (e) => {
this.setState({
shixunCreatePractice: e.target.value
})
}
CreatePracticesend = () => {
this.setState({
CreatePracticesendtype:true
})
if(this.props.status===2){
this.props.showSnackbar("该实训已经发布不能新建")
this.setState({
CreatePracticesendtype:false
})
return
}
let {shixunCreatePractice, shixunCreatePracticeGroup, onshixunsmarkvalue, shixunsskillvaluelist,exec_time} = this.state;
if (shixunCreatePractice === undefined||shixunCreatePractice=="") {
this.setState({
shixunCreatePracticetype: true
})
this.props.showSnackbar("任务名称为空")
$('html').animate({
scrollTop: 10
}, 1000);
this.setState({
CreatePracticesendtype:false
})
return
}
if (shixunsskillvaluelist.length === 0) {
this.setState({
shixunsskillvaluelisttype: true,
CreatePracticesendtype:false
})
this.props.showSnackbar("技能标签为空")
return
}
if(exec_time===null||exec_time===undefined||exec_time===""){
this.setState({
shixunExec_timeType:false
})
return
}
const exercise_editormdvalue = this.exercisememoMDRef.current.getValue().trim();
let id = this.props.match.params.shixunId;
let url = "/shixuns/" + id + "/challenges.json";
axios.post(url, {
identifier:id,
subject: shixunCreatePractice,
task_pass: exercise_editormdvalue,
difficulty: shixunCreatePracticeGroup,
score: onshixunsmarkvalue,
challenge_tag: shixunsskillvaluelist,
st: 0,
exec_time:exec_time
}).then((response) => {
if (response.data.status === 1) {
// $("html").animate({ scrollTop: 0 })
//window.location.href=`/shixuns/${id}/challenges/${response.data.challenge_id}/editcheckpoint?tab=2`;
window.location.href=`/shixuns/${id}/challenges/${response.data.challenge_id}/tab=2`;
// this.setState({
// setopen: true,
// CreatePracticesendtype:false,
// tab2url: "/shixuns/" + id + "/challenges/"+response.data.challenge_id+"/tab=2",
// tab3url: "/shixuns/" + id + "/challenges/"+response.data.challenge_id+"/tab=3",
// })
}
// this.props.showSnackbar(response.data.messages);
}).catch((error) => {
console.log(error)
});
}
onshixunsmark = (value) => {
this.setState({
onshixunsmarkvalue: value
})
}
shixunsskill = (e) => {
this.setState({
shixunsskillvalue: e.target.value
})
}
clickshixunsskill = () => {
let {shixunsskillvalue, shixunsskillvaluelist} = this.state;
if (shixunsskillvalue === "") {
return
} else if (shixunsskillvalue === undefined) {
return
}
if(shixunsskillvalue == "" || shixunsskillvalue == undefined || shixunsskillvalue == null || (shixunsskillvalue.length>0 && shixunsskillvalue.trim().length == 0)){
message.error("输入为空,不能保存!");
return
}
let list = shixunsskillvaluelist;
list.push(shixunsskillvalue);
this.setState({
shixunsskillvaluelist: list,
shixunsskillvalue: ""
})
}
delshixunsskilllist = (key) => {
let {shixunsskillvaluelist} = this.state;
let newshixunsskillvaluelist = shixunsskillvaluelist;
newshixunsskillvaluelist.splice(key, 1);
this.setState({
shixunsskillvaluelist: newshixunsskillvaluelist
})
}
editPracticesend=()=>{
this.setState({
editPracticesendtype:true
})
let {shixunCreatePractice, shixunCreatePracticeGroup, onshixunsmarkvalue, shixunsskillvaluelist,checkpointId,exec_time} = this.state;
const exercise_editormdvalue = this.exercisememoMDRef.current.getValue().trim();
let id = this.props.match.params.shixunId;
let url = "/shixuns/"+id+"/challenges/"+checkpointId+".json";
if (shixunCreatePractice === undefined||shixunCreatePractice=="") {
// this.setState({
// shixunCreatePracticetype: true
// })
this.props.showSnackbar("任务名称为空")
$('html').animate({
scrollTop: 10
}, 1000);
this.setState({
editPracticesendtype:false
})
return
}
if (shixunsskillvaluelist.length === 0) {
// this.setState({
// shixunsskillvaluelisttype: true
// })
this.props.showSnackbar("技能标签为空")
this.setState({
editPracticesendtype:false
})
return
}
if(exec_time===null||exec_time===undefined||exec_time===""){
this.setState({
shixunExec_timeType:false
})
return
}
axios.put(url, {
tab:0,
identifier:id,
id:checkpointId,
challenge:{
subject: shixunCreatePractice,
task_pass: exercise_editormdvalue,
difficulty: shixunCreatePracticeGroup,
score: onshixunsmarkvalue,
exec_time:exec_time
},
challenge_tag:shixunsskillvaluelist
}).then((response) => {
this.props.showSnackbar(response.data.messages);
if (response.data.status === 1) {
window.location.href=`/shixuns/${id}/challenges/${checkpointId}/tab=2`;
this.setState({
setopen: true,
editPracticesendtype:false,
tab2url: "/shixuns/" + id + "/challenges/"+checkpointId+"/tab=2",
tab3url: "/shixuns/" + id + "/challenges/"+checkpointId+"/tab=3",
})
// window.location.href = "/shixuns/" + id + "/challenges/"+response.data.challenge_id+"/tab=2"
}
}).catch((error) => {
console.log(error)
});
}
onshixunsmarks=()=> {
this.setState({
marktype:true
})
}
onshixunsmarkss=()=> {
this.setState({
marktype:false
})
}
setexec_time=(e)=>{
this.setState({
exec_time:e.target.value
})
}
render() {
let shixuntype = this.props.match.params.type;
let {marktype,
shixunCreatePracticetype, shixunsskillvaluelisttype,
choice_url, practice_url, go_back_url, position, task_pass_default, submit_url, setopen,checkpointId,prev_challenge,next_challenge,power,
shixunCreatePractice, shixunCreatePracticeGroup, onshixunsmarkvalue, shixunsskillvalue, shixunsskillvaluelist, tab2url, tab3url,optionsums,
CreatePracticesendtype,editPracticesendtype
} = this.state;
let options;
if(optionsums!=undefined){
options = optionsums.map((d, k) => {
return (
<Option key={d} id={k}>{d}</Option>
)
})
}
return (
<React.Fragment>
<div className="educontent mt30 mb30">
<div className="padding10-20 mb10 edu-back-white clearfix">
<span className="fl ring-blue mr10 mt7">
<img src={getImageUrl("images/educoder/icon/code.svg")} data-tip-down="实训任务" className="fl mt2 ml2"/>
</span>
<span className="font-16 task-hide fl TPMtaskName">{position}</span>
<Link to={go_back_url === undefined ? "" : go_back_url}
className="color-grey-6 fr font-15 mt3">返回</Link>
{ next_challenge===undefined?"":
<a href={next_challenge}className="fr color-blue mr15 mt4">下一关</a>
}
{ prev_challenge===undefined?"":
<a href={prev_challenge} className="fr color-blue mr15 mt4">上一关</a>
}
<a href={practice_url === undefined ? "" : practice_url}
className="fr color-blue mr15 mt4"
style={{display:this.props.identity>4||this.props.identity===undefined||this.props.status===2||this.props.status===1?"none":'block'}}
data-tip-down="新增代码编辑类型的任务">+&nbsp;实践类型</a>
<a href={choice_url === undefined ? "" : choice_url}
className="fr color-blue mr15 mt4"
style={{display:this.props.identity>4||this.props.identity===undefined||this.props.status===2||this.props.status===1?"none":'block'}}
data-tip-down="新增选择题类型的任务">+&nbsp;选择题类型</a>
</div>
<div className="challenge_nav clearfix edu-back-white">
<li className="active">
<a>本关任务</a>
</li>
<li className="">
{tab2url === "" ? <span>评测设置</span> : <Link to={tab2url}></Link>}
</li>
<li className="">
{tab3url === "" ? <span>参考答案</span> : <Link to={tab3url}></Link>}
</li>
</div>
<div className="edu-back-white mb10 clearfix">
<div className="padding40-20">
<p className="color-grey-6 font-16 mb30">任务名称</p>
<div className="df">
<span className="mr30 color-orange pt10">*</span>
<div className="flex1 mr20">
<input type="text"
// className="input-100-45 greyInput"
className={shixunCreatePracticetype===true?"input-100-45 greyInpus wind100":"input-100-45 greyInput "}
maxLength="50"
name="challenge[subject]"
value={shixunCreatePractice}
onInput={this.shixunCreatePractice}
placeholder="请输入任务名称(此信息将提前展示给学员),例:计算学生的课程成绩绩点"/>
</div>
<div style={{width: '57px'}}>
<span
className={shixunCreatePracticetype === true ? "color-orange mt8 fl block" : "color-orange mt8 fl none"}
id="new_shixun_name"><i
className="fa fa-exclamation-circle mr3"></i></span>
</div>
</div>
</div>
</div>
<div className="edu-back-white padding40-20 mb20">
<p className="color-grey-6 font-16 mb30">过关任务</p>
<TPMMDEditor ref={this.exercisememoMDRef} placeholder="请输入选择题的题干内容" mdID={'exercisememoMD'} refreshTimeout={1500}
watch={true} className="courseMessageMD" initValue={this.state.exercisememoMDRefval} height={700}></TPMMDEditor>
<p id="e_tip_Memochallengesnew" className="edu-txt-right color-grey-cd font-12"></p>
<p id="e_tips_Memochallengesnew" className="edu-txt-right color-grey-cd font-12"></p>
</div>
<div className="edu-back-white padding40-20 mb20">
<p className="color-grey-6 font-16 mb30">难度系数</p>
<div className="clearfix mb40">
<RadioGroup value={shixunCreatePracticeGroup} className="fl mr40"
disabled={this.props.status===2?true:false}
onChange={this.props.status===2?"":this.onshixunCreatePracticeChange}>
<Radio value={1}>简单</Radio>
<Radio value={2}>中等</Radio>
<Radio value={3}>困难</Radio>
</RadioGroup>
</div>
<p className="color-grey-6 font-16 mb30">奖励经验值</p>
<div className="clearfix"
// onMouseLeave={this.props.status===2?"":this.onshixunsmarkss}
>
<span className="fl mr30 color-orange pt10">*</span>
<Select style={{width: 120}} className="winput-240-40 fl"
id="challenge_score"
onChange={this.props.status===2?"":this.onshixunsmark}
// onMouseEnter={this.props.status===2?"":this.onshixunsmarks}
disabled={this.props.status===2?true:false}
// open={marktype}
value={onshixunsmarkvalue}
getPopupContainer={triggerNode => triggerNode.parentNode}
>
{options}
</Select>
<p className="fl color-grey-9 font-12 ml20">
如果学员答题错误则不能得到相应的经验值<br/>
如果学员成功得到经验值那么将同时获得等值的金币奖励+10经验值+10金币
</p>
<span className="color-orange mt7 fl ml20 none" id="ex_value_notice"><i
className="fa fa-exclamation-circle mr3"></i></span>
</div>
</div>
<div className="edu-back-white padding40-20 mb20">
<p className="color-grey-6 font-16 mb30">技能标签</p>
<div className="clearfix df">
<span className="mr30 color-orange pt10">*</span>
<div className="flex1">
<Input type="text"
className="winput-240-40 fl mr20 winput-240-40s"
id="input_task_tag"
placeholder="添加标签"
onInput={this.shixunsskill}
value={shixunsskillvalue}
onPressEnter={this.clickshixunsskill}
onBlur={this.clickshixunsskill}
/>
{/*<a className="white-btn orange-btn fl mt1 use_scope-btn ml20 mt5 mr20"*/}
{/*onClick={this.clickshixunsskill}>+ 添加</a>*/}
<div className="ml15 color-grey-9 mt5">学员答题正确将获得技能否则不能获得技能</div>
<div className="mt20 clearfix" id="task_tag_content">
{
shixunsskillvaluelist===undefined?"":shixunsskillvaluelist.length === 0 ? "" : shixunsskillvaluelist.map((itme, key) => {
return (
<li className="task_tag_span" key={key}><span>{itme}</span>
<a onClick={() => this.delshixunsskilllist(key)}>×</a>
</li>
)
})
}
</div>
</div>
<span
className={shixunsskillvaluelisttype === true ? "color-orange mt7 fl ml20 block" : " color-orange mt7 fl ml20 none"}
id="stage_name_notice">
<i className="fa fa-exclamation-circle mr3"></i></span>
</div>
</div>
<div className="edu-back-white padding40-20 mb20">
<p className="color-grey-6 font-16 mb30">服务配置</p>
<div className="clearfix mb5">
<span className="color-orange pt10 fl">*</span>
<label className="panel-form-label fl">评测时限(S)</label>
<div className="pr fl with80 status_con">
<input value={this.state.exec_time} className="panel-box-sizing task-form-100 task-height-40" placeholder="请输入类别名称" onInput={this.setexec_time}/>
</div>
<span
className={this.state.shixunExec_timeType === true ? "color-orange mt8 fl block ml20" : "color-orange mt8 fl none"}
id="new_shixun_name"><i className="fa fa-exclamation-circle mr3"></i></span>
<div className="cl"></div>
</div>
</div>
<div className="clearfix mt30"
style={{display:this.props.identity>4||this.props.identity===undefined?"none":'block'}}
>
{checkpointId===undefined?<a className="defalutSubmitbtn fl mr20" onClick={CreatePracticesendtype===true?"":this.CreatePracticesend}>提交</a>:
<a className="defalutSubmitbtn fl mr20" onClick={editPracticesendtype===true?"":this.editPracticesend}>提交</a>}
{/*<a href={go_back_url === undefined ? "" : go_back_url} className="defalutCancelbtn fl">取消</a>*/}
<Link to={go_back_url === undefined ? "" : go_back_url} className={"defalutCancelbtn fl"}>取消</Link>
</div>
</div>
</React.Fragment>
)
}
}

@ -77,6 +77,15 @@ function JupyterTPI (props) {
const emptyCtx = (
<div className="jupyter_empty">
<style>
{ `
.ant-empty{
margin-top:80px;
color:#fff;
}
`
}
</style>
<Empty />
</div>
);
@ -88,6 +97,15 @@ function JupyterTPI (props) {
const [myIdentifier, setMyIdentifier] = useState('');
const [renderCtx, setRenderCtx] = useState(() => (emptyCtx));
let newHandletype=false
const newHandle = function (event) {
if(newHandletype===false){
newHandletype=true
saveJupyterTpi(event);
setTimeout(()=>{newHandletype=false},500)
}
}
// 保存代码
const addEventListeners = () => {
window.addEventListener('message', (e) => {
@ -95,12 +113,10 @@ function JupyterTPI (props) {
if(e){
if(e.data){
if(e.data==="jupytermessage"){
saveJupyterTpi();
newHandle()
}
}
}
})
}
@ -152,8 +168,8 @@ function JupyterTPI (props) {
title: '更新通知',
content: (<div className="update_notice">
{stopposttpip(1)}
<p className="update_txt">该实训已更新更新后您编写的实训代码将会丢失</p>
<p className="update_txt">如有需要请先导出代码再进行更新</p>
<p className="update_txt">该实训已更新您选择更新后之前编写的实训代码将会丢失</p>
<p className="update_txt">如有需要请先使用jupyter中-文件-下载保存代码再进行更新</p>
{/*<p className="update_txt">还未完成评测的任务代码,请自行保存</p>*/}
</div>),
okText: '立即更新',
@ -294,7 +310,7 @@ function JupyterTPI (props) {
});
const oUl = (
<ul className="jupyter_data_list">
<ul className="jupyter_data_list" >
{ oList }
</ul>
);
@ -332,12 +348,12 @@ function JupyterTPI (props) {
</p>
<p className="jupyter_btn">
{/*sync | poweroff */}
{/*<Button*/}
{/* className="btn_common"*/}
{/* type="link"*/}
{/* icon="history"*/}
{/* onClick={handleClickResetTpi}*/}
{/*>重置实训</Button>*/}
<Button
className="btn_common"
type="link"
icon="history"
onClick={handleClickResetTpi}
>重置实训</Button>
<Button
className="btn_common"
@ -396,7 +412,7 @@ function JupyterTPI (props) {
<h2 className="borbottom17212F jupyterfilepaths">
<span className={"ml50"}>文件路径</span>
<div className="sortinxdirection">
<a className="jupyter_name ml50 maxnamewidth200 lineheighttaj colorlineheighttaj">{jupyter_folder_name}</a>
<a className="jupyter_name ml50 maxnamewidth186JUPYTER lineheighttaj colorlineheighttaj">{jupyter_folder_name}</a>
<a className={"fr color-blue lineheighttaj font-14"}
onClick={() => {
jsCopy("jupyter_folder_name")

@ -215,13 +215,13 @@ line-height: 50px !important;
background: #070F1A !important;
}
.maxnamewidth200{
max-width: 200px;
.maxnamewidth186JUPYTER{
max-width: 186px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
cursor: default;
width: 200px;
width: 186px;
}
.maxnamewidth181{

@ -360,11 +360,11 @@ class Challengesjupyter extends Component {
let id=this.props.match.params.shixunId;
let that=this;
Modal.confirm({
title: '重置实训',
title: '重置环境',
content: (
<p style={{ lineHeight: '24px' }}>
你在本文件中修改的内容将丢失,<br />
是否确定重新加载初始代码
是否确定重置环境
</p>
),
okText: '确定',
@ -424,7 +424,23 @@ class Challengesjupyter extends Component {
};
return (
<React.Fragment>
<div className="">
<div >
<style>
{
`
.ant-notification{
position: fixed !important;
z-index: 3000 !important;
}
.ant-modal-wrap {
position: fixed !important;
z-index: 3000 !important;
margin-top: 100px !important;
}
`
}
</style>
<p className="clearfix mb20 edu-back-white">
<div className={"shixunjianjie"}>
<span className="font-16 fl">简介</span>
@ -579,7 +595,7 @@ class Challengesjupyter extends Component {
<p className="challenbaocuntest" type="upload" >导入</p>
</div>
</Upload>
{/*<button type="button" className="ant-btn deletebuttom chongzhistyles" onClick={this.handleClickResetTpi}><span>重置环境</span></button>*/}
<button type="button" className="ant-btn deletebuttom chongzhistyles" onClick={this.handleClickResetTpi}><span>重置环境</span></button>
</div>

@ -198,7 +198,7 @@
position: fixed;
top: 0px;
left: 0px;
z-index: 999999;
z-index: 2800;
right: 0px;
}
@ -210,7 +210,7 @@
margin-top: 63px;
bottom: 0px;
left: 0px;
z-index: 999999;
z-index: 2800;
right: 0px;
}

@ -127,3 +127,14 @@
background: #FFFFFF;
}
.file_path_input{
position: absolute;
right: -50%;
}
.questiontype:hover{
color: #4CACFF !important;
}
.questiontype:active{
color: #4CACFF !important;
}

@ -56,7 +56,8 @@ const types = {
CLEAR_OJ_FOR_USER_REDUCER: 'CLEAR_OJ_FOR_USER_REDUCER', // 退出时清空 ojForUserReducer保存内容
ADD_OJ_LIKE_COUNT: 'ADD_OJ_LIKE_COUNT', // 增加点赞数
CHANGE_RECORD_PAGINATION_PAGE: 'CHANGE_RECORD_PAGINATION_PAGE', // 改变提交分页
UPDATE_OJ_FOR_USER_COMMENT_COUNT: 'UPDATE_OJ_FOR_USER_COMMENT_COUNT', // 更新 hack 中的评论数
UPDATE_OJ_FOR_USER_COMMENT_COUNT: 'UPDATE_OJ_FOR_USER_COMMENT_COUNT', // 更新 hack 中的评论数,
UPDATE_NOTE_CONTENT: 'UPDATE_NOTE_CONTENT', // 更新笔记内容
/*** jupyter */
GET_JUPYTER_DATA_SETS: 'GET_JUPYTER_DATA_SETS', // jupyter 数据集
GET_JUPYTER_TPI_URL: 'GET_JUPYTER_TPI_URL', // 获取 jupyter url

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-12-23 10:53:25
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-25 17:06:57
* @LastEditTime : 2019-12-27 11:07:02
*/
import types from "./actionTypes";
@ -42,7 +42,7 @@ export const getCommentLists = (identifier) => {
limit,
page
}).then(res => {
console.log('获取评论列表: ====>>>>', res);
// console.log('获取评论列表: ====>>>>', res);
if (res.status === 200) {
const {data} = res;
dispatch({

@ -50,7 +50,8 @@ import {
saveEditorCodeForDetail,
saveOpacityType,
clearOjForUserReducer,
changeRecordPagination
changeRecordPagination,
addNotes
// isUpdateCodeCtx
} from './ojForUser';
@ -137,6 +138,7 @@ export default {
saveOpacityType,
clearOjForUserReducer,
changeRecordPagination,
addNotes,
// jupyter
getJupyterTpiDataSet,
getJupyterTpiUrl,

@ -7,7 +7,7 @@
* @LastEditTime: 2019-12-13 23:03:27
*/
import types from "./actionTypes";
import { message } from 'antd';
import { message ,Modal} from 'antd';
import {
fetchJupyterTpiDataSet,
fetchJupyterTpiUrl,
@ -15,7 +15,8 @@ import {
fetchSyncJupyterCode,
fetchreset_with_tpi,
fetchSaveJupyterTpi,
fetactive_with_tpi
fetactive_with_tpi,
timeinfo_with_tpis
} from "../../services/jupyterServer";
// 获取 jupyter 相关信息
@ -76,7 +77,9 @@ export const getJupyterTpiUrl = (obj) => {
console.log('获取url', res);
if (res.status === 200) {
const { status, url = '', port } = res.data;
addjypertime(Date.now() +3600 * 1000)
dispatch(updataspinning(false))
//setTimeout(()=>{ dispatch(addjypertime(Date.now() +3600 * 1000))},500)
timeinfo_with_tpi(id,dispatch)
dispatch({
type: types.GET_JUPYTER_TPI_URL,
payload: {
@ -106,7 +109,7 @@ export const syncJupyterCode = (identifier, msg) => {
const {status} = res.data
if (status === 0) {
message.success(msg);
updataspinning(false)
dispatch(updataspinning(false))
setTimeout(() => {
window.location.reload();
}, 300);
@ -131,7 +134,7 @@ export const reset_with_tpi = (identifier, msg) => {
const {status} = res.data
if (status === 0) {
message.success(msg);
updataspinning(false)
dispatch(updataspinning(false))
setTimeout(() => {
window.location.reload();
}, 300);
@ -156,7 +159,7 @@ export const active_with_tpi = (identifier, msg) => {
const {status} = res.data
if (status === 0) {
message.success(msg);
addjypertime(Date.now() + 900 * 1000);
dispatch(addjypertime(Date.now() + 900 * 1000))
}
}
})
@ -171,6 +174,7 @@ export const changeGetJupyterUrlState = (status) => {
payload: status
}
}
// 保存 jupyter tpi
export const saveJupyterTpi = () => {
return (dispatch, getState) => {
@ -234,3 +238,28 @@ export const updataspinning=(type)=>{
}
}
// 获取重置实训后的时间
export const timeinfo_with_tpi = (identifier, dispatch) => {
const params = {
identifier: identifier
};
timeinfo_with_tpis(params).then(res => {
if (res.data.status === 401) return;
if (res.status === 200) {
if(res.data.status===0){
if(res.data.useSeconds===null){
Modal.warning({
title: '提示',
content: '因为这个实训pod不在了无法获取倒计时请联系系统管理人员',
});
}else{
let useSeconds=res.data.useSeconds;
let summain=3600 * 1000;
let sums= useSeconds * 1000;
let sum=summain-sums;
setTimeout(()=>{ dispatch(addjypertime(Date.now() +sum))},500);
}
}
}
})
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save