Merge branch 'dev_aliyun' into dev_cs

dev_cs
caicai8 6 years ago
commit d0611dab73

@ -23,7 +23,7 @@ module GitHelper
Rails.logger.info "encoding: #{cd['encoding']} confidence: #{cd['confidence']}"
# 字符编码问题GB18030编码识别率不行
decode_content =
if cd["encoding"] == 'GB18030' && cd['confidence'] == 1.0
if cd["encoding"] == 'GB18030' && cd['confidence'] > 0.8
content.encode('UTF-8', 'GBK', {:invalid => :replace, :undef => :replace, :replace => ' '})
else
content.force_encoding('UTF-8')

@ -494,20 +494,88 @@ class ExerciseQuestionsController < ApplicationController
def adjust_score
ActiveRecord::Base.transaction do
begin
ex_all_scores = @exercise.exercise_questions.pluck(:question_score).sum
ex_obj_score = @exercise_current_user.objective_score #全部客观题得分
ex_subj_score = @exercise_current_user.subjective_score < 0.0 ? 0.0 : @exercise_current_user.subjective_score #全部主观题得分
ex_answers = @exercise_question.exercise_answers.search_answer_users("user_id",@user_id) #当前用户答案的得分
if @exercise_question.question_type == Exercise::COMPLETION #当为填空题,更新问题的总分,
ex_answer_old = ex_answers.score_reviewed.pluck(:score).sum #每一关的得分总和
each_right_score = (@c_score / ex_answers.count.to_f) #调分后,平均每关的分数
new_obj_score = ex_obj_score - ex_answer_old + @c_score
if @exercise_question.question_type == Exercise::MULTIPLE
if ex_answers.present? #学生有回答时 取学生的答题得分否则0分
answer_choice_array = []
ex_answers.each do |a|
if a.try(:exercise_choice).try(:choice_position).present?
answer_choice_array.push(a&.exercise_choice&.choice_position) #学生答案的位置
end
end
user_answer_content = answer_choice_array.reject(&:blank?).sort
standard_answer = @exercise_question.exercise_standard_answers.pluck(:exercise_choice_id).sort
if standard_answer.size == 1 # 老数据需要判断学生答题是否正确, 正确取原题得分否则是0分
standard_answer = standard_answer.first.to_s.split("").map(&:to_i).sort
if user_answer_content == standard_answer
ex_answer_old = @exercise_question.question_score
else
ex_answer_old = 0
end
else # 新多选题只需取第一条答题记录的得分
ex_answer_old = ex_answers.first.score > 0 ? ex_answers.first.score : 0
end
ex_answers.update_all(:score => @c_score) #所有的正确选项需重新更新
else
answer_option = {
:user_id => @user_id,
:exercise_question_id => @exercise_question.id,
:score => @c_score,
:answer_text => ""
}
ExerciseAnswer.create(answer_option)
ex_answer_old = 0
end
if ex_obj_score <= 0.0
new_obj_score = @c_score
else
new_obj_score = ex_obj_score - ex_answer_old + @c_score
end
total_scores = new_obj_score + ex_subj_score
if total_scores < 0.0
total_scores = 0.0
elsif total_scores > ex_all_scores
total_scores = ex_all_scores
end
ex_scores = {
:objective_score => new_obj_score,
:score => total_scores
}
@exercise_current_user.update_attributes(ex_scores)
elsif @exercise_question.question_type == Exercise::COMPLETION #当为填空题,更新问题的总分,
if ex_answers.exists?
ex_answer_old = ex_answers.score_reviewed.pluck(:score).sum #每一关的得分总和
each_right_score = (@c_score / ex_answers.count.to_f) #调分后,平均每关的分数
new_obj_score = ex_obj_score - ex_answer_old + @c_score
ex_answers.update_all(:score => each_right_score) #所有的正确选项需重新更新
else #如果学生未答,则创建新的答题记录
answer_option = {
:user_id => @user_id,
:exercise_question_id => @exercise_question.id,
:score => @c_score,
:answer_text => ""
}
ExerciseAnswer.create(answer_option)
new_obj_score = ex_obj_score + @c_score
end
total_scores = new_obj_score + ex_subj_score
if total_scores < 0.0
total_scores = 0.0
elsif total_scores > ex_all_scores
total_scores = ex_all_scores
end
ex_scores = {
:objective_score => new_obj_score,
:score => total_scores
}
@exercise_current_user.update_attributes(ex_scores)
ex_answers.update_all(:score => each_right_score) #所有的正确选项需重新更新
elsif @exercise_question.question_type == Exercise::SUBJECTIVE #当为主观题时
if ex_answers.exists?
ex_answers_old_score = ex_answers.first.score > 0.0 ? ex_answers.first.score : 0.0 #原分数小于0取0
@ -524,6 +592,11 @@ class ExerciseQuestionsController < ApplicationController
new_sub_score = ex_subj_score + @c_score
end
total_scores = ex_obj_score + new_sub_score
if total_scores < 0.0
total_scores = 0.0
elsif total_scores > ex_all_scores
total_scores = ex_all_scores
end
ex_scores = {
:subjective_score => new_sub_score,
:score => total_scores
@ -549,6 +622,11 @@ class ExerciseQuestionsController < ApplicationController
new_obj_score = @c_score
end
total_scores = new_obj_score + ex_subj_score
if total_scores < 0.0
total_scores = 0.0
elsif total_scores > ex_all_scores
total_scores = ex_all_scores
end
ex_scores = {
:objective_score => new_obj_score,
:score => total_scores
@ -556,30 +634,33 @@ class ExerciseQuestionsController < ApplicationController
@exercise_current_user.update_attributes(ex_scores)
end
comments = params[:comment]
question_comment = @exercise_question.exercise_answer_comments.first
question_comment = @exercise_question.exercise_answer_comments&.first
if question_comment.present?
comment_option = {
:comment => comments.present? ? comments : question_comment.comment,
:comment => comments,
:score => @c_score,
:exercise_answer_id => ex_answers.present? ? ex_answers.first.id : nil
:exercise_answer_id => ex_answers.present? ? ex_answers.first.id : nil,
:user_id => current_user.id
}
question_comment.update_attributes(comment_option)
@exercise_comments = question_comment
else
ex_answer_comment_id = @exercise_question.exercise_answers.find_by(user_id: @user_id).try(:id)
comment_option = {
:user_id => current_user.id,
:comment => comments,
:score => @c_score,
:exercise_question_id => @exercise_question.id,
:exercise_shixun_answer_id => @shixun_a_id.present? ? @shixun_a_id : nil,
:exercise_answer_id => ex_answers.present? ? ex_answers.first.id : nil
:exercise_answer_id => ex_answer_comment_id
}
@exercise_comments = ExerciseAnswerComment.new(comment_option)
@exercise_comments.save
end
rescue Exception => e
uid_logger_error(e.message)
tip_exception("没有权限")
tip_exception(e.message)
raise ActiveRecord::Rollback
end
end
@ -703,8 +784,8 @@ class ExerciseQuestionsController < ApplicationController
normal_status(-1,"用户不存在!")
elsif @c_score.blank?
normal_status(-1,"分数不能为空!")
elsif @exercise_question.question_type <= Exercise::JUDGMENT
normal_status(-1,"题/判断题不能调分!")
elsif @exercise_question.question_type == Exercise::SINGLE || @exercise_question.question_type == Exercise::JUDGMENT
normal_status(-1,"选题/判断题不能调分!")
elsif params[:comment].present? && params[:comment].length > 100
normal_status(-1,"评语不能超过100个字符!")
else

@ -324,7 +324,7 @@ class GraduationTasksController < ApplicationController
tip_exception("缺少截止时间参数") if params[:end_time].blank?
tip_exception("截止时间必须晚于当前时间") if params[:end_time] <= strf_time(Time.now)
tip_exception("截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")}") if
@course.end_date.present? && params[:end_time] > @course.end_date.end_of_day
@course.end_date.present? && params[:end_time] > strf_time(@course.end_date.end_of_day)
# ActiveRecord::Base.transaction do
begin
@ -401,7 +401,7 @@ class GraduationTasksController < ApplicationController
tip_exception("截止时间不能早于当前时间") if params[:end_time] <= Time.now.strftime("%Y-%m-%d %H:%M:%S")
tip_exception("截止时间不能早于发布时间") if params[:publish_time] > params[:end_time]
tip_exception("截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")}") if
@course.end_date.present? && params[:end_time] > @course.end_date.end_of_day
@course.end_date.present? && params[:end_time] > strf_time(@course.end_date.end_of_day)
@task.publish_time = params[:publish_time]
@task.end_time = params[:end_time]
@ -414,7 +414,7 @@ class GraduationTasksController < ApplicationController
tip_exception("截止时间不能为空") if params[:end_time].blank?
tip_exception("截止时间不能早于当前时间") if params[:end_time] <= Time.now.strftime("%Y-%m-%d %H:%M:%S")
tip_exception("截止时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")}") if
@course.end_date.present? && params[:end_time] > @course.end_date.end_of_day
@course.end_date.present? && params[:end_time] > strf_time(@course.end_date.end_of_day)
@task.end_time = params[:end_time]
end
@ -426,7 +426,7 @@ class GraduationTasksController < ApplicationController
tip_exception("补交结束时间不能为空") if params[:late_time].blank?
tip_exception("补交结束时间不能早于截止时间") if params[:late_time] <= @task.end_time
tip_exception("补交结束时间不能晚于课堂结束时间(#{@course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")}") if
@course.end_date.present? && params[:late_time] > @course.end_date.end_of_day
@course.end_date.present? && params[:late_time] > strf_time(@course.end_date.end_of_day)
tip_exception("迟交扣分应为正整数") if params[:late_penalty] && params[:late_penalty].to_i < 0
@task.allow_late = true

@ -271,7 +271,11 @@ class MyshixunsController < ApplicationController
unless @hide_code || @myshixun.shixun&.vnc_evaluate
# 远程版本库文件内容
last_content = GitService.file_content(repo_path: @repo_path, path: path)["content"]
content = params[:content]
content = if @myshixun.mirror_name.select {|a| a.include?("MachineLearning") || a.include?("Python")}.present? && params[:content].present?
params[:content].gsub(/\t/, ' ').gsub(/ /, ' ') # 这个不是空格在windows机器上带来的问题
else
params[:content]
end
Rails.logger.info("###11222333####{content}")
Rails.logger.info("###222333####{last_content}")

@ -264,8 +264,9 @@ class QuestionBanksController < ApplicationController
# new_exercise.create_exercise_list
# exercise.update_column(:quotes, exercise.quotes+1)
# end
new_exercise if new_exercise.save!
new_exercise.save!
exercise.update_column(:quotes, exercise.quotes+1)
new_exercise
end
end
@ -292,8 +293,9 @@ class QuestionBanksController < ApplicationController
# new_poll.create_polls_list
# poll.update_column(:quotes, poll.quotes+1)
# end
new_poll if new_poll.save!
new_poll.save!
poll.update_column(:quotes, poll.quotes+1)
new_poll
end
end

@ -0,0 +1,10 @@
class ShixunListsController < ApplicationController
def index
@results = ShixunSearchService.call(search_params)
end
private
def search_params
params.permit(:keyword, :type, :page, :limit, :order, :type, :status, :diff)
end
end

@ -1,6 +1,7 @@
class ShixunsController < ApplicationController
include ShixunsHelper
include ApplicationHelper
include ElasticsearchAble
before_action :require_login, :check_auth, except: [:download_file, :index, :menus, :show, :show_right, :ranking_list,
:discusses, :collaborators, :fork_list, :propaedeutics]
@ -131,8 +132,16 @@ class ShixunsController < ApplicationController
offset = (page.to_i - 1) * (limit.to_i)
order = params[:order] || "desc"
## 搜索关键字创建者、实训名称、院校名称
keyword = params[:search].blank? ? "*" : params[:search]
@shixuns = Shixun.search keyword, where: {id: @shixuns.pluck(:id)}, order: {"myshixuns_count" => order}, limit: limit, offset: offset
keyword = params[:keyword].to_s.strip.presence || '*'
model_options = {
index_name: [Shixun],
model_includes: Shixun.searchable_includes
}
model_options.merge(where: { id: @shixuns.pluck(:id) }).merge(order: {"myshixuns_count" => order}).merge(limit: limit, offset: offset)
model_options.merge(default_options)
@shixuns = Searchkick.search(keyword, model_options)
# @shixuns = Shixun.search keyword, where: {id: @shixuns.pluck(:id)}, order: {"myshixuns_count" => order}, limit: limit, offset: offset
@total_count = @shixuns.total_count
end

@ -81,7 +81,7 @@ module TidingDecorator
end
def student_join_course_content
I18n.t(locale_format) % Course.find_by(id: container_id)&.name
I18n.t(locale_format) % [trigger_user.show_real_name, Course.find_by(id: container_id)&.name]
end
def teacher_join_course_content

@ -16,18 +16,26 @@ module ExercisesHelper
end
if q_type <= Exercise::JUDGMENT
if answers_content.present? #学生有回答时
answer_choice_array = []
answers_content.each do |a|
answer_choice_array.push(a.exercise_choice.choice_position) #学生答案的位置
end
user_answer_content = answer_choice_array.sort
standard_answer = q.exercise_standard_answers.pluck(:exercise_choice_id).sort #该问题的标准答案,可能有多个
if user_answer_content == standard_answer #答案一致,多选或单选才给分,答案不对不给分
ques_score = q.question_score
else
ques_score = 0.0
end
if answers_content.present? #学生有回答时,分数已经全部存到exercise_answer 表,所以可以直接取第一个值
ques_score = answers_content.first.score
ques_score = ques_score < 0 ? 0.0 : ques_score
# answer_choice_array = []
# answers_content.each do |a|
# answer_choice_array.push(a.exercise_choice.choice_position) #学生答案的位置
# end
# user_answer_content = answer_choice_array.sort
# standard_answer = q.exercise_standard_answers.pluck(:exercise_choice_id).sort #该问题的标准答案,可能有多个
# if q_type == Exercise::MULTIPLE && standard_answer.size == 1 # 老数据的问题
# ques_score = answers_content.first.score
# else
#
# end
# if user_answer_content == standard_answer #答案一致,多选或单选才给分,答案不对不给分
# ques_score = q.question_score
# else
# ques_score = 0.0
# end
else
ques_score = 0.0
end
@ -58,7 +66,6 @@ module ExercisesHelper
exercise_sub_status.each do |s|
sub_answer = s.exercise_answers.search_answer_users("user_id",user_id) #主观题只有一个回答
if sub_answer.present? && sub_answer.first.score >= 0.0
if s.question_score <= sub_answer.first.score
stand_status = 1
else
@ -775,22 +782,24 @@ module ExercisesHelper
user_score = user_score_pre.present? ? user_score_pre.pluck(:score).sum : nil
elsif ques_type == 5 || ques_type == 3
user_score = user_score_pre.present? ? user_score_pre.pluck(:score).sum : 0.0
else
if exercise_answers.present? #判断题和选择题时,
answer_choice_array = []
exercise_answers.each do |a|
answer_choice_array.push(a.exercise_choice.choice_position) #学生答案的位置
end
user_answer_content = answer_choice_array.sort
standard_answer = q.exercise_standard_answers.pluck(:exercise_choice_id).sort #该问题的标准答案,可能有多个
if user_answer_content == standard_answer #答案一致,多选或单选才给分,答案不对不给分
user_score = q.question_score
else
user_score = 0.0
end
else
user_score = 0.0
end
else #选择题,判断题根据第一个记录查分
user_score = user_score_pre.present? ? user_score_pre.first.score : 0.0
# if exercise_answers.present? #判断题和选择题时,
# answer_choice_array = []
# exercise_answers.each do |a|
# answer_choice_array.push(a.exercise_choice.choice_position) #学生答案的位置
# end
# user_answer_content = answer_choice_array.sort
# standard_answer = q.exercise_standard_answers.pluck(:exercise_choice_id).sort #该问题的标准答案,可能有多个
# if user_answer_content == standard_answer #答案一致,多选或单选才给分,答案不对不给分
# user_score = q.question_score
# else
# user_score = 0.0
# end
# else
# user_score = 0.0
# end
end
end

@ -3,7 +3,7 @@ class ExerciseAnswerComment < ApplicationRecord
belongs_to :user
belongs_to :exercise_question
belongs_to :exercise_shixun_answer, optional: true
belongs_to :exercise_answer,optional: true
belongs_to :exercise_answer, optional: true
scope :search_answer_comments, lambda {|name,ids| where("#{name}":ids)}
end

@ -51,13 +51,12 @@ module Searchable::Shixun
visits_count: visits,
challenges_count: challenges_count,
study_count: myshixuns_count,
description: description
}
end
module ClassMethods
def searchable_includes
{ user: { user_extension: :school } }
[ :shixun_info, user: { user_extension: :school } ]
end
end
end

@ -46,8 +46,7 @@ class Subject < ApplicationRecord
# 挑战过路径的成员数(金课统计去重后的报名人数)
def member_count
excellent && CourseMember.where(role: 4, course_id: courses.pluck(:id)).pluck(:user_id).length > shixuns.pluck(:myshixuns_count).sum ?
CourseMember.where(role: 4, course_id: courses.pluck(:id)).pluck(:user_id).length : shixuns.pluck(:myshixuns_count).sum
excellent ? CourseMember.where(role: 4, course_id: courses.pluck(:id)).pluck(:user_id).length : shixuns.pluck(:myshixuns_count).sum
end
def all_score

@ -22,4 +22,9 @@ class Tiding < ApplicationRecord
value
end
def anonymous?
(container_type == 'StudentWorksScore' && extra.to_i == 3) ||
(container_type == 'StudentWorksScoresAppeal' && parent_container_type == 'StudentWork' && tiding_type == 'System')
end
end

@ -1,6 +1,6 @@
class UserExtension < ApplicationRecord
# identity 0: 教师教授 1: 学生, 2: 专业人士, 3: 开发者
enum identity: { teacher: 0, student: 1, professional: 2, developer: 3, cnmooc: 4, unselect: -1 }
enum identity: { teacher: 0, student: 1, professional: 2, developer: 3, enterprise: 4, unselect: -1 }
belongs_to :user, touch: true
belongs_to :school, optional: true

@ -28,9 +28,11 @@ module ElasticsearchAble
end
def body_options
{
min_score: EduSetting.get('es_min_score') || 10
}
hash = {}
hash[:min_score] = (EduSetting.get('es_min_score') || 10) if keyword != '*'
hash
end
def per_page

@ -0,0 +1,56 @@
class ShixunSearchService < ApplicationService
include ElasticsearchAble
attr_reader :params
def initialize(params)
@params = params
end
def call
# 全部实训/我的实训
type = params[:type] || "all"
# 状态:已发布/未发布
status = params[:status] || "all"
# 超级管理员用户显示所有未隐藏的实训、非管理员显示所有已发布的实训(对本单位公开且未隐藏未关闭)
if type == "mine"
@shixuns = User.current.shixuns.none_closed
else
if User.current.admin? || User.current.business?
@shixuns = Shixun.none_closed.where(hidden: 0)
else
none_shixun_ids = ShixunSchool.where("school_id != #{User.current.school_id}").pluck(:shixun_id)
@shixuns = Shixun.where.not(id: none_shixun_ids).none_closed.where(hidden: 0)
end
end
unless status == "all"
@shixuns = status == "published" ? @shixuns.where(status: 2) : @shixuns.where(status: [0, 1])
end
## 筛选 难度
if params[:diff].present? && params[:diff].to_i != 0
@shixuns = @shixuns.where(trainee: params[:diff])
end
Shixun.search(keyword, search_options)
end
private
def search_options
model_options = {
includes: [ :shixun_info, :challenges, :subjects, user: { user_extension: :school } ]
}
model_options.merge!(where: { id: @shixuns.pluck(:id) })
model_options.merge!(order: {"myshixuns_count" => sort_str})
model_options.merge!(default_options)
model_options
end
def sort_str
params[:order] || "desc"
end
end

@ -12,7 +12,7 @@
<div class="form-group mr-2">
<label for="identity">职业:</label>
<% identity_options = [['全部', '']] + UserExtension.identities.map { |k, v| [I18n.t("user.identity.#{k}"), v] } %>
<% identity_options = [['全部', ''], ['教师', 0], ['学生', 1], ['专业人士', 2]] %>
<%= select_tag(:identity, options_for_select(identity_options), class: 'form-control') %>
</div>

@ -5,6 +5,8 @@ if identity == Course::STUDENT
json.task_operation task_operation_url(myshixun, shixun)
json.view_report work.work_status > 0
json.commit_des commit_des_status(work, homework)
json.redo_work (homework.end_or_late ? false : student_redo_work(work, homework))
json.myshixun_identifier myshixun&.identifier
else
json.work_statuses student_work_status(homework, work.user_id, homework.course, work)
end

@ -1,4 +1,4 @@
# json.shixun_list @shixuns do |shixun|
# json.shixun_lists @shixuns do |shixun|
# json.shixun_identifier shixun.identifier
# json.name shixun.name
# json.creator shixun.user&.full_name

@ -40,8 +40,6 @@ elsif @user_course_identity == Course::STUDENT
json.efficiency work_score_format(@work.efficiency, true, @score_open)
json.eff_score work_score_format(@work.eff_score, true, @score_open)
json.complete_count @work.myshixun.try(:passed_count)
json.redo_work (@homework.end_or_late ? false : student_redo_work(@work, @homework))
json.myshixun_identifier @work.myshixun&.identifier
else
json.(@work, :id, :work_status, :update_time, :ultimate_score)

@ -0,0 +1,22 @@
json.shixuns_count @results.total_count
json.shixun_list do
json.array! @results.with_highlights(multiple: true) do |obj, highlights|
json.merge! obj.to_searchable_json
json.challenge_names obj.challenges.pluck(:subject)
# 去除开头标点符号
reg = /^[,。?:;‘’!“”—……、]/
highlights[:description]&.first&.sub!(reg, '')
highlights[:content]&.first&.sub!(reg, '')
json.title highlights.delete(:name)&.join('...') || obj.searchable_title
json.description highlights[:description]&.join('...') || Util.extract_content(obj.description)[0..300]
json.content highlights
json.level level_to_s(obj.trainee)
json.subjects obj.subjects.uniq do |subject|
json.(subject, :id, :name)
end
end
end

@ -10,7 +10,7 @@ json.shixun_list do
# json.description highlights.values[0,5].each { |arr| arr.is_a?(Array) ? arr.join('...') : arr }.join('<br/>')
json.content highlights
json.level level_to_s(obj.trainee)
json.subjects obj.subjects do |subject|
json.subjects obj.subjects.uniq do |subject|
json.(subject, :id, :name)
end
end

@ -17,8 +17,11 @@ json.homework_type homework_type
json.time tiding.how_long_time
json.new_tiding tiding.unread?(@onclick_time)
# 需要系统头像
show_system_user = tiding.trigger_user_id.zero? || tiding.tiding_type == 'System' || tiding.anonymous?
json.trigger_user do
if tiding.trigger_user_id.zero? || (tiding.trigger_user_id == 1 && tiding.tiding_type == 'System')
if show_system_user
json.id 0
json.name "系统"
json.login ""

@ -19,7 +19,7 @@
"9_2_end": "你提交的加入课堂申请:%s教师, 审核未通过"
"7_1_end": "你提交的加入课堂申请:%s助教, 审核已通过"
"7_2_end": "你提交的加入课堂申请:%s助教, 审核未通过"
StudentJoinCourse_end: "加入了课堂:%s学生"
StudentJoinCourse_end: "%s 加入了课堂:%s学生"
TeacherJoinCourse:
"2_end": "%s将你加入课堂%s教师"
"3_end": "%s将你加入课堂%s助教"
@ -202,6 +202,7 @@
2_end: "别人对你的匿评发起的申诉申请:%s审核未通过"
StudentWork:
Apply_end: "发起了匿评申诉申请:%s"
HomeworkCommon_end: "发起了匿评申诉申请:%s"
System_end: "有人对你的匿评发起了申诉:%s"
Department_end: "你选填的二级单位:%s%s因不符合规范,已被系统删除.请重新选择"
Library:

@ -13,7 +13,9 @@
professional: 专业人士
developer: 从业者
enterprise: 组织
unselect: 未选择
"0": 教师
"1": 学生
"2": 专业人士
"3": 专业人士
"3": 从业者
"4": 组织

@ -174,7 +174,10 @@ Rails.application.routes.draw do
end
end
resources :shixun_lists
resources :shixuns, param: :identifier do
collection do
get :menus
get :get_recommend_shixuns
@ -182,7 +185,7 @@ Rails.application.routes.draw do
get :get_mirror_script
post :apply_shixun_mirror
get :download_file
get :shixun_list
get :shixun_lists
end
member do

Binary file not shown.

@ -81,8 +81,10 @@ namespace :public_classes do
homework.update_columns(publish_time: publish_time, end_time: end_time, created_at: created_at, updated_at: updated_at)
homework.homework_detail_manual.update_columns(comment_status: 6, created_at: created_at, updated_at: updated_at)
homework.update_homework_work_score
homework.update_attribute('calculation_time', end_time)
homework.student_works.where("work_status !=0 and update_time > '#{end_time}'").update_all(update_time: end_time)
# homework.student_works.where("work_status !=0 and update_time > '#{end_time}'").update_all(update_time: end_time)
end
when 3
# 试卷

File diff suppressed because one or more lines are too long

@ -1,5 +1,5 @@
'use strict';
// extract-css-assets-webpack-plugin
const autoprefixer = require('autoprefixer');
const path = require('path');
const webpack = require('webpack');

@ -34,8 +34,9 @@
// location.href = './compatibility'
location.href = '/compatibility.html'
}
const isMobile = (/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase()));
if (isMobile) {
// const isMobile = (/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase()));
const isWeiXin = (/MicroMessenger/i.test(navigator.userAgent.toLowerCase()));
if (isWeiXin) {
document.write('<script type="text/javascript" src="/javascripts/wx/jweixin-1.3.0.js"><\/script>');
}
</script>

@ -9,7 +9,7 @@ import {
Route,
Switch
} from 'react-router-dom';
import axios from 'axios';
import '@icedesign/base/dist/ICEDesignBase.css';
import '@icedesign/base/index.scss';
@ -37,7 +37,7 @@ import {MuiThemeProvider, createMuiTheme} from 'material-ui/styles';
import history from './history';
import {SnackbarHOC, configShareForIndex} from 'educoder'
import {SnackbarHOC} from 'educoder'
import {initAxiosInterceptors} from './AppConfig'
@ -298,47 +298,7 @@ class App extends Component {
mydisplay:true,
})
};
initWXShare = () => {
if (window.wx) {
const wx = window.wx
const url = '/wechats/js_sdk_signature.json'
const currentUrl = window.location.href.split('#')[0]
// window.encodeURIComponent()
axios.post(url, {
url: window.__testUrl || currentUrl,
}).then((response) => {
console.log('got res')
const data = response.data;
wx.config({
debug: false,
appId: data.appid,
timestamp: data.timestamp,
nonceStr: data.noncestr,
signature: data.signature,
jsApiList: [
'onMenuShareTimeline',//
'onMenuShareAppMessage',
'onMenuShareQQ',
'onMenuShareWeibo',
'onMenuShareQZone'
]
});
wx.ready(function () {
console.log('wx is ready')
configShareForIndex('/')
});
wx.error(function (res) {
console.log('wx is error')
console.log(res)
//alert(res.errMsg);//错误提示
});
}).catch((error) => {
console.log(error)
})
}
}
disableVideoContextMenu = () => {
window.$( "body" ).on( "mousedown", "video", function(event) {
if(event.which === 3) {
@ -360,7 +320,6 @@ class App extends Component {
});
initAxiosInterceptors(this.props)
this.initWXShare()
//
// axios.interceptors.response.use((response) => {
// // console.log("response"+response);

@ -10,7 +10,7 @@ broadcastChannelOnmessage('refreshPage', () => {
})
function locationurl(list){
debugger
if (window.location.port === "3007") {
} else {

@ -3,4 +3,6 @@ export function isDev() {
}
// const isMobile
export const isMobile = (/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase()));
export const isMobile = (/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase()));
// const isWeiXin = (/MicroMessenger/i.test(navigator.userAgent.toLowerCase()));

@ -1,4 +1,5 @@
const host = window.location.host
import axios from 'axios'
const host = window.location.protocol + '//' + window.location.host
const wx = window.wx
function share(shareData) {
try {
@ -11,7 +12,51 @@ function share(shareData) {
console.log(e)
}
}
const urlDoneMap = {}
function requestForSignatrue (callback) {
const currentUrl = window.location.href.split('#')[0]
if (window.wx) {
if (urlDoneMap[currentUrl]) {
callback && callback()
} else {
const wx = window.wx
const url = '/wechats/js_sdk_signature.json'
urlDoneMap[currentUrl] = true
// window.encodeURIComponent()
axios.post(url, {
url: window.__testUrl || currentUrl,
}).then((response) => {
console.log('got res')
const data = response.data;
wx.config({
debug: false,
appId: data.appid,
timestamp: data.timestamp,
nonceStr: data.noncestr,
signature: data.signature,
jsApiList: [
'onMenuShareTimeline',//
'onMenuShareAppMessage',
'onMenuShareQQ',
'onMenuShareWeibo',
'onMenuShareQZone'
]
});
wx.ready(function () {
callback && callback()
});
wx.error(function (res) {
console.log('wx is error')
console.log(res)
//alert(res.errMsg);//错误提示
});
}).catch((error) => {
console.log(error)
})
}
}
}
/**
实践课程 平台提供涵盖基础入门案例实践和创新应用的完整实训项目体系通过由浅入深的实训路径帮助学生快速提升实战能力
实训项目 覆盖不同专业的IT实验和实训每周更新无需配置本机实验环境随时随地开启企业级真实实训
@ -19,60 +64,72 @@ function share(shareData) {
单个课程和实训 获取课程/实训的简介 该课程或者实训展示的缩略图
*/
export function configShareForIndex (path) {
if (!wx) return;
var shareData = {
title: 'EduCoder - 首页',
desc: 'Educoder是一个面向计算机类的互联网IT教育和实战平台提供企业级工程实训以实现工程化专业教学的自动化和智能化。高校和企业人员可以在此开展计算机实践性教学活动将传统的知识传授和时兴的工程实战一体化。',
link: host + (path || ''),
imgUrl: window.__testImageUrl
|| host + '/react/build/images/share_logo_icon.jpg'
};
share(shareData)
export function configShareForIndex (path) {
requestForSignatrue(() => {
var shareData = {
title: 'EduCoder - 首页',
desc: 'Educoder是一个面向计算机类的互联网IT教育和实战平台提供企业级工程实训以实现工程化专业教学的自动化和智能化。高校和企业人员可以在此开展计算机实践性教学活动将传统的知识传授和时兴的工程实战一体化。',
link: host + (path || ''),
imgUrl: window.__testImageUrl
|| host + '/react/build/images/share_logo_icon.jpg'
};
share(shareData)
})
}
export function configShareForPaths () {
if (!wx) return;
var shareData = {
title: 'EduCoder - 实践课程',
desc: '平台提供涵盖基础入门、案例实践和创新应用的完整实训项目体系,通过由浅入深的实训路径,帮助学生快速提升实战能力。',
link: `${host}/paths`,
imgUrl: window.__testImageUrl
|| host + '/react/build/images/share_logo_icon.jpg'
};
share(shareData)
requestForSignatrue(() => {
console.log('configShareForPaths', host)
var shareData = {
title: 'EduCoder - 实践课程',
desc: '平台提供涵盖基础入门、案例实践和创新应用的完整实训项目体系,通过由浅入深的实训路径,帮助学生快速提升实战能力。',
link: `${host}/paths`,
imgUrl: window.__testImageUrl
|| host + '/react/build/images/share_logo_icon.jpg'
};
share(shareData)
})
}
export function configShareForShixuns () {
if (!wx) return;
var shareData = {
title: 'EduCoder - 实训项目',
desc: '覆盖不同专业的IT实验和实训每周更新无需配置本机实验环境随时随地开启企业级真实实训。',
link: `${host}/shixuns`,
imgUrl: window.__testImageUrl
|| host + '/react/build/images/share_logo_icon.jpg'
};
share(shareData)
requestForSignatrue(() => {
console.log('configShareForShixuns', host)
var shareData = {
title: 'EduCoder - 实训项目',
desc: '覆盖不同专业的IT实验和实训每周更新无需配置本机实验环境随时随地开启企业级真实实训。',
link: `${host}/shixuns`,
imgUrl: window.__testImageUrl
|| host + '/react/build/images/share_logo_icon.jpg'
};
share(shareData)
})
}
export function configShareForCourses () {
if (!wx) return;
var shareData = {
title: 'EduCoder - 翻转课堂',
desc: '自动评测实训任务,支持技能统计,提供教学活动分析报告,减轻教师和助教的辅导压力,免去作业发布和批改的困扰,实时了解学生学习情况,全面提升教师施教效率和水平。',
link: `${host}/courses`,
imgUrl: window.__testImageUrl
|| host + '/react/build/images/share_logo_icon.jpg'
};
share(shareData)
requestForSignatrue(() => {
console.log('configShareForCourses', host)
var shareData = {
title: 'EduCoder - 翻转课堂',
desc: '自动评测实训任务,支持技能统计,提供教学活动分析报告,减轻教师和助教的辅导压力,免去作业发布和批改的困扰,实时了解学生学习情况,全面提升教师施教效率和水平。',
link: `${host}/courses`,
imgUrl: window.__testImageUrl
|| host + '/react/build/images/share_logo_icon.jpg'
};
share(shareData)
})
}
// detail
export function configShareForCustom (title, desc, path, imgUrl) {
if (!wx) return;
var shareData = {
title: title,
desc: desc,
link: `${host}/${path}`,
imgUrl: imgUrl || window.__testImageUrl
|| host + '/react/build/images/share_logo_icon.jpg'
};
share(shareData)
requestForSignatrue(() => {
console.log('configShareForCustom', host)
var shareData = {
title: title,
desc: desc,
link: `${host}/${path}`,
imgUrl: imgUrl || window.__testImageUrl
|| host + '/react/build/images/share_logo_icon.jpg'
};
share(shareData)
})
}

@ -174,7 +174,7 @@ class TPIContextProvider extends Component {
}
let testPath = ''
if (window.location.port == 3007) {
testPath = 'http://pre-newweb.educoder.net'
testPath = 'http://test-newweb.educoder.net'
}
// var url = `${testPath}/api/v1/games/${ game.identifier }/cost_time`
var url = `${testPath}/api/tasks/${ game.identifier }/cost_time`
@ -268,12 +268,14 @@ pop_box_new(htmlvalue, 480, 182);
});
}
onPathChange(index) {
onPathChange(index, callback) {
let { challenge } = this.state;
// challenge = Object.assign({}, challenge)
// challenge.pathIndex = index;
this.setState({
challenge: update(challenge, {pathIndex: { $set: index }}),
}, () => {
callback && callback()
})
// TODO load new path content
}

@ -68,7 +68,7 @@ class CommentInput extends Component {
</textarea>
</div>
<div className="tips"
style={{ 'float': 'left', 'margin-top': '6px', 'font-size': '12px', 'color': '#ff6800'}}>
style={{ 'float': 'left', 'marginTop': '6px', 'fontSize': '12px', 'color': '#ff6800'}}>
请勿粘贴答案否则将造成账号禁用等后果
</div>
<div className="fr buttons" style={{ minWidth:'25px', height: '32px' }}>

@ -305,7 +305,7 @@ class CoursesIndex extends Component{
//Do your stuff here
});
}
//更新左边课堂导航
updataleftNav=()=>{
let query=this.props.location.pathname
let {isaloadtype}=this.state;

@ -93,13 +93,13 @@ class ListPageIndex extends Component{
}
componentDidMount(){
console.log("77");
// console.log("77");
var yslGuideone = window.localStorage.getItem('yslGuideone');
console.log("78");
console.log(yslGuideone);
// console.log("78");
// console.log(yslGuideone);
try {
if (yslGuideone === "true") {
console.log("true 字符串");
// console.log("true 字符串");
this.setState({
yslGuideone:true,
})
@ -107,7 +107,7 @@ class ListPageIndex extends Component{
this.setState({
yslGuideone:false,
});
console.log("false 字符串");
// console.log("false 字符串");
}
}catch (e) {
console.log(e);
@ -133,8 +133,7 @@ class ListPageIndex extends Component{
window.localStorage.setItem('yslGuideone', bool);
try {
if (bool === "true") {
console.log("115");
console.log("true 字符串");
this.setState({
yslGuideone:true,
})
@ -142,11 +141,10 @@ class ListPageIndex extends Component{
this.setState({
yslGuideone:false,
});
console.log("124");
console.log("false 字符串");
}
}catch (e) {
console.log(e);
// console.log(e);
this.setState({
yslGuideone:false,
});

@ -141,7 +141,7 @@ function create_editorMD(id, width, high, placeholder, imageUrl, callback, initV
$("#" + _id + " [type=\"inline\"]").bind("click", function () {
_editorName.cm.replaceSelection("`$$$$`");
var __Cursor = _editorName.cm.getDoc().getCursor();
_editorName.cm.setCursor(__Cursor.line, __Cursor.ch - 2);
_editorName.cm.setCursor(__Cursor.line, __Cursor.ch - 3);
_editorName.cm.focus();
});
$("[type=\"inline\"]").attr("title", "行内公式");

@ -0,0 +1,555 @@
import React,{Component} from 'react';
import { Modal,Checkbox,Select,Input,Tooltip,Spin,Icon,Drawer,Dropdown,Menu,Breadcrumb,Pagination,Button,notification} from "antd";
import axios from'axios';
import NoneData from "../coursesPublic/NoneData";
import './Newshixunmodel.css';
const Search = Input.Search;
class NewShixunModel extends Component{
constructor(props){
super(props)
this.state={
shixun_list:undefined,
shixuns_count:undefined,
Grouplist:[],
allGrouplist:[{page:1,list:[]}],
page:1,
type:'all',
status:'all',
keyword:undefined,
order:'desc',
diff:0,
limit:15,
}
}
componentDidMount() {
let{page,type,keyword,order,diff,limit,status}=this.state;
this.getdatalist(page,type,status,keyword,order,diff,limit)
}
getdatalist=(page,type,newstatus,keyword,order,diff,limit,pagetype)=>{
this.setState({
isspinning:true
})
let status=this.props.statustype===undefined?newstatus:'published';
let url="/shixun_lists.json"
axios.get(url,{params:{
page,
type,
status,
keyword,
order,
diff,
limit
}}).then((response) => {
if(response.data){
if(pagetype===undefined){
this.setState({
shixun_list:response.data.shixun_list,
shixuns_count:response.data.shixuns_count,
Grouplist:[],
isspinning:false
})
}else if(pagetype==="pagetype"){
this.setState({
shixun_list:response.data.shixun_list,
shixuns_count:response.data.shixuns_count,
isspinning:false
})
}
}
}).catch((error) => {
this.setState({
isspinning:false
})
})
}
DropdownClick=(diff)=>{
this.setState({
diff:diff
})
let{page,type,status,keyword,order,limit}=this.state;
this.getdatalist(page,type,status,keyword,order,diff,limit)
}
ItsCourse=(item)=>{
return <Menu>
{item.map((list,key)=>{
return(
<Menu.Item key={key} id={list.id}>
<a target="_blank" href={`/paths/${list.id}`} className={"newshixun500"} title={list.name}>{list.name}</a>
</Menu.Item>
)
})}
</Menu>
}
getGrouplist=(Grouplist)=>{
let {page,allGrouplist}=this.state;
let newallGrouplist=allGrouplist;
var a=newallGrouplist.find((value,index,arr)=>{
return value.page==page
});
if(a!=undefined){
newallGrouplist.map((item,key)=>{
if(item.page===page){
item.list=Grouplist
}
})
}
let newGrouplist=[];
newallGrouplist.map((item,key)=>{
item.list.map((items,ke)=>{
newGrouplist.push(items)
})
})
this.setState({
Grouplist: newGrouplist,
allGrouplist:newallGrouplist
})
}
PaginationCourse=(pageNumber)=>{
let {allGrouplist}=this.state;
let newallGrouplist=allGrouplist;
var v=newallGrouplist.find((value,index,arr)=>{
return value.page==pageNumber
});
if(v===undefined){
newallGrouplist.push({page:pageNumber,list:[]})
}
let{type,status,keyword,order,diff,limit}=this.state;
this.getdatalist(pageNumber,type,status,keyword,order,diff,limit,"pagetype")
this.setState({
page:pageNumber,
allGrouplist:newallGrouplist
})
}
belongto=(value)=>{
this.setState({
type:value,
keyword:undefined,
page:1
})
let{status,order,diff,limit}=this.state;
this.getdatalist(1,value,status,undefined,order,diff,limit)
}
updatedlist=(order)=>{
if(order==="desc"){
this.setState({
order:"asc"
})
let{type,page,status,keyword,diff,limit}=this.state;
this.getdatalist(page,type,status,keyword,"asc",diff,limit)
}else{
this.setState({
order:"desc"
})
let{type,page,status,keyword,diff,limit}=this.state;
this.getdatalist(page,type,status,keyword,"desc",diff,limit)
}
}
setdatafunsval=(e)=>{
this.setState({
keyword:e.target.value
})
}
setdatafuns=(value)=>{
this.setState({
keyword:value,
type:undefined,
page:1,
status:'all',
order:'desc',
diff:0,
limit:15,
})
this.getdatalist(1,undefined,'all',value,'desc',0,15)
}
showNotification = (description, message = "提示", icon) => {
const data = {
message,
description
}
if (icon) {
data.icon = icon;
}
notification.open(data);
}
savecouseShixunModal=()=>{
this.setState({
hometypepvisible:true
})
let {coursesId}=this.props;
let{Grouplist}=this.state;
if(Grouplist.length===0){
this.setState({
hometypepvisible:false
})
this.showNotification("请先选择实训")
return
}
if (this.props.chooseShixun) {
if(Grouplist.length>1){
this.setState({
hometypepvisible:false
})
this.showNotification("试卷选择的实训数不能大于1")
return
}
this.props.chooseShixun(Grouplist)
this.setState({
hometypepvisible:false
})
return;
}
if (this.props.pathShixun) {
this.setState({
hometypepvisible:false
})
this.props.pathShixun(Grouplist)
return;
}
let url="/courses/"+coursesId+"/homework_commons/create_shixun_homework.json";
axios.post(url, {
category_id:this.props.category_id===null||this.props.category_id===undefined?undefined:parseInt(this.props.category_id),
shixun_ids:Grouplist,
}
).then((response) => {
if(response.data.status===-1){
// this.props.showNotification(response.data.message)
}else{
// this.props.courseshomeworkstart(response.data.category_id,response.data.homework_ids)
this.showNotification("操作成功")
this.props.homeworkupdatalists(this.props.Coursename,this.props.page,this.props.order);
this.props.hideNewShixunModelType()
}
this.setState({
hometypepvisible:false
})
// category_id: 3
// homework_ids: (5) [9171, 9172, 9173, 9174, 9175]
}).catch((error) => {
console.log(error)
this.setState({
hometypepvisible:false
})
})
}
poststatus=(status)=>{
this.setState({
status:status
})
let{page,type,keyword,order,diff,limit}=this.state;
this.getdatalist(page,type,status,keyword,order,diff,limit)
}
render() {
let {diff,Grouplist,status,shixun_list,shixuns_count,page,type,order}=this.state;
// let {visible,patheditarry}=this.props;
// console.log(Grouplist)
// console.log(allGrouplist)
const statusmenus=(
<Menu className="menus">
<Menu.Item>
<a className={status==="all"?"color-blue":""} onClick={()=>this.poststatus("all")}>
所有
</a>
</Menu.Item>
<Menu.Item >
<a className={status==="published"?"color-blue":""} onClick={()=>this.poststatus("published")} >
已发布
</a>
</Menu.Item>
<Menu.Item>
<a className={status==="unpublished"?"color-blue":""} onClick={()=>this.poststatus("unpublished")}>
未发布
</a>
</Menu.Item>
</Menu>
);
const menus = (
<Menu className="menus">
<Menu.Item>
<a className={diff===0?"color-blue":""} onClick={()=>this.DropdownClick(0)}>
所有
</a>
</Menu.Item>
<Menu.Item >
<a className={diff===1?"color-blue":""} onClick={()=>this.DropdownClick(1)} >
初级
</a>
</Menu.Item>
<Menu.Item>
<a className={diff===2?"color-blue":""} onClick={()=>this.DropdownClick(2)}>
中级
</a>
</Menu.Item>
<Menu.Item>
<a className={diff===3?"color-blue":""} onClick={()=>this.DropdownClick(3)}>
高级
</a>
</Menu.Item>
<Menu.Item>
<a className={diff===4?"color-blue":""} onClick={()=>this.DropdownClick(4)}>
顶级
</a>
</Menu.Item>
</Menu>
);
return(
<div>
<style>
{
`body{ overflow: hidden !important; }
.ant-drawer-content{ overflow:auto !important; background: #f5f5f5; }
.yslbottomsj{position: absolute;bottom: -8px;}
`
}
</style>
<Drawer
placement="bottom"
closable={false}
destroyOnClose={true}
visible={this.props.NewShixunModelType}
height={'100%'}
>
<Spin spinning={this.state.isspinning}>
<div className={"clearfix educontent pr"}>
<div className={"square-list clearfix"}>
<div className="newshixunheadersear">
<div style={{height:"53px"}}></div>
<Search
style={{ width: "800px"}}
className="packinput"
placeholder="实训信息 / 院校名称 / 创建者"
value={this.state.keyword}
enterButton={<span>搜索</span>}
onInput={(e)=>this.setdatafunsval(e)}
onSearch={ (value)=>this.setdatafuns(value)} />
</div>
<div className="clearfix font-12 mt30">
<div className="font-12 ml5 fl">
<span className="fl color-grey-9 mr20">已选 <span className={"color-blue"}>{Grouplist.length}</span> </span>
<span className="fl color-grey-9 mr20"> <span className={"color-blue"}>{shixuns_count===undefined?"":shixuns_count}</span> </span>
<span className="fl color-grey-9 pointer mr30">
<a className={" color-grey-6"} onClick={()=>this.updatedlist(order)}>学习人数</a>
<sapn className="relativef ml5 " >
<i className={order==="desc"?"iconfont icon-sanjiaoxing-up font-12 ntopsj color-grey-9 color-blue":"iconfont icon-sanjiaoxing-up font-12 ntopsj color-grey-9"}></i>
<i className={order==="asc"?"iconfont icon-sanjiaoxing-down font-12 nyslbottomsj color-grey-9 color-blue":"iconfont icon-sanjiaoxing-down font-12 nyslbottomsj color-grey-9"}></i>
</sapn>
</span>
{this.props.statustype===undefined?<Dropdown overlay={statusmenus}>
<a className="ant-dropdown-link color-grey-6 mr20">
{status==='all'?"发布状态":status==='published'?"已发布":status==="unpublished"?"未发布":""}<Icon type="down" className={"color-grey-6"}/>
</a>
</Dropdown>:""}
<Dropdown overlay={menus}>
<a className="ant-dropdown-link color-grey-6">
{diff===0?"难度":diff===1?"初级":diff===2?"中级":diff===3?"高级":diff===4?"顶级":""}<Icon type="down" className={"color-grey-6"}/>
</a>
</Dropdown>
</div>
<div className="font-12 alltopiscright ml25 fr">
<span className={"fr pointer color-grey-3"} onClick={()=>this.props.hideNewShixunModelType()}>返回</span>
<span className={type==="mine"?"fr mr30 topcsactive pointer color-grey-3 color-blue":"fr mr30 pointer color-grey-3"} onClick={()=>this.belongto("mine")}>我的实训</span>
<span className={type==="all"?"fr mr30 topcsactive pointer color-grey-3 color-blue":"fr mr30 pointer color-grey-3"} onClick={()=>this.belongto("all")}>全部实训</span>
</div>
</div>
<Checkbox.Group onChange={this.getGrouplist} value={Grouplist} >
{shixun_list===undefined?"":shixun_list.length===0?"":shixun_list.map((item,key)=>{
return(
<div className="mt20 edu-back-white pd20 relativef newshixunlist" key={key}>
<div className="clearfix">
<div className="item-body">
<div className="clearfix ds pr contentSection">
<Checkbox
value={item.id}
key={item.id}
className="fl task-hide edu-txt-left mt3"
name="shixun_homework[]"
></Checkbox>
<a target="_blank" href={`/shixuns/${item.identifier}/challenges`} title={item.title} className="ml15 fl font-16 color-dark maxwidth1100"
dangerouslySetInnerHTML={{__html: item.title}}
>
</a>
<div className="cl"></div>
<style>
{
`
.newradioStyles{
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
max-height: 42px;
}
`
}
</style>
{JSON.stringify(item.description) == "{}"?"":<div className="newshixunmodelmidfont newradioStyles" title={item.description} dangerouslySetInnerHTML={{__html: item.description}}>
</div>}
{item.challenge_names.length===0?"":<div className="newshixunmodelbotfont">
{item.challenge_names.map((item,key)=>{
return(
<span>{key+1}{item}</span>
)
})}
</div>}
<div className={"newshixunpd030"}>
<div className="xuxianpro"></div>
</div>
<div className="color-grey panel-lightgrey fl ml30">
<style>
{`
.ant-breadcrumb-separator{
color: #D7D7D7 !important;
}
.panel-lightgrey, .panel-lightgrey span{
color: #999 !important;
}
.ant-breadcrumb-link{
margin-right:10px !important;
}
.ant-breadcrumb-separator{
margin-right:20px !important;
}
`}
</style>
<Breadcrumb separator="|">
<Breadcrumb.Item>{item.author_name}</Breadcrumb.Item>
<Breadcrumb.Item>{item.author_school_name}</Breadcrumb.Item>
<Breadcrumb.Item>难度系数{item.level}</Breadcrumb.Item>
<Breadcrumb.Item>学习人数{item.study_count}</Breadcrumb.Item>
</Breadcrumb>
</div>
{item.subjects.length===0?"":<Dropdown overlay={()=>this.ItsCourse(item.subjects)}>
<a className="ant-dropdown-link fl ml30 newshixunfont12 color-blue" >
所属课程<Icon className={"color-blue"} type="down" />
</a>
</Dropdown>}
</div>
</div>
</div>
</div>
)})
}
</Checkbox.Group>
{shixun_list===undefined||shixuns_count===undefined?"":shixun_list.length===0||shixuns_count===0?"":shixuns_count>15?<div className={" edu-txt-center pd303010"}>
<Pagination
showQuickJumper
defaultCurrent={1}
pageSize={15}
total={shixuns_count===undefined?"":shixuns_count}
current={page}
onChange={this.PaginationCourse}
/>
</div>:""}
{
shixun_list===undefined?
<div className={"minhegiht300"}>
</div>
:shixun_list.length===0? <NoneData></NoneData>:""
}
{
shixun_list===undefined?"":shixun_list.length===0?"":<div className={" edu-txt-center padding20-30"}>
<Button className={"mr20 newshixunmode"} onClick={()=>this.props.hideNewShixunModelType()}>取消</Button>
<Button className={"newshixunmode"} type="primary" onClick={()=>this.savecouseShixunModal()} loading={this.state.hometypepvisible}>确定</Button>
</div>}
</div>
</div>
</Spin>
</Drawer>
</div>
)
}
}
export default NewShixunModel;
// {JSON.stringify(item.content) == "{}"?<div className="newshixunmodelmidfont newradioStyles" title={item.description} dangerouslySetInnerHTML={{__html: item.description}}>
// </div>:<div className="newshixunmodelbotfont">
// {item.content.description === undefined || item.content.description===0?"":item.content.description.map((item,key)=>{
// return(
// <span dangerouslySetInnerHTML={{__html: item}}>{}</span>
// )
// })}
// </div>}
//
// {JSON.stringify(item.content) == "{}"?item.challenge_names.length===0?"":<div className="newshixunmodelbotfont">
// {item.challenge_names.map((item,key)=>{
// return(
// <span>第{key+1}关:{item}</span>
// )
// })}
// </div>:<div className="newshixunmodelbotfont">
// {item.content.challenge_names === undefined || item.content.challenge_names===0?"":item.content.challenge_names.map((item,key)=>{
// return(
// <span dangerouslySetInnerHTML={{__html: item}}>{}</span>
// )
// })}
// </div>}

@ -0,0 +1,250 @@
.searchinput{
width: 800px;
margin-top: 53px;
}
.newshixunheadersear{
display: flex;
justify-content: center;
}
.packinput .ant-input{
height: 55px;
width:663px !important;
font-size: 14px;
/*color: #681616 !important;*/
border-color: #E1EDF8 !important;
padding-left: 20px;
}
.packinput .ant-input-group-addon .ant-btn{
width:137px !important;
font-size: 18px;
height: 53px;
background:rgba(76,172,255,1);
}
.tabtitle{
height: 62px !important;
box-shadow: 3px 10px 21px 0px rgba(76, 76, 76, 0.15);
border-radius: 6px;
background: #fff;
display: flex;
justify-content: center;
}
.tabtitles2{
background: #fff;
height: 62px !important;
width: 1200px;
}
.tabtitless{
height: 62px !important;
line-height: 62px !important;
}
.tabtitle1{
}
.tabtitle2{
margin-left: 30px !important;
}
.counttit{
display: flex;
justify-content: center;
}
.counttittext{
text-align: left;
width: 1200px;
height: 18px;
color: #888888;
font-size: 13px;
margin-top: 24px;
}
.counttittexts{
color: #4CACFF !important;
font-size: 13px;
}
.mainx{
display: flex;
justify-content: center;
margin-top: 17px;
}
.project-packages-list{
}
.project-package-item{
display: -webkit-flex;
display: flex;
flex-direction:column;
margin-bottom: 20px;
padding: 20px;
background: white;
/* box-shadow: 1px 3px 3px 1px rgba(156,156,156,0.16); */
}
.xuxianpro{
height: 20px;
border-bottom: 1px dashed;
border-color: #EAEAEA;
margin-bottom: 18px;
}
.magr11{
margin-top: 11px;
}
.highlight{
color: #4CACFF;
}
.fonttext{
font-size: 20px;
font-weight:bold;
}
.fontextcolor{
color: #777777;
}
.tzbq{
margin-left: 68px;
}
.tzbqx{
/* margin-left: 24px; */
}
.bjyss{
background: #F8F8F8;
}
.zj{
overflow:hidden;
text-overflow:ellipsis;
white-space:nowrap
}
.ziticor{
color: #777777;
font-size: 13px;
}
.foohter{
margin-top: 20px;
display: flex;
flex-direction:row;
}
.maxwidth1100{
max-width: 1100px;
overflow:hidden;
text-overflow:ellipsis;
white-space:nowrap;
font-size: 18px !important;
font-weight: 500;
color: rgba(51,51,51,1) !important;
}
.newshixunmodelmidfont{
font-size: 14px;
font-weight: 400;
color: #999999;
margin-top: 15px;
margin-left: 30px;
max-width: 1100px;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.newshixunmodelbotfont{
font-size:12px;
font-weight:400;
color:rgba(102,102,102,1);
margin-top: 15px;
margin-left: 30px;
}
.newshixunlist{
max-height:227px;
width: 1200px;
}
.xuxianpro {
height: 20px;
border-bottom: 1px dashed;
border-color: #eaeaea;
margin-bottom: 18px;
}
.newshixunpd030{
padding: 0px 30px;
}
.pd303010{
padding: 30px 30px 10px;
}
.newshixunfont12{
font-size: 12px;
color: rgba(76,172,255,1);
line-height: 21px;
}
.newshixunmode{
width: 100px;
height: 38px;
border-radius: 3px;
border: 1px solid rgba(191,191,191,1);
}
.ntopsj {
position: absolute;
top: -4px;
}
.nyslbottomsj {
position: absolute;
bottom: -6px;
}
.inherits .ant-dropdown-menu-item{
cursor: inherit !important;
}
.menus{
width: 91px;
text-align: center;
}
.newshixunmodelbotfont span{
display: inline-block;
margin-right: 34px;
}
.minhegiht300{
min-height: 300px;
}
.newshixunlist:hover{
box-shadow: 1px 6px 16px rgba(156,156,156,0.16);
opacity: 1;
border-radius: 2px;
}
.newshixun500{
max-width: 500px;
overflow: hidden;
-o-text-overflow: ellipsis;
text-overflow: ellipsis;
white-space: nowrap;
}
.mt3 {
margin-top: 3px !important;
}
.highlight{
color: #4CACFF;
}

@ -1,120 +1,122 @@
import React,{ Component } from "react";
import { Modal,Checkbox,Select,Input,Tooltip} from "antd";
import axios from'axios';
import ShixunModal from './ShixunModal'
const Option = Select.Option;
const Search = Input.Search;
class ShixunChooseModal extends Component{
constructor(props){
super(props);
this.state={
shixunmodal: false,
hometypepvisible: false,
}
}
setVisible = (visible) => {
if (visible) {
this.createCommonWork()
} else {
this.setState({ shixunmodal: visible })
}
}
hidecouseShixunModal = () => {
this.setVisible(false)
}
componentDidMount() {
}
funshixunmodallist=(search,type,loading,page)=>{
let{newshixunmodallist}=this.state;
let newshixunmodallists=[]
if(page>1){
newshixunmodallists=newshixunmodallist;
}
this.setState({
hometypepvisible:loading
})
let coursesId=this.props.match.params.coursesId;
let url = this.props.shixunsUrl || "/courses/"+coursesId+"/homework_commons/shixuns.json";
axios.get(url, {
params: {
search: search,
type:type,
page:page
}
}).then((result)=>{
if(result.status===200){
let shixun_list=result.data.shixun_list;
for(var i=0; i<shixun_list.length;i++){
newshixunmodallists.push(shixun_list[i])
}
this.setState({
shixunmodal:true,
shixunmodallist:result.data,
newshixunmodallist:newshixunmodallists,
hometypepvisible:false
})
}
}).catch((error)=>{
console.log(error);
})
}
funpatheditarry=(list)=>{
this.setState({
patheditarry:list
})
}
createCommonWork=()=>{
this.setState({
hometypepvisible:true,
patheditarry:[]
})
let coursesId=this.props.match.params.coursesId;
let url = this.props.shixunsUrl || "/courses/"+coursesId+"/homework_commons/shixuns.json";
axios.get(url).then((result)=>{
if(result.status===200){
this.setState({
shixunmodal:true,
shixunmodallist:result.data,
hometypepvisible:false,
newshixunmodallist:result.data.shixun_list,
})
}
}).catch((error)=>{
console.log(error);
})
}
render(){
let {Searchvalue,type,category_id, datas, shixunmodal, shixunmodallist
, hometypepvisible, newshixunmodallist, patheditarry }=this.state;
let {visible}=this.props;
// console.log(patheditarry)
return(
<ShixunModal
datas={datas}
category_id={this.props.match.params.category_id}
visible={shixunmodal}
shixunmodallist={shixunmodallist}
funshixunmodallist={(search,type,loading,page)=>this.funshixunmodallist(search,type,loading,page)}
hometypepvisible={hometypepvisible}
hidecouseShixunModal={this.hidecouseShixunModal}
newshixunmodallist={newshixunmodallist}
coursesId={this.props.match.params.coursesId}
courseshomeworkstart={(category_id,homework_ids)=> this.props.newhomeworkstart
&& this.props.newhomeworkstart(category_id,homework_ids)}
funpatheditarry={(patheditarry)=>this.funpatheditarry(patheditarry)}
patheditarry={patheditarry}
{...this.props}
></ShixunModal>
)
}
}
import React,{ Component } from "react";
import { Modal,Checkbox,Select,Input,Tooltip} from "antd";
import axios from'axios';
import NewShixunModel from '../coursesPublic/NewShixunModel';
const Option = Select.Option;
const Search = Input.Search;
class ShixunChooseModal extends Component{
constructor(props){
super(props);
this.state={
shixunmodal: false,
hometypepvisible: false,
}
}
setVisible = (visible) => {
// if (visible) {
// this.createCommonWork()
// } else {
//
// }
this.setState({ shixunmodal: visible })
}
hidecouseShixunModal = () => {
this.setVisible(false)
}
componentDidMount() {
}
funshixunmodallist=(search,type,loading,page)=>{
let{newshixunmodallist}=this.state;
let newshixunmodallists=[]
if(page>1){
newshixunmodallists=newshixunmodallist;
}
this.setState({
hometypepvisible:loading
})
let coursesId=this.props.match.params.coursesId;
let url = this.props.shixunsUrl || "/courses/"+coursesId+"/homework_commons/shixuns.json";
axios.get(url, {
params: {
search: search,
type:type,
page:page
}
}).then((result)=>{
if(result.status===200){
let shixun_list=result.data.shixun_list;
for(var i=0; i<shixun_list.length;i++){
newshixunmodallists.push(shixun_list[i])
}
this.setState({
shixunmodal:true,
shixunmodallist:result.data,
newshixunmodallist:newshixunmodallists,
hometypepvisible:false
})
}
}).catch((error)=>{
console.log(error);
})
}
funpatheditarry=(list)=>{
this.setState({
patheditarry:list
})
}
createCommonWork=()=>{
this.setState({
hometypepvisible:true,
patheditarry:[]
})
let coursesId=this.props.match.params.coursesId;
let url = this.props.shixunsUrl || "/courses/"+coursesId+"/homework_commons/shixuns.json";
axios.get(url).then((result)=>{
if(result.status===200){
this.setState({
shixunmodal:true,
shixunmodallist:result.data,
hometypepvisible:false,
newshixunmodallist:result.data.shixun_list,
})
}
}).catch((error)=>{
console.log(error);
})
}
render(){
let {Searchvalue,type,category_id, datas, shixunmodal, shixunmodallist
, hometypepvisible, newshixunmodallist, patheditarry }=this.state;
let {visible}=this.props;
// console.log(patheditarry)
return(
shixunmodal===true?<NewShixunModel
statustype={'published'}
datas={datas}
category_id={this.props.match.params.category_id}
NewShixunModelType={shixunmodal}
shixunmodallist={shixunmodallist}
funshixunmodallist={(search,type,loading,page)=>this.funshixunmodallist(search,type,loading,page)}
hometypepvisible={hometypepvisible}
hideNewShixunModelType={this.hidecouseShixunModal}
newshixunmodallist={newshixunmodallist}
coursesId={this.props.match.params.coursesId}
courseshomeworkstart={(category_id,homework_ids)=> this.props.newhomeworkstart
&& this.props.newhomeworkstart(category_id,homework_ids)}
funpatheditarry={(patheditarry)=>this.funpatheditarry(patheditarry)}
patheditarry={patheditarry}
{...this.props}
></NewShixunModel>:""
)
}
}
export default ShixunChooseModal;

@ -29,12 +29,14 @@ class Elearning extends Component{
userlogin:"",
isRender:false,
subject_id:0,
myupdataleftNavs:this.myupdataleftNav
}
}
componentDidMount() {
// 记得删除退出课堂
// console.log("获取到数据");
// console.log("在线学习");
// console.log("获取到数据");
// console.log(this.props);
this.getdata();
}
@ -289,6 +291,9 @@ class Elearning extends Component{
})
};
myupdataleftNav=()=>{
this.props.updataleftNavfun();
}
render(){
console.log("Elearning++++++++");
// console.log(this.props.Chapterupdate);
@ -397,7 +402,7 @@ class Elearning extends Component{
<div>
{/*开始学习*/}
<YslDetailCards {...this.state} {...this.props} Startlearningtwo={()=>this.Startlearningtwo()} Myreload={()=>this.Myreload()} Tojoinclass={()=>this.Tojoinclass()} getPathCardsList={()=>this.getdata()}></YslDetailCards>
<YslDetailCards {...this.state} {...this.props} Startlearningtwo={()=>this.Startlearningtwo()} Myreload={()=>this.Myreload()} Tojoinclass={()=>this.Tojoinclass()} getPathCardsList={()=>this.getdata()} ></YslDetailCards>
</div>

@ -210,7 +210,7 @@ class YslDetailCards extends Component{
//取消
//确认
updatapathCardsedit=()=>{
this.setState({
idsum:undefined,
@ -219,9 +219,10 @@ class YslDetailCards extends Component{
editbuttomtypeadd:false
})
this.props.getPathCardsList();
this.props.myupdataleftNavs();
// this.props.updatadetailInfoLists();
};
//确认
//取消
editeditbuttomtypecanle=()=>{
this.setState({
editbuttomtype:true,
@ -300,6 +301,7 @@ class YslDetailCards extends Component{
this.updatapathCardsedit()
this.props.showNotification(`删除成功`);
this.props.myupdataleftNavs();
}else {
this.props.showNotification(`删除失败`);
}

@ -77,7 +77,9 @@ class ExerciseReviewAndAnswer extends Component{
exerciseTotalScore:undefined,
// 加载效果
isSpin:false
isSpin:false,
// 调分数组
ajustSore:undefined
}
}
componentDidUpdate (prevProps) {
@ -190,7 +192,23 @@ class ExerciseReviewAndAnswer extends Component{
user_exercise_status:1,
Id:result.data.exercise_answer_user.user_id,
exerciseTotalScore:result.data.exercise_answer_user.score,
isSpin:false
isSpin:false,
})
// 先将未批的简答题放入到调分数组中
let ajustSore = [];
result.data && result.data.exercise_questions.length>0 && result.data.exercise_questions.map((item,key)=>{
if( item.question_type == 4 && item.answer_status == 0 ){
ajustSore.push({
inputSore:0,
desc:undefined,
id:item.question_id,
position:item.q_position,
setTip:""
})
}
})
this.setState({
ajustSore
})
}
}).catch((error)=>{
@ -227,7 +245,7 @@ class ExerciseReviewAndAnswer extends Component{
}
scrollToAnchor=(index)=>{
let name="Anchor_"+index;
console.log($("#Anchor_"+index).scrollTop());
// console.log($("#Anchor_"+index).scrollTop());
if (index) {
// let anchorElement = document.getElementById(name);
// if(anchorElement) { anchorElement.scrollIntoView(); }
@ -244,62 +262,115 @@ class ExerciseReviewAndAnswer extends Component{
)
}
// 调分
showSetScore=(key,flag,setId)=>{
showSetScore=(key,flag,position,type,id)=>{
this.setState(
(prevState) => ({
exercise_questions : update(prevState.exercise_questions, {[key]: { setScore: {$set: flag == undefined || flag==false ? true : false}}})
}),()=>{
if (setId && (flag == undefined || flag==false)) {
$("html").animate({ scrollTop: $("#Anchor_"+setId).offset().top - 150 })
if (position && type && (flag == undefined || flag==false)) {
$("#input_"+position+"_"+type).focus();
$("html").animate({ scrollTop: $("#Anchor_"+position+"_"+type).offset().top - 150 });
if(id){
let { ajustSore } = this.state;
let obj = ajustSore.filter(obj => obj.id === id).length > 0;
if(!obj){
ajustSore.push({
id,
inputSore:0,
desc:undefined,
position:position,
setTip:""
})
}
}
}
}
)
this.setState({
score:undefined
})
// this.setState({
// score:undefined
// })
}
inputScore=(value)=>{
inputScore=(value,id)=>{
let { ajustSore } = this.state;
var index = ajustSore.map(function (item) { return item.id; }).indexOf(id);
let reg = /^[0-9]+.?[0-9]*$/;
if(reg.test(value)==false){
this.setState({
setTip:"请输入数字"
})
// this.setState({
// setTip:"请输入数字"
// })
this.setState(
(prevState) => ({
ajustSore : update(prevState.ajustSore, {[index]: { setTip: {$set: "请输入数字"}}})
})
)
return;
}else{
this.setState({
setTip:"",
score:value
})
// this.setState({
// setTip:"",
// score:value
// })
this.setState(
(prevState) => ({
ajustSore : update(prevState.ajustSore, {[index]: { inputSore: {$set: value},setTip:{$set: ""}}})
})
)
}
}
changeScoreReasons=(e)=>{
console.log(e.target.value);
this.setState({
setScoreReason:e.target.value
})
changeScoreReasons=(e,id)=>{
// console.log(e.target.value);
// this.setState({
// setScoreReason:e.target.value
// })
let value = e.target.value;
let { ajustSore } = this.state;
var index = ajustSore.map(function (item) { return item.id; }).indexOf(id);
this.setState(
(prevState) => ({
ajustSore : update(prevState.ajustSore, {[index]: { desc: {$set: value}}})
})
)
}
//确认调分
setAction=(key,q_id,maxScore)=>{
let{ score,setScoreReason ,setTip }=this.state;
setAction=(key,q_id,maxScore,oldScore)=>{
let {ajustSore}=this.state;
let list = ajustSore.filter(obj => obj.id == q_id);
let index = ajustSore.map(function (item) { return item.id; }).indexOf(q_id);
let score = list[0].inputSore;
let setScoreReason = list[0].desc;
let{ setTip }=this.state;
if(!score && score != 0){
this.setState({
setTip:"请输入分数"
})
// this.setState({
// setTip:"请输入分数"
// })
this.setState(
(prevState) => ({
ajustSore : update(prevState.ajustSore, {[index]: { setTip: {$set: "请输入分数"}}})
})
)
return;
}
if(score < 0){
this.setState({
setTip:"分数必须大于或者等于0"
})
// this.setState({
// setTip:"分数必须大于或者等于0"
// })
this.setState(
(prevState) => ({
ajustSore : update(prevState.ajustSore, {[index]: { setTip: {$set: "分数必须大于或者等于0"}}})
})
)
return;
}
if(score > maxScore){
this.setState({
setTip:"分数不能大于当前题目的分数"
})
// this.setState({
// setTip:"分数不能大于当前题目的分数"
// })
this.setState(
(prevState) => ({
ajustSore : update(prevState.ajustSore, {[index]: { setTip: {$set: "分数不能大于当前题目的分数"}}})
})
)
return;
}
if(setTip==""){
@ -311,21 +382,26 @@ class ExerciseReviewAndAnswer extends Component{
}).then((result)=>{
if(result.status==200){
this.props.showNotification('调分成功');
console.log(this.state.exercise_questions);
let statusScore = score==0 ? 0 : score > 0 && score < maxScore ? 2 : 1;
console.log(statusScore);
this.setState(
(prevState) => ({
exercise_questions : update(prevState.exercise_questions, {[key]: { user_score: {$set: score},answer_status : {$set: statusScore},question_comments:{$set:result.data.question_comments} }}),
})
)
console.log(this.state.exercise_questions);
this.setState({
score:undefined,
setTip:"",
setScoreReason:undefined
})
this.showSetScore(key,true);
this.getInfo();
// let statusScore = score==0 ? 0 : score > 0 && score < maxScore ? 2 : 1;
// this.setState(
// (prevState) => ({
// exercise_questions : update(prevState.exercise_questions, {[key]: { user_score: {$set: parseFloat(score).toFixed(1)},answer_status : {$set: statusScore},question_comments:{$set:result.data.question_comments} }}),
// })
// )
// this.setState(
// (prevState) => ({
// ajustSore : update(prevState.ajustSore, {[index]: { desc: {$set: undefined},inputSore:{ $set:undefined }}})
// })
// )
// let {exerciseTotalScore} = this.state;
// let newScore = parseFloat(parseFloat(exerciseTotalScore)+parseFloat(score)-parseFloat(oldScore)).toFixed(1);
// this.setState({
// exerciseTotalScore:newScore
// })
// this.showSetScore(key,true);
}
}).catch((error)=>{
console.log(error);
@ -518,12 +594,13 @@ class ExerciseReviewAndAnswer extends Component{
ModalSave,
Loadtype,
exerciseTotalScore,
isSpin
isSpin,
ajustSore
}=this.state
let isAdmin = this.props.isAdmin();
let isStudent =this.props.isStudent();
const { current_user } = this.props
console.log(data&&data.exercise.user_name)
// console.log(data&&data.exercise.user_name)
return(
<div className="newMain" style={{paddingTop:"0px"}}>
<Spin size="large" spinning={isSpin}>
@ -709,6 +786,7 @@ class ExerciseReviewAndAnswer extends Component{
<div>
{
exercise_questions && exercise_questions.map((item,key)=>{
let list = ajustSore && ajustSore.filter(obj => obj.id === item.question_id);
return(
<div className="bor-top-greyE pt30 pb30" id={"Anchor_"+parseInt(key+1)}>
<p className="clearfix font-16 pl30 pr30">
@ -716,32 +794,32 @@ class ExerciseReviewAndAnswer extends Component{
<span className="fr">
{
// 填空(一直都有调分),和简答题调分:老师身份 已经评分的才能出现调分按钮
isAdmin && ((parseInt(item.answer_status) != 0 && item.question_type == 4) || item.question_type == 3) ?
<WordsBtn style="blue" className="mr20 font-16 fl" onClick={()=>this.showSetScore(key,item.setScore,item.q_position+"_"+item.question_type)}>调分</WordsBtn>:""
isAdmin && ((parseInt(item.answer_status) != 0 && item.question_type == 4) || item.question_type == 3 || item.question_type == 1) ?
<WordsBtn style="blue" className="ml20 font-16 fl" onClick={()=>this.showSetScore(key,item.setScore,item.q_position,item.question_type,item.question_id)}>调分</WordsBtn>:""
}
{
// 简答题,未评分的显示未批
isAdmin && parseInt(item.answer_status) == 0 && item.question_type == 4 ?
<span className="color-red fl mr20">未批</span>:""
<span className="color-red fl ml20">未批</span>:""
}
{
// 客观题:老师||学生(试卷已截止且答案公开)显示正确答案
item.question_type < 3 && item.standard_answer_show ?
<span className="font-16 ml20">
<span className="font-16 fl ml20">
正确答案{ item.standard_answer_show }
</span>:""
}
{
//(老师身份且除实训题外) || (学生身份且试卷已经截止)就显示用户当前题目所得分数
( isAdmin || (isStudent && exercise.exercise_status == 3)) && item.question_type != 5 && item.user_score ?
<span className="font-16 ml20">
<span className="font-16 ml20 fl">
<span><span className={parseInt(item.answer_status) == 0 ?"color-red":parseInt(item.answer_status) == 1 ?"color-green":"color-orange-tip"}>{item.user_score}</span> </span>
</span> : ""
}
{
//实训题 ,答题
item.question_type == 5 &&
<a href={"/shixuns/"+item.shixun_identifier+"/challenges"} target="_blank" class="font-16 color-blue" target={"_blank"}>实训详情</a>
<a href={"/shixuns/"+item.shixun_identifier+"/challenges"} target="_blank" class="font-16 color-blue fl" target={"_blank"}>实训详情</a>
}
</span>
</p>
@ -825,7 +903,7 @@ class ExerciseReviewAndAnswer extends Component{
{
//调分理由部分
item.question_comments && item.question_comments.comment && (item.question_type == 3 || item.question_type == 4) &&
item.question_comments && item.question_comments.comment && (item.question_type == 3 || item.question_type == 4 || item.question_type == 1) &&
<div className="ml30 mr30 bor-top-greyE pt30 mt20 clearfix df">
<img src={getImageUrl(`images/${item.question_comments.user_picture}`)} width="48" height="48" className="radius mr10"/>
<div className="flex1">
@ -839,7 +917,7 @@ class ExerciseReviewAndAnswer extends Component{
}
{
// 调分输入部分
isAdmin && ((item.setScore && item.question_type == 3) || ((item.setScore || parseInt(item.answer_status) == 0) && item.question_type == 4))?
isAdmin && ((item.setScore && item.question_type == 3) || (item.setScore && item.question_type == 1) || ((item.setScore || parseInt(item.answer_status) == 0) && item.question_type == 4))?
<div className="ml30 mr30 bor-top-greyE pt20 mt20" id={`${"Anchor_"+item.q_position+"_"+item.question_type}`}>
<div className="edu-txt-right">
<span><span className="color-red">*</span></span>
@ -848,25 +926,26 @@ class ExerciseReviewAndAnswer extends Component{
<InputNumber
placeholder="请填写分数"
min={0}
max={item.question_score}
value={score}
// max={item.question_score}
value={list && list.length>0 && list[0].inputSore}
step={0.1}
precision={1}
className={ setTip !="" ? "edu-txt-center winput-115-40 fl mt3 noticeTip inputNumber30" : "edu-txt-center winput-115-40 fl mt3 inputNumber30"}
onChange={this.inputScore}
className={ list && list.length>0 && list[0].setTip !="" ? "edu-txt-center winput-115-40 fl mt3 noticeTip inputNumber30" : "edu-txt-center winput-115-40 fl mt3 inputNumber30"}
onChange={(value)=>this.inputScore(value,item.question_id)}
id={`${"input_"+item.q_position+"_"+item.question_type}`}
></InputNumber>
<span className="ml5"></span>
{
parseInt(item.answer_status) == 0 && item.question_type == 4 ? <span className="color-red ml10 font-16">未评分</span> : ''
}
<ActionBtn style="blue" className="middle ml20" onClick={()=>this.setAction(key,item.question_id,item.question_score)}>确认</ActionBtn>
<ActionBtn style="blue" className="middle ml20" onClick={()=>this.setAction(key,item.question_id,item.question_score,item.user_score)}>确认</ActionBtn>
</p>
{
setTip !="" ? <p className="color-red edu-txt-left">{setTip}</p> :""
list && list.length > 0 && list[0].setTip !="" ? <p className="color-red edu-txt-left">{ list[0].setTip }</p> :""
}
</li>
</div>
<Textarea className="winput-100-150 mt20" value={setScoreReason} style={{height:"180px"}} maxLength="100" onChange={this.changeScoreReasons} placeholder="请您输入评语最大限制100个字符"></Textarea>
<Textarea className="winput-100-150 mt20" value={list && list.length>0 && list[0].desc} style={{height:"180px"}} maxLength="100" onChange={(e)=>this.changeScoreReasons(e,item.question_id)} placeholder="请您输入评语最大限制100个字符"></Textarea>
</div>:""
}
</div>

@ -182,6 +182,10 @@ class SingleEditor extends Component{
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 })

@ -683,7 +683,7 @@ class studentsList extends Component{
{isAdmin && <li className="li_line"><a href="javascript:void(0)" className="color-grey-9" onClick={this.onDelete}>删除</a></li>}
{isAdmin && <li className="drop_down">
移动到...<i className="iconfont icon-xiajiantou font-12 ml2"></i>
<ul className="drop_down_menu" style={{"right":"0px","left":"unset", minWidth: '160px', maxHeight: '324px', overflowY: 'auto'}}>
<ul className="drop_down_menu" style={{"right":"0px","left":"unset", width: '200px', maxHeight: '324px', overflowY: 'auto'}}>
{
course_groups && course_groups.length > 9 ?
(<p className="drop_down_search">

@ -35,10 +35,15 @@ class ShixunWorkDetails extends Component {
}
}).then((result) => {
if (result.status === 200) {
this.setState({
data:result.data,
spinning:false
})
if (result.data.status === 403 || result.data.status === 401 || result.data.status === 407 || result.data.status === 408|| result.data.status === 409 || result.data.status === 500) {
}else{
this.setState({
data:result.data,
spinning:false
})
}
}
}).catch((error) => {
console.log(error)
@ -50,7 +55,33 @@ class ShixunWorkDetails extends Component {
shixuntypes:type[3]
})
}
updatas=()=>{
this.setState({
spinning:true
})
let homeworkid=this.props.match.params.homeworkid;
let userid=this.props.match.params.userid;
let url = "/homework_commons/"+homeworkid+"/code_review_detail.json";
axios.get(url,{
params: {
user_id:userid,
}
}).then((result) => {
if (result.status === 200) {
if (result.data.status === 403 || result.data.status === 401 || result.data.status === 407 || result.data.status === 408|| result.data.status === 409 || result.data.status === 500) {
}else{
this.setState({
data:result.data,
spinning:false
})
}
}
}).catch((error) => {
console.log(error)
})
}
goback=(sum)=>{
// let{data}=this.state
// if(sum===1){
@ -102,14 +133,18 @@ class ShixunWorkDetails extends Component {
<span className="fl color-orange font-14">非编程类型任务不参与查重</span>
<span className="fr mt4">
<span className={"color656565"}>被查作品</span>
<span className={"mr20"}>{data&&data.username}</span>
<span className={"color-orange"}>{data&&data.final_score}</span>
<span className={"mr50"}><span className={"color-orange"}>{data&&data.username}</span></span>
{data&&data.eff_score===null||data&&data.eff_score===undefined||data&&data.eff_score_full===null||data&&data.eff_score_full===undefined?"":<span className={"mr50"}>效率分<span className={"color-orange"}>{data&&data.eff_score}</span>/{data&&data.eff_score_full}</span>}
<span className={""}>最终成绩<span className={"color-orange"}>{data&&data.final_score}</span></span>
</span>
</div>
<div className="stud-class-set bor-bottom-greyE">
<div className="clearfix edu-back-white poll_list">
<ShixunCustomsPass
{...this.props}
{...this.state}
updatas={()=>this.updatas()}
data={data}
/>
</div>

@ -1,10 +1,10 @@
import React, {Component} from "react";
import {WordsBtn} from 'educoder';
import {Table} from "antd";
import {Table,InputNumber} from "antd";
import {Link,Switch,Route,Redirect} from 'react-router-dom';
import moment from 'moment';
import { MonacoDiffEditor } from 'react-monaco-editor';
import axios from 'axios';
class ShixunCustomsPass extends Component {
constructor(props) {
@ -18,10 +18,51 @@ class ShixunCustomsPass extends Component {
componentDidMount() {
}
editgame_scores=(e,id,maxsum,code_rate,copy_user_id)=>{
let{datas}=this.state;
let newdatas=datas;
let score=e.target.value;
if(score!=null&&score!=undefined&&score!=""){
if(score<0){
this.props.showNotification("不能小于0");
this.setState({
customsids:id
})
}else if(score>maxsum){
this.props.showNotification(`不能大于关卡分值${maxsum}`);
this.setState({
customsids:id
})
}else{
let work_id=this.props.data.work_id;
let url=`/student_works/${work_id}/adjust_review_score.json`
axios.post(url,{
type:"review",
score:score,
challenge_id:id,
code_rate:code_rate,
copy_user_id:copy_user_id
}).then((result)=>{
if(result.data.status===0){
this.props.updatas();
this.props.showNotification(result.data.message);
}else{
this.props.showNotification(result.data.message);
}
}).catch((error)=>{
})
}
}else{
this.props.showNotification("调分为空将不会修改之前的分数");
}
}
render() {
let {data}=this.props;
console.log(data)
let {customsids}=this.state;
// console.log(data)
let datas=[];
data&&data.challenge_list.forEach((item,key)=>{
@ -33,6 +74,8 @@ class ShixunCustomsPass extends Component {
finishtime:item.copy_username,
elapsedtime:item.copy_end_time===null?"无":item.copy_end_time===undefined?"无":item.copy_end_time===""?"无":moment(item.copy_end_time).format('YYYY-MM-DD HH:mm:ss'),
empvalue:item.code_rate,
challenge_id:{id:item.id},
copy_user_id:item.copy_user_id
// adjustmentminute:asdasd
})
})
@ -112,6 +155,22 @@ class ShixunCustomsPass extends Component {
render: (text, record) => (
<span className={"color-grey-9"}>
{record.elapsedtime}
</span>
),
},{
title: '调分',
key: 'adjustmentminute',
dataIndex: 'adjustmentminute',
render: (text, record) => (
<span>
<a>
{record.copy_user_id===null?"":<InputNumber size="small" className={customsids===record.challenge_id.id?"bor-red":""} defaultValue={record.evaluating.final_score}
onBlur={(e) => this.editgame_scores(e,record.challenge_id.id,record.evaluating.all_score,record.empvalue,record.copy_user_id)}
// min={0} max={record.game_scores.game_score_full}
/>}
</a>
{/*<a style={{textAlign: "center"}} className="color-blue font-14 mr20">查看</a>*/}
</span>
),
}, {
@ -138,7 +197,15 @@ class ShixunCustomsPass extends Component {
// },
if(this.props.isAdmin()===false){
columns.some((item,key)=> {
if (item.title === "调分") {
columns.splice(key, 1)
return true
}
}
)
}
return (
<div>
@ -177,6 +244,9 @@ class ShixunCustomsPass extends Component {
.customsPass{
text-align: left !important;
}
.ant-table-thead > tr > th, .ant-table-tbody > tr > td {
padding: 16px 12px;
}
`}
</style>
{datas===undefined?"":<Table

@ -6,6 +6,7 @@ import axios from'axios';
import HomeworkModal from "../coursesPublic/HomeworkModal";
import ShixunModal from "../coursesPublic/ShixunModal";
import PathModal from "../coursesPublic/PathModal";
import NewShixunModel from '../coursesPublic/NewShixunModel';
import AddcoursesNav from "../coursesPublic/AddcoursesNav";
import Modals from '../../modals/Modals';
import moment from 'moment';
@ -445,18 +446,18 @@ class ShixunHomework extends Component{
}
// 选用实训
createCommonWork=()=>{
this.setState({
hometypepvisible:true,
shixunmodal:true,
patheditarry:[],
checkBoxValues:[]
})
}
// // 选用实训
// createCommonWork=()=>{
//
// this.setState({
// hometypepvisible:true,
// shixunmodal:true,
// patheditarry:[],
// checkBoxValues:[]
// })
//
//
// }
// 选用实训路径
createCommonpath=()=>{
@ -502,9 +503,9 @@ class ShixunHomework extends Component{
// }).then((result)=>{
// if(result.status===200){
//
// let shixun_list=result.data.shixun_list;
// for(var i=0; i<shixun_list.length;i++){
// newshixunmodallists.push(shixun_list[i])
// let shixun_lists=result.data.shixun_lists;
// for(var i=0; i<shixun_lists.length;i++){
// newshixunmodallists.push(shixun_lists[i])
// }
// this.setState({
// shixunmodal:true,
@ -540,9 +541,9 @@ class ShixunHomework extends Component{
// }).then((result)=>{
// if(result.status===200){
//
// let shixun_list=result.data.subject_list;
// for(var i=0; i<shixun_list.length;i++){
// newshixunmodallists.push(shixun_list[i])
// let shixun_lists=result.data.subject_list;
// for(var i=0; i<shixun_lists.length;i++){
// newshixunmodallists.push(shixun_lists[i])
// }
// this.setState({
// shixunpath:true,
@ -896,6 +897,18 @@ class ShixunHomework extends Component{
this.props.history.push(this.props.current_user.first_category_url);
}
}
showNewShixunModelType=()=>{
this.setState({
NewShixunModelType:true,
patheditarry:[],
checkBoxValues:[]
})
}
hideNewShixunModelType=()=>{
this.setState({
NewShixunModelType:false
})
}
render(){
let {
modalname,
@ -931,7 +944,7 @@ class ShixunHomework extends Component{
course_modules,
shixunpath,
order,
antIcon,
NewShixunModelType,
}=this.state;
let main_id=this.props.match.params.main_id;
@ -940,6 +953,23 @@ class ShixunHomework extends Component{
return(
<React.Fragment >
<div>
{/*新版实训model*/}
{NewShixunModelType===true?<NewShixunModel
{...this.props}
{...this.state}
category_id={this.props.match.params.category_id}
type={'shixuns'}
hideNewShixunModelType={()=>this.hideNewShixunModelType()}
coursesId={this.props.match.params.coursesId}
homeworkupdatalists={(Coursename,page,order)=>this.homeworkupdatalist(Coursename,page,order)}
Coursename={Coursename}
page={page}
order={order}
statustype={'published'}
/>:""}
{/*提示*/}
{Modalstype&&Modalstype===true?<Modals
modalsType={this.state.Modalstype}
@ -973,23 +1003,23 @@ class ShixunHomework extends Component{
getcourse_groupslist={(id)=>this.getcourse_groupslist(id)}
/>:""}
{/*选择实训*/}
{shixunmodal===true?<ShixunModal
{...this.props}
{...this.state}
datas={datas}
category_id={this.props.match.params.category_id}
visible={shixunmodal}
shixunmodallist={shixunmodallist}
homeworkupdatalists={(Coursename,page,order)=>this.homeworkupdatalist(Coursename,page,order)}
hometypepvisible={hometypepvisible}
hidecouseShixunModal={this.hidecouseShixunModal}
newshixunmodallist={newshixunmodallist}
coursesId={this.props.match.params.coursesId}
courseshomeworkstart={(category_id,homework_ids)=>this.newhomeworkstart(category_id,homework_ids)}
funpatheditarry={(patheditarry)=>this.funpatheditarry(patheditarry)}
patheditarry={patheditarry}
/>:""}
{/*/!*选择实训*!/*/}
{/*{shixunmodal===true?<ShixunModal*/}
{/*{...this.props}*/}
{/*{...this.state}*/}
{/*datas={datas}*/}
{/*category_id={this.props.match.params.category_id}*/}
{/*visible={shixunmodal}*/}
{/*shixunmodallist={shixunmodallist}*/}
{/*homeworkupdatalists={(Coursename,page,order)=>this.homeworkupdatalist(Coursename,page,order)}*/}
{/*hometypepvisible={hometypepvisible}*/}
{/*hidecouseShixunModal={this.hidecouseShixunModal}*/}
{/*newshixunmodallist={newshixunmodallist}*/}
{/*coursesId={this.props.match.params.coursesId}*/}
{/*courseshomeworkstart={(category_id,homework_ids)=>this.newhomeworkstart(category_id,homework_ids)}*/}
{/*funpatheditarry={(patheditarry)=>this.funpatheditarry(patheditarry)}*/}
{/*patheditarry={patheditarry}*/}
{/*/>:""}*/}
{shixunmodal===true||shixunpath===true?<style>
{
@ -1037,7 +1067,7 @@ class ShixunHomework extends Component{
{/*<span className="font-18 fl color-dark-21">{datas&&datas.category_name===undefined||datas&&datas.category_name===null?datas&&datas.main_category_name:datas&&datas.category_name+" 作业列表"}</span>*/}
<span className="font-18 fl color-dark-21">实训作业</span>
<li className="fr">
{datas===undefined?"":datas.homeworks && datas.homeworks.length>1?this.props.isClassManagement()===true?datas&&datas.category_name===undefined||datas&&datas.category_name===null?
{datas===undefined?"":datas.homeworks && datas.homeworks.length>1?this.props.isAdminOrCreator()===true?datas&&datas.category_name===undefined||datas&&datas.category_name===null?
<span>
<WordsBtn style="blue" className={"mr30 font-16"}>
<Link className="color4CACFF" to={`/courses/${this.props.match.params.coursesId}/ordering/shixun_homework/${main_id&&main_id}`}>调整排序</Link>
@ -1051,7 +1081,7 @@ class ShixunHomework extends Component{
</span>:
<WordsBtn style="blue" onClick={()=>this.editDir(datas&&datas.category_name)} className={"mr30 font-16"}>目录重命名</WordsBtn>:""}
{this.props.isAdmin()===true?datas&&datas.category_name===undefined||datas&&datas.category_name===null?<WordsBtn style="blue" className="mr30 font-16" onClick={this.createCommonpath}>选用实践课程</WordsBtn>:"":""}
{this.props.isAdmin()===true?<a className={"btn colorblue font-16"} onClick={()=>this.createCommonWork()}>选用实训</a>:""}
{this.props.isAdmin()===true?<a className={"btn colorblue font-16"} onClick={()=>this.showNewShixunModelType()}>选用实训</a>:""}
</li>
</p>

@ -101,9 +101,9 @@ function create_editorMD(id, width, high, placeholder, imageUrl, callback){
});
$("#"+ id +" [type=\"inline\"]").bind("click", function(){
editorName.cm.replaceSelection("$$$$");
editorName.cm.replaceSelection("`$$$$`");
var __Cursor = editorName.cm.getDoc().getCursor();
editorName.cm.setCursor(__Cursor.line, __Cursor.ch-2);
editorName.cm.setCursor(__Cursor.line, __Cursor.ch-3);
editorName.cm.focus();
});
$("[type=\"inline\"]").attr("title", "行内公式");

@ -208,11 +208,12 @@ class MainContentContainer extends Component {
if (!this.props || !this.props.game
|| ( newProps.game.identifier !== this.props.game.identifier ) ) {
setTimeout(this.fetchRepositoryCode( newProps), 1500);
} else if ( this.props.challenge.pathIndex != newProps.challenge.pathIndex
&& newProps.challenge.pathIndex !== -1) { // 切换到只读文件
}
// else if ( this.props.challenge.pathIndex != newProps.challenge.pathIndex
// && newProps.challenge.pathIndex !== -1) { // 切换到只读文件
// pathIndex切换
setTimeout(this.fetchRepositoryCode( newProps), 1500);
}
// setTimeout(this.fetchRepositoryCode( newProps), 1500);
// }
}
if (newProps.myshixun) {
var stageId = newProps.match.params.stageId;
@ -231,9 +232,13 @@ class MainContentContainer extends Component {
// 切换关卡时,停止轮训
this.oldGameIdentifier = prevProps.game.identifier;
this.doFileUpdateRequestOnCodeMirrorBlur(prevProps)
} else if (challenge && (challenge.pathIndex || prevProps.challenge.pathIndex) && challenge.pathIndex != prevProps.challenge.pathIndex) {
}
// else if (this.props.shixun && this.props.shixun.code_edit_permission && this.state.currentPath != prevState.currentPath) {
// this.doFileUpdateRequestOnCodeMirrorBlur(prevProps)
// }
else if (challenge && (challenge.pathIndex || prevProps.challenge.pathIndex) && challenge.pathIndex != prevProps.challenge.pathIndex) {
this.doFileUpdateRequestOnCodeMirrorBlur(prevProps)
}
}
}
@ -253,6 +258,9 @@ class MainContentContainer extends Component {
this.setState({ codeLoading: false });
return;
}
if (type && arg_path) {
this.doFileUpdateRequestOnCodeMirrorBlur(this.props)
}
const stageId = game.identifier
let path;
let isEditablePath = false;
@ -300,11 +308,12 @@ class MainContentContainer extends Component {
// })
}).then((fetchRepositoryCodeResponse) => {
// monaca 需要刷新,不然无法编辑
if (this.retryAndRefresh && fetchRepositoryCodeResponse.data.content) {
this.retryAndRefresh = false;
window.location.reload()
return;
}
// 加了dispose应该不会重现了暂时注释掉reload
// if (this.retryAndRefresh && fetchRepositoryCodeResponse.data.content) {
// this.retryAndRefresh = false;
// window.location.reload()
// return;
// }
// 空字符串还是正常切换
if (fetchRepositoryCodeResponse.data.status == 0) {
readingRepoTimes = readingRepoTimes + 1;
@ -383,9 +392,16 @@ class MainContentContainer extends Component {
// var fileUpdatePromise = this.doFileUpdateRequest(true)
// });
// }
window.addEventListener("beforeunload", this.beforeunload);
}
componentWillUnmount() {
// window.$(window).off( "unload" )
window.removeEventListener("beforeunload", this.beforeunload);
}
beforeunload = () => {
this.doFileUpdateRequestOnCodeMirrorBlur()
}
@ -515,7 +531,7 @@ class MainContentContainer extends Component {
let codeContent = this.state.repositoryCode;
if (window['editor_CodeMirror']) {
codeContent = window.editor_CodeMirror.getValue();
} else if (window.editor_monaco) {
} else if (window.editor_monaco && window.editor_monaco.getModel()) { // (编程切选择题) 如果dispose了model为空
codeContent = window.editor_monaco.getValue()
}
if (checkIfCodeChanged === true && this.oldRepositoryCode == codeContent) {
@ -535,7 +551,9 @@ class MainContentContainer extends Component {
this.oldRepositoryCode = codeContent;
let argPath;
if (challenge.pathIndex === -1) { // 当前是只读文件
if (this.props.shixun && this.props.shixun.code_edit_permission == true) {
argPath = this.state.currentPath
} else if (challenge.pathIndex === -1) { // 当前是只读文件
argPath = challenge.multiPath === true ? challenge.path[0] : challenge.path
} else {
argPath = challenge.multiPath === true ? challenge.path[challenge.pathIndex] : challenge.path
@ -624,6 +642,11 @@ class MainContentContainer extends Component {
gameBuilding: false
})
}
onPathChange = (index, isDropDown) => {
this.props.onPathChange(index, () => {
isDropDown && this.fetchRepositoryCode()
})
}
onRunCodeTest() {
// tipContent(0, 100, 30, 360, 1)
// return; // for test
@ -634,7 +657,7 @@ class MainContentContainer extends Component {
showDialog({
contentText: '需要先切回可编辑的文件才可评测,确认要现在切换吗?',
callback: () => {
onPathChange(0)
this.onPathChange(0, true)
handleGdialogClose();
}
})
@ -957,7 +980,9 @@ class MainContentContainer extends Component {
onRepositoryCodeUpdate={this.onRepositoryCodeUpdate} onRunCodeTest={this.onRunCodeTest}
codemirrorDidMount={this.codemirrorDidMount} fetchRepositoryCode={this.fetchRepositoryCode}
showResetCodeDialog={this.showResetCodeDialog} showResetPassedCodeDialog={this.showResetPassedCodeDialog}
doFileUpdateRequestOnCodeMirrorBlur={this.doFileUpdateRequestOnCodeMirrorBlur} ></MainContent>
doFileUpdateRequestOnCodeMirrorBlur={this.doFileUpdateRequestOnCodeMirrorBlur}
onPathChange={this.onPathChange}
></MainContent>
</React.Fragment>
);

@ -1,6 +1,6 @@
import React, { Component } from 'react';
import axios from 'axios'
import { Spin } from 'antd'
import { Spin, Icon } from 'antd'
import ClipboardJS from 'clipboard'
import VNCDisplay from './VNCDisplay'
@ -22,7 +22,9 @@ class VNCContainer extends Component {
this.state = {
fileTreeSelectedKeys: [],
repositoryCode: '',
displayKey: 1
displayKey: 1,
vnc_reseting: false,
}
}
componentDidMount() {
@ -116,6 +118,7 @@ class VNCContainer extends Component {
this.setState({ bottomDrawer: true })
}
onResetVNC = () => {
if (this.state.vnc_reseting) return;
// 桌面系统将恢复到初始状态,您在系统中创建的数据可能会丢失
// 请确保您的数据已保存(如:版本库代码已推送到服务器)
// 是否确认重置?
@ -127,13 +130,15 @@ class VNCContainer extends Component {
</div>,
onOk: () => {
const url = `/tasks/${this.props.game.identifier}/reset_vnc_link.json`
this.setState({ vnc_reseting: true })
axios.get(url, {
}).then((response) => {
if (response.data.data && response.data.data.vnc_url) {
// reset
this.setState({
displayKey: this.state.displayKey + 1,
vnc_url: response.data.data.vnc_url
vnc_url: response.data.data.vnc_url,
vnc_reseting: false
})
} else {
}
@ -141,7 +146,7 @@ class VNCContainer extends Component {
}).catch(error =>{
console.log(error)
this.setState({ readingCodeLoading: false });
this.setState({ vnc_reseting: false });
this.props.showSnackbar(`服务端异常,请联系管理员!`);
})
@ -270,15 +275,23 @@ class VNCContainer extends Component {
></RepoTree>
</SecondDrawer>
<FloatButton className="resetVNC" onClick={this.onResetVNC}>
<i className="iconfont icon-zhongzhi2 font-16 "></i>
{/* <i className="iconfont icon-zhongzhi2 font-16 "></i> */}
{this.state.vnc_reseting ? <Icon type="loading" style={{verticalAlign: 'sub'}} />
: <i className="iconfont icon-zhongzhi2 font-16 "></i>}
<span>重置桌面系统</span>
</FloatButton>
{/* <Spin tip="..." spinning={this.state.vnc_reseting}>
</Spin> */}
<VNCDisplay
{...this.props}
key={this.state.displayKey}
vnc_url={this.state.vnc_url || this.props.vnc_url}
>
>
<Spin tip="加载中..." spinning={this.state.vnc_reseting}>
</Spin>
<Drawer
mask={true}
title=""

@ -222,7 +222,7 @@ class TPIMonaco extends Component {
// https://github.com/Microsoft/monaco-editor/issues/539
window.monaco.editor.setModelLanguage(editor_monaco.getModel(), lang)
} else if (prevProps.isEditablePath != this.props.isEditablePath) {
if (this.props.isEditablePath) {
if (this.props.isEditablePath || this.props.shixun && this.props.shixun.code_edit_permission == true) {
editor_monaco.updateOptions({readOnly: false})
} else {
editor_monaco.updateOptions({readOnly: true})
@ -245,6 +245,10 @@ class TPIMonaco extends Component {
// extend_editor.clearHistory()
}
}
componentWillUnmount() {
this.editor_monaco && this.editor_monaco.dispose()
}
componentDidMount() {
checkIfLoaded(() => {
let value = [
@ -271,7 +275,7 @@ class TPIMonaco extends Component {
const lang = getLanguageByMirrorName(this.props.mirror_name);
const editor = window.monaco.editor.create(document.getElementById('extend-challenge-file-edit'), {
value: value,
readOnly: !this.props.isEditablePath,
readOnly: !this.props.isEditablePath && this.props.shixun && this.props.shixun.code_edit_permission != true,
// 属性说明
// http://testeduplus2.educoder.net/react/build/static/node_modules/_monaco-editor@0.15.6@monaco-editor/esm/vs/editor/common/config/commonEditorConfig.js
// https://github.com/Microsoft/monaco-editor/issues/29

@ -157,13 +157,13 @@ class CodeRepositoryView extends Component {
}
onPathChange(index) {
onPathChange(index, isDropDown) {
const { challenge, onPathChange, doFileUpdateRequestOnCodeMirrorBlur } = this.props;
if (challenge.pathIndex !== index) {
// 切换时保存文件
// doFileUpdateRequestOnCodeMirrorBlur(true)
onPathChange(index)
onPathChange(index, isDropDown)
}
}
@ -174,7 +174,7 @@ class CodeRepositoryView extends Component {
const pathArray = path.forEach ? path : [path]
pathArray.forEach( (item, index) => {
domArray.push(
<p key={index} className={classNames({'blue-line': pathIndex == index})} onClick={ () => this.onPathChange(index) } >
<p key={index} className={classNames({'blue-line': pathIndex == index})} onClick={ () => this.onPathChange(index, true) } >
{item}
</p> )
})
@ -501,7 +501,8 @@ class CodeRepositoryView extends Component {
</Tooltip>
} */}
<div className="codemirrorBackground"
style={{ backgroundImage: `url('${notEditablePathImg}')`, display: (isEditablePath ? 'none' : 'block') }}></div>
style={{ backgroundImage: `url('${notEditablePathImg}')`
, display: (isEditablePath || this.props.shixun && this.props.shixun.code_edit_permission ? 'none' : 'block') }}></div>
{/*<textarea className = "" id="extend-challenge-file-edit" name="content">{repositoryCode}</textarea>*/}
{/* cm monaco 切换 */}
{/* <TPICodeMirror {...this.props} ></TPICodeMirror> */}

@ -231,12 +231,14 @@ class CodeRepositoryViewContainer extends Component {
const { fetchRepositoryCode, onPathChange, showSnackbar, challenge } = this.props;
const nodePath = info.node.props.eventKey;
let isCurrentFile = false;
// 设置pathIndex为-1那么代码文件下拉可以切回可编辑的文件
if (!challenge.multiPath) { // 单path任务 多path任务 path是数组
if (challenge.path.trim() == nodePath.trim()) {
if (challenge.pathIndex === 0) {
showSnackbar(`当前编辑文件已经是${nodePath}`)
} else {
fetchRepositoryCode(null, nodePath, 1);
onPathChange(0)
}
return;
@ -244,7 +246,7 @@ class CodeRepositoryViewContainer extends Component {
onPathChange(-1)
}
} else {
let isCurrentFile = false;
let cur_index = -1;
if (challenge.path && challenge.path.forEach) {
challenge.path.forEach((item, index) => {

@ -1,10 +1,11 @@
import React, { Component } from 'react';
import {getImageUrl} from 'educoder';
import {Modal,Input,Checkbox,Tooltip,Spin} from "antd";
import {Modal,Input,Checkbox,Tooltip,Spin,notification} from "antd";
import { DragDropContext , Draggable, Droppable} from 'react-beautiful-dnd';
import Modals from '../../modals/Modals';
import '../ShixunPaths.css';
import axios from 'axios';
import NewShixunModel from '../../courses/coursesPublic/NewShixunModel';
const $ = window.$;
const Search = Input.Search;
@ -60,36 +61,34 @@ class DetailCardsEditAndAdd extends Component{
this.setState({
selectShixun:true,
patheditarry:[],
page:1
})
this.changeTag(0,"");
// this.changeTag(0,"");
}
//关闭选择实训弹框
cloasShixunBox =()=>{
this.setState({
selectShixun:false,
page:1,
patheditarry:[]
})
}
clickShixunchoose=()=>{
let{patheditarry,shixuns_listeditlist,shixuns_listedit}=this.state
showNotification = (description, message = "提示", icon) => {
const data = {
message,
description
}
if (icon) {
data.icon = icon;
}
notification.open(data);
}
clickShixunchoose=(patheditarry)=>{
let{shixuns_listeditlist,shixuns_listedit}=this.state
let newshixuns_listedit=shixuns_listedit;
let list=shixuns_listeditlist
if(patheditarry.length===0){
this.setState({
Modalstype:true,
Modalstopval:'请选择实训',
cardsModalsave:this.cardsModalsave
})
return
}
let url='/paths/append_to_stage.json'
axios.post(url,{
shixun_id:patheditarry
@ -98,6 +97,19 @@ class DetailCardsEditAndAdd extends Component{
if(response.data){
let newshixun_lists=response.data.shixun_lists;
for(var j=0; j<newshixuns_listedit.length; j++){
for(var a=0; a<newshixun_lists.length; a++){
if(newshixuns_listedit[j].shixun_id===newshixun_lists[a].shixun_id){
// this.setState({
// Modalstype:true,
// Modalstopval:'请勿重复选择'+newshixun_lists[a].shixun_name+'实训',
// })
this.showNotification('请勿重复选择:'+newshixun_lists[a].shixun_name+'实训')
return
}
}
}
for(var z=0; z<newshixun_lists.length; z++){
newshixuns_listedit.push(newshixun_lists[z]);
}
@ -123,10 +135,11 @@ class DetailCardsEditAndAdd extends Component{
//点击新建阶段
addStage=()=>{
this.props.editeditbuttomtypes();
this.setState({
editPanel:true
})
this.props.editeditbuttomtypes();
}
//取消新建阶段
@ -147,38 +160,7 @@ class DetailCardsEditAndAdd extends Component{
})
}
//打开选择实训弹框初始化tag标签和列表
changeTag=(id,search)=>{
this.setState({
ChooseShixunListshixun_list:[],
page:1,
hometypepvisible:true,
})
let pathId=this.props.pathid;
let url='/paths/'+pathId+'/choose_subject_shixun.json?page='+1
if(search!="" && search!=undefined){
url+="&search="+search;
}
if(id!=0){
url+="&type="+id;
}
axios.get(encodeURI(url)).then((result)=>{
if(result.status===200){
this.setState({
ChooseShixunList:result.data,
hometypepvisible:false,
type:id,
ChooseShixunListshixun_list:result.data.shixun_list
})
}
}).catch((error)=>{
console.log(error);
})
}
//勾选实训
shixunhomeworkedit=(list)=>{
@ -294,70 +276,19 @@ class DetailCardsEditAndAdd extends Component{
shixun_id:shixuns_listeditlist
}).then((response) => {
// window.location.href = "/paths/" + response.data.subject_id
this.props.getPathCardsLists();
this.cancelAddState();
this.setState({
stage_nametype:false,
descriptiontype:false
})
this.props.getPathCardsLists();
}).catch((error) => {
console.log(error)
});
}
contentViewScrolladd=(e)=>{
const {ChooseShixunList}=this.state;
//滑动到底判断
let newscrollTop=parseInt(e.currentTarget.scrollTop);
let allclientHeight=e.currentTarget.clientHeight+newscrollTop;
if(e.currentTarget.scrollHeight-allclientHeight===0||e.currentTarget.scrollHeight-allclientHeight===1||e.currentTarget.scrollHeight-allclientHeight===-1){
if(ChooseShixunList.shixun_list.length===0){
return
}else{
// console.log("到达底部");
this.setState({
hometypepvisible:true
})
let pathId=this.props.pathid;
let {search,page,type,ChooseShixunListshixun_list}=this.state;
let newpage=page+1;
let newChooseShixunListshixun_list=ChooseShixunListshixun_list;
let url='/paths/'+pathId+'/choose_subject_shixun.json?page='+newpage
if(search!="" && search!=undefined){
url+="&search="+search;
}
if(type!=0){
url+="&type="+type;
}
axios.get(encodeURI(url)).then((result)=>{
if(result.status===200){
let list =result.data.shixun_list;
for(var i=0; i<list.length; i++){
newChooseShixunListshixun_list.push(list[i])
}
this.setState({
ChooseShixunList:result.data,
hometypepvisible:false,
type:type,
search:search,
page:newpage,
ChooseShixunListshixun_list:newChooseShixunListshixun_list
})
}
}).catch((error)=>{
console.log(error);
})
}
}
}
onDragEnd (result) {
let {shixuns_listedit,shixuns_listeditlist} =this.state;
@ -456,99 +387,13 @@ class DetailCardsEditAndAdd extends Component{
`
}
</style>:""}
{selectShixun===true?<NewShixunModel
NewShixunModelType={selectShixun}
hideNewShixunModelType={this.cloasShixunBox}
pathShixun={this.clickShixunchoose}
{...this.props}
></NewShixunModel>:""}
<Modal
keyboard={false}
title="选择实训"
visible={selectShixun}
closable={false}
footer={null}
width="840px"
destroyOnClose={true}
>
<Spin spinning={hometypepvisible} size="large" style={{marginTop:'15%'}}>
<div className="newupload_conbox">
<div className="clearfix mb20 shixun_work_div newshixun_tab_div cdefault" style={{"marginRight":"4px"}} id="shixun_tab_div">
<li className="fl mr5 mt5"> <a onClick={()=>this.changeTag(0,`${search}`)} className={ parseInt(type)===0 ? "active edu-filter-cir-grey font-12":"edu-filter-cir-grey font-12"}>全部</a></li>
{
ChooseShixunList && ChooseShixunList.tags.map((item,key)=>{
return(
<li className="fl mr5 mt5" key={key}>
<a onClick={()=>this.changeTag(`${item.tag_id}`,`${search}`)} className={ parseInt(type) === parseInt(item.tag_id) ? "active edu-filter-cir-grey font-12":"edu-filter-cir-grey font-12"}>{item.tag_name}</a>
</li>
)
})
}
</div>
<div className="clearfix mb20" id="shixun_search_form_div">
<span className="fl color-grey-9 font-16 mt3">
<span></span>
<span className="color-orange-tip">{ChooseShixunList && ChooseShixunList.shixuns_count}</span>
<span>个实训</span>
</span>
<div className="fr search-new mb0">
<Search
placeholder="请输入创建者或者实训名称进行搜索"
onInput={this.searchNameInput}
onSearch={()=>this.changeTag(`${type}`,`${search}`)}
style={{width: '115%'}}
></Search>
</div>
</div>
<ul className="clearfix greybackHead edu-txt-center" style={{marginBottom: '0px'}}>
<li className="fl with40 paddingleft22">实训名称</li>
<li className="fl with30 edu-txt-left">使用院校</li>
<li className="fl with10">使用人数</li>
<li className="fl with10">评价等级</li>
<li className="fl with10"></li>
</ul>
<style>
{
`
.over180{min-height: 180px;max-height: 180px;overflow-y: auto}
`
}
</style>
{ChooseShixunListshixun_list && ChooseShixunListshixun_list.length===0?"": <div className="over180 pl20 pr20"
onScroll={this.contentViewScrolladd}
>
<Checkbox.Group style={{ width: '100%' }} onChange={this.shixunhomeworkedit}>
{
ChooseShixunListshixun_list && ChooseShixunListshixun_list.map((item,key)=>{
return(
<div className="clearfix edu-txt-center lineh-40 bor-bottom-greyE" key={key}>
<li className="fl with40">
<Checkbox
id={"shixun_input_"+item.shixun_id}
value={item.shixun_id}
key={item.shixun_id}
className="fl task-hide edu-txt-left"
style={{"width":"298px"}}
name="shixun_homework[]"
>
<label style={{"textAlign":"left","color":"#05101A"}} className="task-hide color-grey-name" title={item.shixun_name}>{item.shixun_name}</label>
</Checkbox>
</li>
<li className="fl with30 edu-txt-left task-hide paddingl5">{item.school_users}</li>
<li className="fl with10 paddingl10">{item.myshixuns_count}</li>
<li className="fl with10 color-orange-tip paddingl10">{item.preference}</li>
<li className="fl with10"><a className="color-blue" href={"/shixuns/"+item.identifier+"/challenges"} target="_blank">详情</a></li>
</div>
)
})
}
</Checkbox.Group>
</div>}
<div className="mt20 marginauto clearfix edu-txt-center">
<a className="pop_close task-btn mr30 margin-tp26" onClick={this.cloasShixunBox}>取消</a>
<a className="task-btn task-btn-orange margin-tp26" id="submit_send_shixun" onClick={this.clickShixunchoose}>确定</a>
</div>
</div>
</Spin>
</Modal>
</div>
{/* 可拖拽选择实训列表*/}
@ -650,4 +495,185 @@ class DetailCardsEditAndAdd extends Component{
)
}
}
export default DetailCardsEditAndAdd;
export default DetailCardsEditAndAdd;
//
// <Modal
// keyboard={false}
// title="选择实训"
// visible={selectShixun}
// closable={false}
// footer={null}
// width="840px"
// destroyOnClose={true}
// >
// <Spin spinning={hometypepvisible} size="large" style={{marginTop:'15%'}}>
// <div className="newupload_conbox">
// <div className="clearfix mb20 shixun_work_div newshixun_tab_div cdefault" style={{"marginRight":"4px"}} id="shixun_tab_div">
// <li className="fl mr5 mt5"> <a onClick={()=>this.changeTag(0,`${search}`)} className={ parseInt(type)===0 ? "active edu-filter-cir-grey font-12":"edu-filter-cir-grey font-12"}>全部</a></li>
// {
// ChooseShixunList && ChooseShixunList.tags.map((item,key)=>{
// return(
// <li className="fl mr5 mt5" key={key}>
// <a onClick={()=>this.changeTag(`${item.tag_id}`,`${search}`)} className={ parseInt(type) === parseInt(item.tag_id) ? "active edu-filter-cir-grey font-12":"edu-filter-cir-grey font-12"}>{item.tag_name}</a>
// </li>
// )
// })
// }
//
//
// </div>
// <div className="clearfix mb20" id="shixun_search_form_div">
// <span className="fl color-grey-9 font-16 mt3">
// <span>共</span>
// <span className="color-orange-tip">{ChooseShixunList && ChooseShixunList.shixuns_count}</span>
// <span>个实训</span>
// </span>
// <div className="fr search-new mb0">
// <Search
// placeholder="请输入创建者或者实训名称进行搜索"
// onInput={this.searchNameInput}
// onSearch={()=>this.changeTag(`${type}`,`${search}`)}
// style={{width: '115%'}}
// ></Search>
// </div>
// </div>
// <ul className="clearfix greybackHead edu-txt-center" style={{marginBottom: '0px'}}>
// <li className="fl with40 paddingleft22">实训名称</li>
// <li className="fl with30 edu-txt-left">使用院校</li>
// <li className="fl with10">使用人数</li>
// <li className="fl with10">评价等级</li>
// <li className="fl with10"></li>
// </ul>
//
// <style>
// {
// `
// .over180{min-height: 180px;max-height: 180px;overflow-y: auto}
// `
// }
// </style>
// {ChooseShixunListshixun_list && ChooseShixunListshixun_list.length===0?"": <div className="over180 pl20 pr20"
// onScroll={this.contentViewScrolladd}
// >
// <Checkbox.Group style={{ width: '100%' }} onChange={this.shixunhomeworkedit}>
// {
// ChooseShixunListshixun_list && ChooseShixunListshixun_list.map((item,key)=>{
// return(
// <div className="clearfix edu-txt-center lineh-40 bor-bottom-greyE" key={key}>
// <li className="fl with40">
// <Checkbox
// id={"shixun_input_"+item.shixun_id}
// value={item.shixun_id}
// key={item.shixun_id}
// className="fl task-hide edu-txt-left"
// style={{"width":"298px"}}
// name="shixun_homework[]"
// >
// <label style={{"textAlign":"left","color":"#05101A"}} className="task-hide color-grey-name" title={item.shixun_name}>{item.shixun_name}</label>
// </Checkbox>
// </li>
// <li className="fl with30 edu-txt-left task-hide paddingl5">{item.school_users}</li>
// <li className="fl with10 paddingl10">{item.myshixuns_count}</li>
// <li className="fl with10 color-orange-tip paddingl10">{item.preference}</li>
// <li className="fl with10"><a className="color-blue" href={"/shixuns/"+item.identifier+"/challenges"} target="_blank">详情</a></li>
// </div>
// )
// })
// }
// </Checkbox.Group>
// </div>}
// <div className="mt20 marginauto clearfix edu-txt-center">
// <a className="pop_close task-btn mr30 margin-tp26" onClick={this.cloasShixunBox}>取消</a>
// <a className="task-btn task-btn-orange margin-tp26" id="submit_send_shixun" onClick={this.clickShixunchoose}>确定</a>
// </div>
// </div>
// </Spin>
// </Modal>
// contentViewScrolladd=(e)=>{
// const {ChooseShixunList}=this.state;
// //滑动到底判断
// let newscrollTop=parseInt(e.currentTarget.scrollTop);
// let allclientHeight=e.currentTarget.clientHeight+newscrollTop;
//
// if(e.currentTarget.scrollHeight-allclientHeight===0||e.currentTarget.scrollHeight-allclientHeight===1||e.currentTarget.scrollHeight-allclientHeight===-1){
//
// if(ChooseShixunList.shixun_list.length===0){
// return
// }else{
// // console.log("到达底部");
// this.setState({
// hometypepvisible:true
// })
// let pathId=this.props.pathid;
// let {search,page,type,ChooseShixunListshixun_list}=this.state;
// let newpage=page+1;
// let newChooseShixunListshixun_list=ChooseShixunListshixun_list;
// let url='/paths/'+pathId+'/choose_subject_shixun.json?page='+newpage
// if(search!="" && search!=undefined){
// url+="&search="+search;
// }
// if(type!=0){
// url+="&type="+type;
// }
// axios.get(encodeURI(url)).then((result)=>{
// if(result.status===200){
// let list =result.data.shixun_list;
//
// for(var i=0; i<list.length; i++){
// newChooseShixunListshixun_list.push(list[i])
// }
// this.setState({
// ChooseShixunList:result.data,
// hometypepvisible:false,
// type:type,
// search:search,
// page:newpage,
// ChooseShixunListshixun_list:newChooseShixunListshixun_list
// })
// }
// }).catch((error)=>{
// console.log(error);
// })
//
// }
//
// }
//
// }
//
// //打开选择实训弹框初始化tag标签和列表
// changeTag=(id,search)=>{
//
// this.setState({
// ChooseShixunListshixun_list:[],
// page:1,
// hometypepvisible:true,
// })
//
// let pathId=this.props.pathid;
//
// let url='/paths/'+pathId+'/choose_subject_shixun.json?page='+1
// if(search!="" && search!=undefined){
// url+="&search="+search;
// }
// if(id!=0){
// url+="&type="+id;
// }
//
// axios.get(encodeURI(url)).then((result)=>{
// if(result.status===200){
// this.setState({
// ChooseShixunList:result.data,
// hometypepvisible:false,
// type:id,
// ChooseShixunListshixun_list:result.data.shixun_list
// })
// }
// }).catch((error)=>{
// console.log(error);
// })
// }

@ -1,8 +1,9 @@
import React, { Component } from 'react';
import {getImageUrl} from 'educoder';
import {Modal,Input,Checkbox,Tooltip,Spin} from "antd";
import {Modal,Input,Checkbox,Tooltip,Spin,notification} from "antd";
import { DragDropContext,Draggable, Droppable} from 'react-beautiful-dnd';
import Modals from '../../modals/Modals';
import NewShixunModel from '../../courses/coursesPublic/NewShixunModel';
import '../ShixunPaths.css';
import axios from 'axios';
const $ = window.$;
@ -63,7 +64,7 @@ class DetailCardsEditAndEdit extends Component{
selectShixun:true,
patheditarry:[]
})
this.changeTag(0,"");
// this.changeTag(0,"");
}
//关闭选择实训弹框
cloasShixunBox =()=>{
@ -79,36 +80,7 @@ class DetailCardsEditAndEdit extends Component{
})
}
//打开选择实训弹框初始化tag标签和列表
changeTag(id,search){
this.setState({
ChooseShixunListshixun_list:[],
page:1,
hometypepvisible:true
})
let pathId=this.props.pathid;
let url='/paths/'+pathId+'/choose_subject_shixun.json?page='+1
if(search!="" && search!=undefined){
url+="&search="+search;
}
if(id!=0){
url+="&type="+id;
}
axios.get(encodeURI(url)).then((result)=>{
if(result.status===200){
this.setState({
ChooseShixunList:result.data,
hometypepvisible:false,
type:id,
search:search,
ChooseShixunListshixun_list:result.data.shixun_list
})
}
}).catch((error)=>{
console.log(error);
})
}
shixunhomeworkedit=(list)=>{
@ -158,22 +130,12 @@ class DetailCardsEditAndEdit extends Component{
}
clickShixunchoose=()=>{
clickShixunchoose=(patheditarry)=>{
let{patheditarry,shixuns_listedit,shixuns_listeditlist}=this.state
let{shixuns_listedit,shixuns_listeditlist}=this.state
let newshixuns_listedit=shixuns_listedit;
let list=shixuns_listeditlist
if(patheditarry.length===0){
this.setState({
Modalstype:true,
Modalstopval:'请选择实训',
})
return
}
let url='/paths/append_to_stage.json'
axios.post(url,{
shixun_id:patheditarry
@ -184,10 +146,11 @@ class DetailCardsEditAndEdit extends Component{
for(var j=0; j<newshixuns_listedit.length; j++){
for(var a=0; a<newshixun_lists.length; a++){
if(newshixuns_listedit[j].shixun_id===newshixun_lists[a].shixun_id){
this.setState({
Modalstype:true,
Modalstopval:'请勿重复选择'+newshixun_lists[a].shixun_name+'实训',
})
// this.setState({
// Modalstype:true,
// Modalstopval:'请勿重复选择'+newshixun_lists[a].shixun_name+'实训',
// })
this.showNotification('请勿重复选择:'+newshixun_lists[a].shixun_name+'实训')
return
}
}
@ -338,69 +301,16 @@ class DetailCardsEditAndEdit extends Component{
})
}
contentViewScrolledit=(e)=>{
//滑动到底判断
const {ChooseShixunList}=this.state;
let newscrollTop=parseInt(e.currentTarget.scrollTop);
let allclientHeight=e.currentTarget.clientHeight+newscrollTop;
if(e.currentTarget.scrollHeight-allclientHeight===0||e.currentTarget.scrollHeight-allclientHeight===1||e.currentTarget.scrollHeight-allclientHeight===-1){
if(ChooseShixunList.shixun_list.length===0){
return
}else{
this.setState({
hometypepvisible:true
})
// console.log("到达底部");
let {page,type,search,ChooseShixunListshixun_list}=this.state;
let newpage=page+1;
let pathId=this.props.pathid;
let newChooseShixunListshixun_list=ChooseShixunListshixun_list;
let url='/paths/'+pathId+'/choose_subject_shixun.json?page='+newpage
if(search!="" && search!=undefined){
url+="&search="+search;
}
if(type!=0){
url+="&type="+type;
}
axios.get(encodeURI(url)).then((result)=>{
if(result.status===200){
let list =result.data.shixun_list;
for(var i=0; i<list.length; i++){
newChooseShixunListshixun_list.push(list[i])
}
this.setState({
ChooseShixunList:result.data,
hometypepvisible:false,
type:type,
page:newpage,
search:search,
ChooseShixunListshixun_list:newChooseShixunListshixun_list
})
}
}).catch((error)=>{
console.log(error);
})
}
}
}
showNotification = (description, message = "提示", icon) => {
const data = {
message,
description
}
if (icon) {
data.icon = icon;
}
notification.open(data);
}
render(){
let {selectShixun,
@ -483,99 +393,13 @@ class DetailCardsEditAndEdit extends Component{
}
</style>:""}
{selectShixun===true?<NewShixunModel
NewShixunModelType={selectShixun}
hideNewShixunModelType={this.cloasShixunBox}
pathShixun={this.clickShixunchoose}
{...this.props}
></NewShixunModel>:""}
<Modal
keyboard={false}
title="选择实训"
visible={selectShixun}
closable={false}
footer={null}
width="840px"
destroyOnClose={true}
>
<Spin spinning={hometypepvisible} size="large" style={{marginTop:'15%'}}>
<div className="newupload_conbox">
<div className="clearfix mb20 shixun_work_div newshixun_tab_div cdefault" style={{"marginRight":"4px"}} id="shixun_tab_div">
<li className="fl mr5 mt5"> <a onClick={()=>this.changeTag(0,`${search}`)} className={ parseInt(type)===0 ? "active edu-filter-cir-grey font-12":"edu-filter-cir-grey font-12"}>全部</a></li>
{
ChooseShixunList && ChooseShixunList.tags.map((item,key)=>{
return(
<li className="fl mr5 mt5" key={key}>
<a onClick={()=>this.changeTag(`${item.tag_id}`,`${search}`)} className={ parseInt(type) === parseInt(item.tag_id) ? "active edu-filter-cir-grey font-12":"edu-filter-cir-grey font-12"}>{item.tag_name}</a>
</li>
)
})
}
</div>
<div className="clearfix mb20" id="shixun_search_form_div">
<span className="fl color-grey-9 font-16 mt3">
<span></span>
<span className="color-orange-tip">{ChooseShixunList && ChooseShixunList.shixuns_count}</span>
<span>个实训</span>
</span>
<div className="fr search-new mb0">
<Search
placeholder="请输入创建者或者实训名称进行搜索"
onInput={this.searchNameInput}
onSearch={()=>this.changeTag(`${type}`,`${search}`)}
style={{width: '115%'}}
></Search>
</div>
</div>
<ul className="clearfix greybackHead edu-txt-center" style={{marginBottom: '0px'}}>
<li className="fl with40 paddingleft22">实训名称</li>
<li className="fl with30 edu-txt-left">使用院校</li>
<li className="fl with10">使用人数</li>
<li className="fl with10">评价等级</li>
<li className="fl with10"></li>
</ul>
<style>
{
`
.over180{min-height: 180px;max-height: 180px;overflow-y: auto}
`
}
</style>
{ChooseShixunListshixun_list && ChooseShixunListshixun_list.length===0?"":<div className="over180 pl20 pr20"
onScroll={this.contentViewScrolledit}
>
<Checkbox.Group style={{ width: '100%' }} onChange={this.shixunhomeworkedit}>
{
ChooseShixunListshixun_list && ChooseShixunListshixun_list.map((item,key)=>{
return(
<div className="clearfix edu-txt-center lineh-40 bor-bottom-greyE" key={key}>
<li className="fl with40">
<Checkbox
id={"shixun_input_"+item.shixun_id}
value={item.shixun_id}
key={item.shixun_id}
className="fl task-hide edu-txt-left"
style={{"width":"298px"}}
name="shixun_homework[]"
>
<label style={{"textAlign":"left","color":"#05101A"}} className="task-hide color-grey-name" title={item.shixun_name}>{item.shixun_name}</label>
</Checkbox>
</li>
<li className="fl with30 edu-txt-left task-hide paddingl5">{item.school_users}</li>
<li className="fl with10 paddingl10">{item.myshixuns_count}</li>
<li className="fl with10 color-orange-tip paddingl10">{item.preference}</li>
<li className="fl with10"><a className="color-blue" href={"/shixuns/"+item.identifier+"/challenges"} target="_blank">详情</a></li>
</div>
)
})
}
</Checkbox.Group>
</div>}
<div className="mt20 marginauto clearfix edu-txt-center">
<a className="pop_close task-btn mr30 margin-tp26" onClick={this.cloasShixunBox}>取消</a>
<a className="task-btn task-btn-orange margin-tp26" id="submit_send_shixun" onClick={this.clickShixunchoose}>确定</a>
</div>
</div>
</Spin>
</Modal>
</div>
{/* 可拖拽选择实训列表*/}
@ -716,4 +540,191 @@ export default DetailCardsEditAndEdit;
// </div>
// )
// })
// }
// }
// <Modal
// keyboard={false}
// title="选择实训"
// visible={selectShixun}
// closable={false}
// footer={null}
// width="840px"
// destroyOnClose={true}
// >
// <Spin spinning={hometypepvisible} size="large" style={{marginTop:'15%'}}>
// <div className="newupload_conbox">
// <div className="clearfix mb20 shixun_work_div newshixun_tab_div cdefault" style={{"marginRight":"4px"}} id="shixun_tab_div">
// <li className="fl mr5 mt5"> <a onClick={()=>this.changeTag(0,`${search}`)} className={ parseInt(type)===0 ? "active edu-filter-cir-grey font-12":"edu-filter-cir-grey font-12"}>全部</a></li>
// {
// ChooseShixunList && ChooseShixunList.tags.map((item,key)=>{
// return(
// <li className="fl mr5 mt5" key={key}>
// <a onClick={()=>this.changeTag(`${item.tag_id}`,`${search}`)} className={ parseInt(type) === parseInt(item.tag_id) ? "active edu-filter-cir-grey font-12":"edu-filter-cir-grey font-12"}>{item.tag_name}</a>
// </li>
// )
// })
// }
//
//
// </div>
// <div className="clearfix mb20" id="shixun_search_form_div">
// <span className="fl color-grey-9 font-16 mt3">
// <span>共</span>
// <span className="color-orange-tip">{ChooseShixunList && ChooseShixunList.shixuns_count}</span>
// <span>个实训</span>
// </span>
// <div className="fr search-new mb0">
// <Search
// placeholder="请输入创建者或者实训名称进行搜索"
// onInput={this.searchNameInput}
// onSearch={()=>this.changeTag(`${type}`,`${search}`)}
// style={{width: '115%'}}
// ></Search>
// </div>
// </div>
// <ul className="clearfix greybackHead edu-txt-center" style={{marginBottom: '0px'}}>
// <li className="fl with40 paddingleft22">实训名称</li>
// <li className="fl with30 edu-txt-left">使用院校</li>
// <li className="fl with10">使用人数</li>
// <li className="fl with10">评价等级</li>
// <li className="fl with10"></li>
// </ul>
//
// <style>
// {
// `
// .over180{min-height: 180px;max-height: 180px;overflow-y: auto}
// `
// }
// </style>
// {ChooseShixunListshixun_list && ChooseShixunListshixun_list.length===0?"":<div className="over180 pl20 pr20"
// onScroll={this.contentViewScrolledit}
// >
// <Checkbox.Group style={{ width: '100%' }} onChange={this.shixunhomeworkedit}>
// {
// ChooseShixunListshixun_list && ChooseShixunListshixun_list.map((item,key)=>{
// return(
// <div className="clearfix edu-txt-center lineh-40 bor-bottom-greyE" key={key}>
// <li className="fl with40">
// <Checkbox
// id={"shixun_input_"+item.shixun_id}
// value={item.shixun_id}
// key={item.shixun_id}
// className="fl task-hide edu-txt-left"
// style={{"width":"298px"}}
// name="shixun_homework[]"
// >
// <label style={{"textAlign":"left","color":"#05101A"}} className="task-hide color-grey-name" title={item.shixun_name}>{item.shixun_name}</label>
// </Checkbox>
// </li>
// <li className="fl with30 edu-txt-left task-hide paddingl5">{item.school_users}</li>
// <li className="fl with10 paddingl10">{item.myshixuns_count}</li>
// <li className="fl with10 color-orange-tip paddingl10">{item.preference}</li>
// <li className="fl with10"><a className="color-blue" href={"/shixuns/"+item.identifier+"/challenges"} target="_blank">详情</a></li>
// </div>
// )
// })
// }
// </Checkbox.Group>
// </div>}
// <div className="mt20 marginauto clearfix edu-txt-center">
// <a className="pop_close task-btn mr30 margin-tp26" onClick={this.cloasShixunBox}>取消</a>
// <a className="task-btn task-btn-orange margin-tp26" id="submit_send_shixun" onClick={this.clickShixunchoose}>确定</a>
// </div>
// </div>
// </Spin>
// </Modal>
// //打开选择实训弹框初始化tag标签和列表
// changeTag(id,search){
//
// this.setState({
// ChooseShixunListshixun_list:[],
// page:1,
// hometypepvisible:true
// })
// let pathId=this.props.pathid;
// let url='/paths/'+pathId+'/choose_subject_shixun.json?page='+1
// if(search!="" && search!=undefined){
// url+="&search="+search;
// }
// if(id!=0){
// url+="&type="+id;
// }
// axios.get(encodeURI(url)).then((result)=>{
// if(result.status===200){
// this.setState({
// ChooseShixunList:result.data,
// hometypepvisible:false,
// type:id,
// search:search,
// ChooseShixunListshixun_list:result.data.shixun_list
// })
// }
// }).catch((error)=>{
// console.log(error);
// })
// }
// contentViewScrolledit=(e)=>{
// //滑动到底判断
// const {ChooseShixunList}=this.state;
// let newscrollTop=parseInt(e.currentTarget.scrollTop);
// let allclientHeight=e.currentTarget.clientHeight+newscrollTop;
//
// if(e.currentTarget.scrollHeight-allclientHeight===0||e.currentTarget.scrollHeight-allclientHeight===1||e.currentTarget.scrollHeight-allclientHeight===-1){
//
// if(ChooseShixunList.shixun_list.length===0){
// return
// }else{
// this.setState({
// hometypepvisible:true
// })
// // console.log("到达底部");
//
// let {page,type,search,ChooseShixunListshixun_list}=this.state;
//
// let newpage=page+1;
//
// let pathId=this.props.pathid;
//
// let newChooseShixunListshixun_list=ChooseShixunListshixun_list;
//
// let url='/paths/'+pathId+'/choose_subject_shixun.json?page='+newpage
//
// if(search!="" && search!=undefined){
// url+="&search="+search;
// }
//
// if(type!=0){
// url+="&type="+type;
// }
// axios.get(encodeURI(url)).then((result)=>{
// if(result.status===200){
//
// let list =result.data.shixun_list;
//
// for(var i=0; i<list.length; i++){
// newChooseShixunListshixun_list.push(list[i])
// }
// this.setState({
// ChooseShixunList:result.data,
// hometypepvisible:false,
// type:type,
// page:newpage,
// search:search,
// ChooseShixunListshixun_list:newChooseShixunListshixun_list
// })
// }
// }).catch((error)=>{
// console.log(error);
// })
//
//
// }
//
//
//
// }
//
// }

@ -362,6 +362,9 @@ class PathDetailIndex extends Component{
.head-right{
line-height: 30px;
}
.padding40-20-30{
padding:40px 20px 30px;
}
`
}
</style>
@ -457,7 +460,7 @@ class PathDetailIndex extends Component{
}
{
this.props.checkIfLogin()===false?"":progress === undefined ? "" : progress === null ? "" :
<div className="edu-back-white myProgress padding40-20 mb10">
<div className="edu-back-white myProgress padding40-20-30 mb10">
<p className="mb20">
<span className="font-16 mr10">关卡数</span>
<Tooltip placement="bottom" title="已通关数/关卡总数">
@ -468,7 +471,8 @@ class PathDetailIndex extends Component{
<span className="fl color-green">已学 {progress.learned}%</span>
<span className="fr color-grey-9" id="time-consuming">学习耗时{this.timeStamp(progress.time)} </span>
</p>
<div className="myProgressNav"><div className="myProgressGreen" style={{"width":`${progress.learned+"%"}`}}></div></div>
<div className="myProgressNav mb20"><div className="myProgressGreen" style={{"width":`${progress.learned+"%"}`}}></div></div>
<span className="font-14 color-grey-8">: 我的进展以已发布的实训详情关卡数为准</span>
</div>
}

@ -48,6 +48,8 @@ function create_editorMD(id, width, high, placeholder, imageUrl,initValue, callb
imageUploadURL: imageUrl,//url
onload: function () {
// this.previewing();
var id = this.id;
var editorName = this;
$("#" + id + " [type=\"latex\"]").bind("click", function () {
editorName.cm.replaceSelection("```latex");
editorName.cm.replaceSelection("\n");
@ -58,9 +60,9 @@ function create_editorMD(id, width, high, placeholder, imageUrl,initValue, callb
});
$("#" + id + " [type=\"inline\"]").bind("click", function () {
editorName.cm.replaceSelection("$$$$");
editorName.cm.replaceSelection("`$$$$`");
var __Cursor = editorName.cm.getDoc().getCursor();
editorName.cm.setCursor(__Cursor.line, __Cursor.ch - 2);
editorName.cm.setCursor(__Cursor.line, __Cursor.ch - 3);
editorName.cm.focus();
});
$("[type=\"inline\"]").attr("title", "行内公式");
@ -288,7 +290,7 @@ class PathNew extends Component{
</div>
<div className="clearfix mb30 mt30">
<Button className="defalutSubmitbtn fl mr20" loading={this.state.bottonloading} onClick={this.submitNewPath}>提交</Button>
<button className="defalutSubmitbtn fl mr20" loading={this.state.bottonloading} onClick={this.submitNewPath}>提交</button>
{this.isEditPage ?
<Link to={`/paths/${this.props.match.params.pathId}`}
className="defalutCancelbtn fl">取消</Link>

@ -8,6 +8,7 @@ class ShixunPath extends Component{
super(props)
}
componentDidMount() {
console.log('configShareForPaths')
configShareForPaths()
}

@ -168,7 +168,7 @@ function create_editorMD(id, width, high, placeholder, imageUrl, callback, initV
$("#" + _id + " [type=\"inline\"]").bind("click", function () {
_editorName.cm.replaceSelection("`$$$$`");
var __Cursor = _editorName.cm.getDoc().getCursor();
_editorName.cm.setCursor(__Cursor.line, __Cursor.ch - 2);
_editorName.cm.setCursor(__Cursor.line, __Cursor.ch - 3);
_editorName.cm.focus();
});
$("[type=\"inline\"]").attr("title", "行内公式");

@ -202,48 +202,40 @@ export function TPMIndexHOC(WrappedComponent) {
NORMAL = 6 # 普通用户
Anonymous = 7 # 普未登录
*/
//超管
//超管0
isSuperAdmin = () => {
// return false
return this.state.coursedata&&this.state.coursedata.course_identity === 0
}
// 课堂管理等
//超管、运维0-1
isClassManagement = () => {
// return this.state.coursedata&&this.state.coursedata.course_identity >= 0 &&
return this.state.coursedata&&this.state.coursedata.course_identity < 2
}
//老师等
//超管、运维、课堂管理0-2
isAdminOrCreator = () => {
// return this.state.coursedata&&this.state.coursedata.course_identity >= 0 &&
return this.state.coursedata&&this.state.coursedata.course_identity < 3
}
// 助教等
//超管、运维、课堂管理、老师0-3
isAdminOrTeacher = () => {
// return this.state.coursedata&&this.state.coursedata.course_identity >= 0 &&
return this.state.coursedata&&this.state.coursedata.course_identity < 4
}
// 老师、管理员等
// 超管、运维、课堂管理、老师、助教0-4
isAdmin = () => {
// return false
// return this.state.coursedata&&this.state.coursedata.course_identity >= 0 &&
return this.state.coursedata&&this.state.coursedata.course_identity < 5
}
// 学生
// 学生5
isStudent = () => {
// return true
// return this.state.coursedata&&this.state.coursedata.course_identity >= 0 &&
return this.state.coursedata&&this.state.coursedata.course_identity === 5
}
// 超管、运维、课堂管理、老师、助教、学生0-5
isAdminOrStudent = () => {
// return this.state.coursedata&&this.state.coursedata.course_identity >= 0 &&
return this.state.coursedata&&this.state.coursedata.course_identity <= 5
}
// 非课堂成员
// 游客未登录/非课堂成员6>
isNotMember = () => {
// return this.state.coursedata&&this.state.coursedata.course_identity >= 0 &&
return this.state.coursedata&&this.state.coursedata.course_identity >= 6
}
//课堂是否已结束
isCourseEnd = () => {
return this.state.current_user ? this.state.current_user.course_is_end : false
}

@ -156,9 +156,9 @@ function create_editorMD(id, width, high, placeholder, imageUrl,initValue, callb
});
$("#" + id + " [type=\"inline\"]").bind("click", function () {
editorName.cm.replaceSelection("$$$$");
editorName.cm.replaceSelection("`$$$$`");
var __Cursor = editorName.cm.getDoc().getCursor();
editorName.cm.setCursor(__Cursor.line, __Cursor.ch - 2);
editorName.cm.setCursor(__Cursor.line, __Cursor.ch - 3);
editorName.cm.focus();
});
$("[type=\"inline\"]").attr("title", "行内公式");
@ -220,6 +220,7 @@ export default class TPMsettings extends Component {
can_copy: undefined,
task_pass: undefined,
test_set_permission: undefined,
code_edit_permission: undefined,
hide_code: undefined,
code_hidden: undefined,
forbid_copy: undefined,
@ -352,6 +353,7 @@ export default class TPMsettings extends Component {
task_pass: response.data.shixun.task_pass,
test_set_permission: response.data.shixun.test_set_permission,
hide_code: response.data.shixun.hide_code,
code_edit_permission: response.data.shixun.code_edit_permission,
code_hidden: response.data.shixun.code_hidden,
is_secret_repository: response.data.shixun.is_secret_repository,
init_is_secret_repository: response.data.shixun.is_secret_repository,
@ -546,7 +548,11 @@ export default class TPMsettings extends Component {
});
}
code_edit_permission = (e) => {
this.setState({
code_edit_permission: e.target.checked
})
}
code_hidden=(e)=>{
let sum = ""
if (e.target.checked === false) {
@ -869,7 +875,7 @@ export default class TPMsettings extends Component {
let {
name, choice_main_type, choice_small_type, choice_standard_scripts, scope_partment, choice_standard_scriptssum, vnc_evaluate,
evaluate_script, webssh, use_scope, trainee, can_copy, task_pass, test_set_permission, hide_code, code_hidden, forbid_copy, vnc,multi_webssh,
opening_time,shixunmemoMDvalue,shixun_service_configlist, is_secret_repository
opening_time,shixunmemoMDvalue,shixun_service_configlist, is_secret_repository, code_edit_permission
} = this.state;
let newshixun_service_configlist = shixun_service_configlist.map(v => {
@ -982,6 +988,7 @@ export default class TPMsettings extends Component {
vnc_evaluate: vnc_evaluate===null?undefined:vnc_evaluate,
test_set_permission: test_set_permission,
code_hidden: code_hidden,
code_edit_permission: code_edit_permission,
trainee: trainee,
task_pass: task_pass,
hide_code: hide_code,
@ -1563,6 +1570,7 @@ export default class TPMsettings extends Component {
test_set_permission,
hide_code,
forbid_copy,
code_edit_permission,
code_hidden,
vnc,
vnc_evaluate,
@ -2274,6 +2282,15 @@ export default class TPMsettings extends Component {
</span>
</div>
{!code_hidden && !hide_code && <div className="clearfix mt20 ml30">
<span className="color-grey-6 mt5 fl" style={{minWidth: '95px'}}>代码开放修改:</span>
<span className="fl mt5">
<Checkbox checked={code_edit_permission === undefined ? false : code_edit_permission}
onChange={this.code_edit_permission}></Checkbox>
<label style={{top:'6px'}} className="color-grey-9 ml10" >勾选则学员可以修改版本库目录中的任意文件内容</label>
</span>
</div>}
<div className="clearfix mt20 ml30">
<span className="color-grey-6 mt5 fl" style={{minWidth: '95px'}}>隐藏代码窗口:</span>
<span className="fl mt5">

@ -16,8 +16,8 @@ require('codemirror/lib/codemirror.css');
let origin = getUrl();
let path = getUrl("/editormd/lib/")
let path = '/editormd/lib/'
path = getUrl("/editormd/lib/")
const $ = window.$;
let timeout;
@ -171,7 +171,7 @@ function create_editorMD(id, width, high, placeholder, imageUrl, callback, initV
$("#" + _id + " [type=\"inline\"]").bind("click", function () {
_editorName.cm.replaceSelection("`$$$$`");
var __Cursor = _editorName.cm.getDoc().getCursor();
_editorName.cm.setCursor(__Cursor.line, __Cursor.ch - 2);
_editorName.cm.setCursor(__Cursor.line, __Cursor.ch - 3);
_editorName.cm.focus();
});
$("[type=\"inline\"]").attr("title", "行内公式");

@ -130,9 +130,9 @@ function create_editorMD(id, width, high, placeholder, imageUrl, callback) {
});
$("#" + id + " [type=\"inline\"]").bind("click", function () {
editorName.cm.replaceSelection("$$$$");
editorName.cm.replaceSelection("`$$$$`");
var __Cursor = editorName.cm.getDoc().getCursor();
editorName.cm.setCursor(__Cursor.line, __Cursor.ch - 2);
editorName.cm.setCursor(__Cursor.line, __Cursor.ch - 3);
editorName.cm.focus();
});
$("[type=\"inline\"]").attr("title", "行内公式");

@ -73,9 +73,9 @@ function create_editorMD(id, width, high, placeholder, imageUrl, callback) {
});
$("#" + id + " [type=\"inline\"]").bind("click", function () {
editorName.cm.replaceSelection("$$$$");
editorName.cm.replaceSelection("`$$$$`");
var __Cursor = editorName.cm.getDoc().getCursor();
editorName.cm.setCursor(__Cursor.line, __Cursor.ch - 2);
editorName.cm.setCursor(__Cursor.line, __Cursor.ch - 3);
editorName.cm.focus();
});
$("[type=\"inline\"]").attr("title", "行内公式");

@ -51,9 +51,9 @@ function create_editorMD(id, width, high, placeholder, imageUrl, callback) {
});
$("#" + id + " [type=\"inline\"]").bind("click", function () {
editorName.cm.replaceSelection("$$$$");
editorName.cm.replaceSelection("`$$$$`");
var __Cursor = editorName.cm.getDoc().getCursor();
editorName.cm.setCursor(__Cursor.line, __Cursor.ch - 2);
editorName.cm.setCursor(__Cursor.line, __Cursor.ch - 3);
editorName.cm.focus();
});
$("[type=\"inline\"]").attr("title", "行内公式");

@ -160,9 +160,9 @@ function create_editorMD(id, width, high, placeholder, imageUrl, callback) {
});
$("#" + id + " [type=\"inline\"]").bind("click", function () {
editorName.cm.replaceSelection("$$$$");
editorName.cm.replaceSelection("`$$$$`");
var __Cursor = editorName.cm.getDoc().getCursor();
editorName.cm.setCursor(__Cursor.line, __Cursor.ch - 2);
editorName.cm.setCursor(__Cursor.line, __Cursor.ch - 3);
editorName.cm.focus();
});
$("[type=\"inline\"]").attr("title", "行内公式");

@ -12,7 +12,7 @@
height: 55px;
width:663px !important;
font-size: 18px;
color: #681616 !important;
/*color: #681616 !important;*/
border-color: #E1EDF8 !important;
}

Loading…
Cancel
Save