Merge branch 'dev_cxt2' into dev_cxt

dev_ec
cxt 5 years ago
commit 913432aa22

@ -378,7 +378,6 @@ DEPENDENCIES
kaminari (~> 1.1, >= 1.1.1)
listen (>= 3.0.5, < 3.2)
mysql2 (>= 0.4.4, < 0.6.0)
newrelic_rpm
oauth2
pdfkit
puma (~> 3.11)

@ -13,6 +13,7 @@
//= require bootstrap-datepicker
//= require bootstrap.viewer
//= require jquery.mloading
//= require jquery-confirm.min
//= require common
//= require echarts

@ -0,0 +1,12 @@
$(document).on('turbolinks:load', function(){
$(document).on('click', '.batch-all-check-box', function(){
var $checkAll = $(this);
$('.batch-check-box').prop('checked', $checkAll.is(':checked'));
})
$(document).on('click', '.batch-check-box', function(){
var allChecked = $('.batch-check-box:checked').length === $('.batch-check-box').length
$('.batch-all-check-box').prop('checked', allChecked);
})
});

@ -10,11 +10,41 @@ $(document).on('turbolinks:load', function() {
$searchFrom.find('select[name="status"]').val('processed');
if($link.data('value') === 'processed'){
$('.batch-action-container').hide();
$searchFrom.find('.status-filter').show();
} else {
$('.batch-action-container').show();
$searchFrom.find('.status-filter').hide();
$searchFrom.find('select[name="status"]').val('pending');
}
});
$('.batch-agree-btn').on('click', function(){
if($('.batch-check-box:checked').length === 0){
$.notify({ message: '请先选择数据' }, { type: 'info' });
return;
}
customConfirm({
content: '确认审核通过?',
ok: function(){
var ids = $('.batch-check-box:checked').map(function(_, e){ return $(e).val() }).get();
$.ajax({
url: '/admins/identity_authentications/batch_agree',
method: 'POST',
dataType: 'json',
data: { ids: ids },
success: function(data){
$.notify({ message: '操作成功' });
window.location.reload();
},
error: function(res){
$.notify({ message: res.responseJSON.message }, { type: 'danger' });
}
})
}
})
})
}
})

@ -10,11 +10,41 @@ $(document).on('turbolinks:load', function() {
$searchFrom.find('select[name="status"]').val('processed');
if($link.data('value') === 'processed'){
$('.batch-action-container').hide();
$searchFrom.find('.status-filter').show();
} else {
$('.batch-action-container').show();
$searchFrom.find('.status-filter').hide();
$searchFrom.find('select[name="status"]').val('pending');
}
});
$('.batch-agree-btn').on('click', function(){
if($('.batch-check-box:checked').length === 0){
$.notify({ message: '请先选择数据' }, { type: 'info' });
return;
}
customConfirm({
content: '确认审核通过?',
ok: function(){
var ids = $('.batch-check-box:checked').map(function(_, e){ return $(e).val() }).get();
$.ajax({
url: '/admins/professional_authentications/batch_agree',
method: 'POST',
dataType: 'json',
data: { ids: ids },
success: function(data){
$.notify({ message: '操作成功' });
window.location.reload();
},
error: function(res){
$.notify({ message: res.responseJSON.message }, { type: 'danger' });
}
})
}
})
})
}
})

@ -42,4 +42,26 @@ function ajaxErrorNotifyHandler(res) {
function resetFileInputFunc(file){
file.after(file.clone().val(""));
file.remove();
}
function customConfirm(opts){
var okCallback = opts.ok;
var cancelCallback = opts.cancel;
var defaultOpts = {
title: '提示',
buttons: {
ok: {
text: '确认',
btnClass: 'btn btn-primary',
action: okCallback
},
cancel: {
text: '取消',
btnClass: 'btn btn-secondary',
action: cancelCallback
},
}
}
return $.confirm($.extend({}, defaultOpts, opts))
}

File diff suppressed because one or more lines are too long

@ -6,6 +6,7 @@
@import "bootstrap-datepicker";
@import "bootstrap-datepicker.standalone";
@import "jquery.mloading";
@import "jquery-confirm.min";
@import "codemirror/lib/codemirror";
@import "editormd/css/editormd.min";

@ -110,5 +110,11 @@
.CodeMirror {
border: 1px solid #ced4da;
}
.batch-action-container {
margin-bottom: -15px;
padding: 10px 20px 0;
background: #fff;
}
}

File diff suppressed because one or more lines are too long

@ -127,21 +127,21 @@ class AccountsController < ApplicationController
# UserDayCertification.create(user_id: user.id, status: 1)
end
def set_autologin_cookie(user)
token = Token.get_or_create_permanent_login_token(user, "autologin")
cookie_options = {
:value => token.value,
:expires => 1.month.from_now,
:path => '/',
:secure => false,
:httponly => true
}
if edu_setting('cookie_domain').present?
cookie_options = cookie_options.merge(domain: edu_setting('cookie_domain'))
end
cookies[autologin_cookie_name] = cookie_options
logger.info("cookies is #{cookies}")
end
# def set_autologin_cookie(user)
# token = Token.get_or_create_permanent_login_token(user, "autologin")
# cookie_options = {
# :value => token.value,
# :expires => 1.month.from_now,
# :path => '/',
# :secure => false,
# :httponly => true
# }
# if edu_setting('cookie_domain').present?
# cookie_options = cookie_options.merge(domain: edu_setting('cookie_domain'))
# end
# cookies[autologin_cookie_name] = cookie_options
# logger.info("cookies is #{cookies}")
# end
def logout
UserAction.create(action_id: User.current.id, action_type: "Logout", user_id: User.current.id, :ip => request.remote_ip)

@ -1,6 +1,7 @@
class Admins::IdentityAuthenticationsController < Admins::BaseController
def index
params[:status] ||= 'pending'
params[:sort_direction] = params[:status] == 'pending' ? 'asc' : 'desc'
applies = Admins::ApplyUserAuthenticationQuery.call(params.merge(type: 1))
@ -18,6 +19,24 @@ class Admins::IdentityAuthenticationsController < Admins::BaseController
render_success_js
end
def batch_agree
ApplyUserAuthentication.real_name_auth.where(id: params[:ids]).each do |apply|
begin
Admins::IdentityAuths::AgreeApplyService.call(apply)
rescue => e
Util.logger_error(e)
end
end
render_ok
end
def revoke
Admins::IdentityAuths::RevokeApplyService.call(current_apply)
render_success_js
end
private
def current_apply

@ -1,6 +1,7 @@
class Admins::ProfessionalAuthenticationsController < Admins::BaseController
def index
params[:status] ||= 'pending'
params[:sort_direction] = params[:status] == 'pending' ? 'asc' : 'desc'
applies = Admins::ApplyUserAuthenticationQuery.call(params.merge(type: 2))
@ -18,6 +19,23 @@ class Admins::ProfessionalAuthenticationsController < Admins::BaseController
render_success_js
end
def batch_agree
ApplyUserAuthentication.professional_auth.where(id: params[:ids]).each do |apply|
begin
Admins::ProfessionalAuths::AgreeApplyService.call(apply)
rescue => e
Util.logger_error(e)
end
end
render_ok
end
def revoke
Admins::ProfessionalAuths::RevokeApplyService.call(current_apply)
render_success_js
end
private
def current_apply

@ -253,7 +253,10 @@ class ApplicationController < ActionController::Base
if Digest::MD5.hexdigest(content) == params[:chinaoocKey]
user = open_class_user
start_user_session(user) if user
if user
start_user_session(user)
set_autologin_cookie(user)
end
User.current = user
end
end
@ -617,6 +620,22 @@ class ApplicationController < ActionController::Base
cookies[:fileDownload] = true
end
def set_autologin_cookie(user)
token = Token.get_or_create_permanent_login_token(user, "autologin")
cookie_options = {
:value => token.value,
:expires => 1.month.from_now,
:path => '/',
:secure => false,
:httponly => true
}
if edu_setting('cookie_domain').present?
cookie_options = cookie_options.merge(domain: edu_setting('cookie_domain'))
end
cookies[autologin_cookie_name] = cookie_options
logger.info("cookies is #{cookies}")
end
# 149课程的评审用户数据创建包含创建课堂学生
def open_class_user
user = User.find_by(login: "OpenClassUser")

@ -51,7 +51,7 @@ class CommonsController < ApplicationController
200
end
when 'journals_for_message'
course = @object.jour&.course || @object.jour&.student_work&.homework_common&.course
course = @object&.jour_type.to_s == "StudentWorksScore" ? @object.jour&.student_work&.homework_common&.course : @object.jour&.course
if current_user.course_identity(course) >= Course::STUDENT && @object.user != current_user
403
else

@ -128,8 +128,8 @@ class CoursesController < ApplicationController
# POST /courses
# POST /courses.json
def create
ActiveRecord::Base.transaction do
begin
begin
ActiveRecord::Base.transaction do
@course = Course.new(name: params[:name], class_period: params[:class_period], credit: params[:credit],
end_date: params[:end_date], is_public: params[:is_public], school_id: @school.id,
authentication: params[:authentication], professional_certification: params[:professional_certification])
@ -174,11 +174,12 @@ class CoursesController < ApplicationController
course_module_types = params[:course_module_types]
@course.create_course_modules(course_module_types)
end
rescue => e
uid_logger_error(e.message)
tip_exception(e.message)
raise ActiveRecord::Rollback
end
CreateSubjectCourseStudentJob.perform_later(@course.id) if @course.subject && @course.subject.subject_appointments.count > 0
rescue => e
uid_logger_error(e.message)
tip_exception(e.message)
raise ActiveRecord::Rollback
end
end
@ -306,8 +307,8 @@ class CoursesController < ApplicationController
def destroy
if @course.is_delete == 0
@course.delete!
Tiding.create!(user_id: @course.tea_id, trigger_user_id: 0, container_id: @course.id,
container_type: 'Course', tiding_type: 'Delete', extra: @course.name)
Tiding.create!(user_id: current_user.id, trigger_user_id: current_user.id, container_id: @course.id,
container_type: 'DeleteCourse', tiding_type: 'System', belong_container: @course, extra: @course.name)
normal_status(0, "成功")
else
normal_status(-1, "课堂已删除,无需重复操作")
@ -571,6 +572,10 @@ class CoursesController < ApplicationController
tip_exception("删除失败") if course_member.CREATOR? or course_member.STUDENT?
course_student = CourseMember.find_by(user_id: course_member.user_id, course_id: @course.id, role: %i[STUDENT])
# Tiding.create!(user_id: course_member.user_id, trigger_user_id: current_user.id, container_id: @course.id,
# container_type: 'DeleteCourseMember', tiding_type: 'System', belong_container: @course, extra: @course.name)
CourseDeleteStudentNotifyJob.perform_later(@course.id, [course_member.user_id], current_user.id)
course_member.destroy!
course_student.update_attributes(is_active: 1) if course_student.present? && !course_student.is_active
normal_status(0, "删除成功")
@ -801,6 +806,7 @@ class CoursesController < ApplicationController
end
end
CourseDeleteStudentDeleteWorksJob.perform_later(@course.id, student_ids) if student_ids.present?
CourseDeleteStudentNotifyJob.perform_later(@course.id, student_ids, current_user.id) if student_ids.present?
normal_status(0, "操作成功")
rescue => e
uid_logger(e.message)

@ -656,7 +656,17 @@ class ExerciseQuestionsController < ApplicationController
:exercise_answer_id => ex_answer_comment_id
}
@exercise_comments = ExerciseAnswerComment.new(comment_option)
@exercise_comments.save
@exercise_comments.save!
# 给被评阅人发送消息,同一个教师评阅无需重复发消息
unless Tiding.where(user_id: @user_id, trigger_user_id: current_user.id, parent_container_id: @exercise.id, parent_container_type: "ExerciseScore").exists?
Tiding.create!(user_id: @user_id, trigger_user_id: current_user.id, container_id: @exercise.id,
container_type: "Exercise", parent_container_id: @exercise.id,
parent_container_type: "ExerciseScore", belong_container_id: @course.id,
belong_container_type: 'Course', tiding_type: "Exercise")
end
end
rescue Exception => e
uid_logger_error(e.message)

@ -476,10 +476,13 @@ class GamesController < ApplicationController
if @myshixun.shixun.try(:status) < 2
tip_exception("代码获取异常,请检查实训模板的评测设置是否正确")
else
# 报错继续retry
tip_exception(-3, "#{e.message}")
end
end
# 如果报错了并且retry 为1的时候则fork一个新的仓库
if params[:retry].to_i == 1
project_fork(@myshixun, @shixun.repo_path, current_user.login)
end
tip_exception(0, e.message)
end
end

@ -19,43 +19,48 @@ class GitsController < ApplicationController
result = false
if request.env["HTTP_AUTHORIZATION"] && request.env["HTTP_AUTHORIZATION"].split(" ").length == 2
username_password = Base64.decode64(request.env["HTTP_AUTHORIZATION"].split(" ")[1])
input_username = username_password.split(":")[0].strip()
input_password = username_password.split(":")[1].strip()
uid_logger("git start auth: input_username is #{input_username}")
# Git 超级权限用户
if input_username.strip == gituser.strip && input_password.strip == gitpassword.strip
result = true
if username_password.split(":")[0].nil? || username_password.split(":")[1].nil?
result = false
else
# 用户是否对对象拥有权限
system_user = User.find_by_login(input_username) || User.find_by_mail(input_username) || User.find_by_phone(input_username)
input_username = username_password.split(":")[0].strip()
input_password = username_password.split(":")[1].strip()
uid_logger("git start auth: input_username is #{input_username}")
# 如果用户名密码错误
if system_user && !system_user.check_password?(input_password)
uid_logger_error("git start: password is wrong")
result = false
# Git 超级权限用户
if input_username.strip == gituser.strip && input_password.strip == gitpassword.strip
result = true
else
git_url = params["url"]
username = git_url.split("/")[0]
shixunname = git_url.split("/")[1].split(".")[0]
repo_name = username + "/" + shixunname
uid_logger("git start: repo_name is #{repo_name}")
shixun = Shixun.select([:id, :user_id, :repo_name, :identifier]).where(repo_name: repo_name).first
uid_logger("git start auth: shixun identifier is #{shixun.try(:identifier)}")
uid_logger("git start auth: systemuser is #{system_user.try(:login)}")
# 用户是否对对象拥有权限
system_user = User.find_by_login(input_username) || User.find_by_mail(input_username) || User.find_by_phone(input_username)
if shixun.present?
if system_user.present? && system_user.manager_of_shixun?(shixun)
result = true
# 如果用户名密码错误
if system_user && !system_user.check_password?(input_password)
uid_logger_error("git start: password is wrong")
result = false
else
git_url = params["url"]
username = git_url.split("/")[0]
shixunname = git_url.split("/")[1].split(".")[0]
repo_name = username + "/" + shixunname
uid_logger("git start: repo_name is #{repo_name}")
shixun = Shixun.select([:id, :user_id, :repo_name, :identifier]).where(repo_name: repo_name).first
uid_logger("git start auth: shixun identifier is #{shixun.try(:identifier)}")
uid_logger("git start auth: systemuser is #{system_user.try(:login)}")
if shixun.present?
if system_user.present? && system_user.manager_of_shixun?(shixun)
result = true
else
uid_logger_error("gituser is not shixun manager")
result = false
end
else
uid_logger_error("gituser is not shixun manager")
result = false
uid_logger_error("shixun is not exist")
# result = false
result = true # 为了测试跳出
end
else
uid_logger_error("shixun is not exist")
# result = false
result = true # 为了测试跳出
end
end
end

@ -1,18 +1,18 @@
class GraduationWorksController < ApplicationController
before_action :require_login, :check_auth
before_action :find_task, only: [:new, :create, :search_member_list, :check_project, :relate_project,
:cancel_relate_project]
:cancel_relate_project, :delete_work]
before_action :find_work, only: [:show, :edit, :update, :revise_attachment, :supply_attachments, :comment_list,
:add_score, :delete_score, :adjust_score, :assign_teacher]
before_action :user_course_identity
before_action :task_public
before_action :teacher_allowed, only: [:add_score, :adjust_score, :assign_teacher]
before_action :course_student, only: [:new, :create, :edit, :update, :search_member_list, :relate_project,
:cancel_relate_project]
:cancel_relate_project, :delete_work]
before_action :my_work, only: [:edit, :update, :revise_attachment]
before_action :published_task, only: [:new, :create, :edit, :update, :search_member_list, :relate_project,
:cancel_relate_project, :revise_attachment]
before_action :edit_duration, only: [:edit, :update]
before_action :edit_duration, only: [:edit, :update, :delete_work]
before_action :open_work, only: [:show, :supply_attachments, :comment_list]
def new
@ -47,6 +47,24 @@ class GraduationWorksController < ApplicationController
@members = @members.page(page).per(limit).includes(:course_group, user: :user_extension)
end
def delete_work
ActiveRecord::Base.transaction do
begin
work = @task.graduation_works.find_by!(user_id: params[:user_id])
tip_exception("只有组长才能删除组员") if work.commit_user_id != current_user.id
work.update_attributes(description: nil, project_id: 0, late_penalty: 0, work_status: 0, commit_time: nil,
update_time: nil, group_id: 0, commit_user_id: nil, final_score: nil, work_score: nil,
teacher_score: nil, teaching_asistant_score: nil, update_user_id: nil)
work.attachments.destroy_all
work.tidings.destroy_all
normal_status("删除成功")
rescue Exception => e
uid_logger(e.message)
tip_exception(e.message)
end
end
end
# 判断项目是否已有其他作品关联上了
def check_project
tip_exception("项目id不能为空") if params[:project_id].blank?
@ -374,6 +392,11 @@ class GraduationWorksController < ApplicationController
new_score.save!
@work.update_attributes(ultimate_score: 1, work_score: params[:score].to_f)
Tiding.create!(user_id: @work.user_id, trigger_user_id: current_user.id, container_id: new_score.id,
container_type: "AdjustScore", parent_container_id: @task.id,
parent_container_type: "GraduationTask", belong_container_id: @course.id,
belong_container_type: 'Course', tiding_type: "GraduationTask")
normal_status("调分成功")
rescue Exception => e
uid_logger(e.message)

@ -224,7 +224,7 @@ class StudentWorksController < ApplicationController
raise ActiveRecord::Rollback
end
SubmitStudentWorkNotifyJob.perform_later(@homework.id, student_ids) if student_ids.present?
ResubmitStudentWorkNotifyJob.perform_later(@homework.id, student_ids) if student_ids.present?
end
end
@ -333,6 +333,11 @@ class StudentWorksController < ApplicationController
@work.update_attributes(update_time: Time.now)
# 补交附件时给评阅过作品的教师、助教发消息
unless @work.student_works_scores.where.not(score: nil).where(reviewer_role: [1, 2]).pluck(user_id).uniq.blank?
ResubmitStudentWorkNotifyJob.perform_later(@homework.id, [current_user.id])
end
normal_status(0, "提交成功")
rescue Exception => e
uid_logger(e.message)
@ -551,6 +556,11 @@ class StudentWorksController < ApplicationController
@work.work_score = params[:score].to_f
@work.save!
Tiding.create!(user_id: @work.user_id, trigger_user_id: current_user.id, container_id: new_score.id,
container_type: "AdjustScore", parent_container_id: @homework.id,
parent_container_type: "HomeworkCommon", belong_container_id: @course.id,
belong_container_type: 'Course', tiding_type: "HomeworkCommon")
normal_status(0,"调分成功")
rescue Exception => e
uid_logger(e.message)

@ -134,6 +134,15 @@ module TidingDecorator
end
end
def delete_course_content
I18n.t(locale_format) % container.name
end
def delete_course_member_content
name = Course.find_by(id: container_id)&.name
I18n.t(locale_format) % [trigger_user&.show_real_name, name]
end
def shixun_content
I18n.t(locale_format) % container.name
end
@ -331,13 +340,21 @@ module TidingDecorator
end
def student_work_content
I18n.t(locale_format(extra.nil?)) % container&.homework_common.try(:name)
I18n.t(locale_format) % container&.homework_common.try(:name)
end
def resubmit_student_work_content
I18n.t(locale_format) % container&.homework_common.try(:name)
end
def student_works_score_content
I18n.t(locale_format(extra)) % container&.student_work&.homework_common.try(:name)
end
def adjust_score_content
I18n.t(locale_format) % parent_container.try(:name)
end
def challenge_work_score_content
I18n.t(locale_format) % container&.comment
end

@ -0,0 +1,22 @@
# 删除课堂用户
class CourseDeleteStudentNotifyJob < ApplicationJob
queue_as :notify
def perform(course_id, student_ids, trigger_user_id)
course = Course.find_by(id: course_id)
return if course.blank?
attrs = %i[user_id trigger_user_id container_id container_type belong_container_id
belong_container_type tiding_type created_at updated_at]
same_attrs = {
trigger_user_id: trigger_user_id, container_id: course.id, container_type: 'DeleteCourseMember',
belong_container_id: course.id, belong_container_type: 'Course', tiding_type: 'System'
}
Tiding.bulk_insert(*attrs) do |worker|
student_ids.each do |user_id|
worker.add same_attrs.merge(user_id: user_id)
end
end
end
end

@ -0,0 +1,22 @@
class CreateSubjectCourseStudentJob < ApplicationJob
queue_as :default
def perform(course_id)
course = Course.find_by(id: course_id)
return if course.blank? || course.subject.blank?
attrs = %i[course_id user_id role created_at updated_at]
same_attrs = {course_id: course.id, role: 4}
Rails.logger.info("1:course.students.count:##{course.students.count}")
CourseMember.bulk_insert(*attrs) do |worker|
course.subject.subject_appointments.each do |app|
Rails.logger.info("##{course.students.where(user_id: app.user_id)}")
next if course.students.where(user_id: app.user_id).any?
worker.add same_attrs.merge(user_id: app.user_id)
end
end
Rails.logger.info("2:course.students.count:##{course.students.count}")
course.subject.subject_appointments.destroy_all
end
end

@ -0,0 +1,33 @@
class ResubmitStudentWorkNotifyJob < ApplicationJob
queue_as :notify
def perform(homework_id, student_ids)
homework = HomeworkCommon.find_by(id: homework_id)
return if homework.blank? || student_ids.blank?
course = homework.course
attrs = %i[user_id trigger_user_id container_id container_type parent_container_id parent_container_type
belong_container_id belong_container_type tiding_type viewed created_at updated_at]
same_attrs = {
container_type: 'ResubmitStudentWork', parent_container_id: homework.id, parent_container_type: 'HomeworkCommon',
belong_container_id: course.id, belong_container_type: 'Course', tiding_type: 'HomeworkCommon', viewed: 0
}
Tiding.bulk_insert(*attrs) do |worker|
student_ids.each do |user_id|
next unless User.exists?(id: user_id)
work = homework.student_works.find_by(user_id: user_id)
next if work.blank?
score_user_ids = work.student_works_scores.where.not(score: nil).where(reviewer_role: [1, 2]).pluck(user_id).uniq
next if score_user_ids.blank?
attrs = same_attrs.merge(trigger_user_id: user_id, container_id: work.id)
score_user_ids.each do |user_id|
worker.add attrs.merge(user_id: user_id)
end
end
end
end
end

@ -18,6 +18,10 @@ class ApplyUserAuthentication < ApplicationRecord
nil
end
def revoke!
update!(status: 3)
end
private
def send_tiding

@ -134,6 +134,11 @@ class HomeworkCommon < ApplicationRecord
self.homework_type == 'practice' && self.publish_time.present? && self.publish_time < Time.now && self.homework_group_reviews.count == 0
end
# 作业查看最新成绩
def update_score identity
identity < Course::NORMAL && publish_time.present? && publish_time < Time.now && !course.is_end
end
# 作业能否立即发布
def publish_immediately user
homework_detail_manual.try(:comment_status) == 0 || homework_group_settings.where(course_group_id: course.charge_group_ids(user)).

@ -104,7 +104,7 @@ class Poll < ApplicationRecord
status = 4
else
if user.present? && user.student_of_course?(course)
ex_time = get_poll_times(user_id,false)
ex_time = get_poll_times(user.id,false)
pb_time = ex_time[:publish_time]
ed_time = ex_time[:end_time]
if pb_time.present? && ed_time.present? && pb_time <= Time.now && ed_time > Time.now

@ -46,6 +46,10 @@ class Subject < ApplicationRecord
courses.where("start_date <= '#{Date.today}' and end_date >= '#{Date.today}'").count > 0
end
def has_participate?
subject_appointments.exists?(user_id: User.current.id)
end
# 挑战过路径的成员数(金课统计去重后的报名人数)
def member_count
excellent ? CourseMember.where(role: 4, course_id: courses.pluck(:id)).pluck(:user_id).length : shixuns.pluck(:myshixuns_count).sum

@ -0,0 +1,26 @@
class Admins::IdentityAuths::RevokeApplyService < ApplicationService
attr_reader :apply, :user
def initialize(apply)
@apply = apply
@user = apply.user
end
def call
ActiveRecord::Base.transaction do
apply.revoke!
user.update!(authentication: false)
deal_tiding!
end
end
private
def deal_tiding!
Tiding.create!(user_id: apply.user_id, trigger_user_id: 0,
container_id: apply.id, container_type: 'CancelUserAuthentication',
belong_container_id: apply.user_id, belong_container_type: 'User',
status: 1, tiding_type: 'System')
end
end

@ -0,0 +1,26 @@
class Admins::ProfessionalAuths::RevokeApplyService < ApplicationService
attr_reader :apply, :user
def initialize(apply)
@apply = apply
@user = apply.user
end
def call
ActiveRecord::Base.transaction do
apply.revoke!
user.update!(professional_certification: false)
deal_tiding!
end
end
private
def deal_tiding!
Tiding.create!(user_id: apply.user_id, trigger_user_id: 0,
container_id: apply.id, container_type: 'CancelUserProCertification',
belong_container_id: apply.user_id, belong_container_type: 'User',
status: 1, tiding_type: 'System')
end
end

@ -25,6 +25,10 @@
<% end %>
</div>
<div class="batch-action-container">
<%= javascript_void_link '批量同意', class: 'btn btn-outline-primary btn-sm batch-agree-btn' %>
</div>
<div class="box identity-authentication-list-container">
<%= render(partial: 'admins/identity_authentications/shared/list', locals: { applies: @applies }) %>
</div>

@ -3,6 +3,12 @@
<table class="table table-hover text-center identity-authentication-list-table">
<thead class="thead-light">
<tr>
<% unless is_processed %>
<th width="4%">
<%= check_box_tag('all-check', 1, false, id: nil, class: 'batch-all-check-box',
data: { toggle: 'tooltip', title: '全选' }) %>
</th>
<% end %>
<th width="8%">头像</th>
<th width="10%">姓名</th>
<th width="14%">身份证号</th>
@ -14,12 +20,14 @@
<i class="fa fa-question-circle" data-toggle="tooltip" data-html="true" data-placement="top" title="审核完成后自动删除图片"></i>
</th>
<% end %>
<th width="16%">时间</th>
<% if is_processed %>
<th width="14%">拒绝原因</th>
<th width="10%">时间</th>
<th width="12%">拒绝原因</th>
<th width="8%">状态</th>
<th width="8%">操作</th>
<% else %>
<th width="20%">操作</th>
<th width="16%">时间</th>
<th width="16%">操作</th>
<% end %>
</tr>
</thead>
@ -28,6 +36,9 @@
<% applies.each do |apply| %>
<% user = apply.user %>
<tr class="identity-authentication-item identity-authentication-<%= apply.id %>">
<% unless is_processed %>
<td><%= check_box_tag('ids[]', apply.id, false, id: nil, class: 'batch-check-box') %></td>
<% end %>
<td>
<%= link_to "/users/#{user.login}", class: 'identity-authentication-avatar', target: '_blank', data: { toggle: 'tooltip', title: '个人主页' } do %>
<img src="/images/<%= url_to_avatar(user) %>" class="rounded-circle" width="40" height="40" />
@ -53,6 +64,11 @@
<% if is_processed %>
<td class="text-secondary"><%= overflow_hidden_span apply.remarks, width: 140 %></td>
<td><span class="apply-status-<%= apply.status %>"><%= apply.status_text %></span></td>
<td>
<% if apply.status == 1 %>
<%= agree_link '撤销', revoke_admins_identity_authentication_path(apply, element: ".identity-authentication-#{apply.id}"), 'data-confirm': '是否确认撤销认证??' %>
<% end %>
</td>
<% else %>
<td class="action-container">
<%= agree_link '同意', agree_admins_identity_authentication_path(apply, element: ".identity-authentication-#{apply.id}"), 'data-confirm': '确认审核通过?' %>

@ -25,6 +25,10 @@
<% end %>
</div>
<div class="batch-action-container">
<%= javascript_void_link '批量同意', class: 'btn btn-outline-primary btn-sm batch-agree-btn' %>
</div>
<div class="box professional-authentication-list-container">
<%= render(partial: 'admins/professional_authentications/shared/list', locals: { applies: @applies }) %>
</div>

@ -3,12 +3,18 @@
<table class="table table-hover text-center professional-authentication-list-table">
<thead class="thead-light">
<tr>
<% unless is_processed %>
<th width="4%">
<%= check_box_tag('all-check', 1, false, id: nil, class: 'batch-all-check-box',
data: { toggle: 'tooltip', title: '全选' }) %>
</th>
<% end %>
<th width="8%">头像</th>
<th width="14%">姓名</th>
<th width="28%">学校/单位</th>
<th width="20%">学校/单位</th>
<th width="12%">职称</th>
<% unless is_processed %>
<th width="10%">
<th width="14%">
照片
<i class="fa fa-question-circle" data-toggle="tooltip" data-html="true" data-placement="top" title="审核完成后自动删除图片"></i>
</th>
@ -17,8 +23,9 @@
<% if is_processed %>
<th width="14%">拒绝原因</th>
<th width="8%">状态</th>
<th width="8%">操作</th>
<% else %>
<th width="18%">操作</th>
<th width="22%">操作</th>
<% end %>
</tr>
</thead>
@ -27,6 +34,9 @@
<% applies.each do |apply| %>
<% user = apply.user %>
<tr class="professional-authentication-item professional-authentication-<%= apply.id %>">
<% unless is_processed %>
<td><%= check_box_tag('ids[]', apply.id, false, id: nil, class: 'batch-check-box') %></td>
<% end %>
<td>
<%= link_to "/users/#{user.login}", class: 'professional-authentication-avatar', target: '_blank', data: { toggle: 'tooltip', title: '个人主页' } do %>
<img src="/images/<%= url_to_avatar(user) %>" class="rounded-circle" width="40" height="40" />
@ -51,6 +61,11 @@
<% if is_processed %>
<td class="text-secondary"><%= overflow_hidden_span apply.remarks, width: 140 %></td>
<td><span class="apply-status-<%= apply.status %>"><%= apply.status_text %></span></td>
<td>
<% if apply.status == 1 %>
<%= agree_link '撤销', revoke_admins_professional_authentication_path(apply, element: ".professional-authentication-#{apply.id}"), 'data-confirm': '是否确认撤销认证??' %>
<% end %>
</td>
<% else %>
<td class="action-container">
<%= agree_link '同意', agree_admins_professional_authentication_path(apply, element: ".professional-authentication-#{apply.id}"), 'data-confirm': '确认审核通过?', 'data-disable-with': "提交中..." %>

@ -4,6 +4,7 @@ json.partial! "homework_btn_check", locals: {identity: @user_course_identity, ho
json.partial! "student_btn_check", locals: {identity: @user_course_identity, homework: @homework, work: @work}
json.update_score @homework.update_score(@user_course_identity) if @homework.homework_type == "practice"
json.work_count @work_count
json.all_member_count @all_member_count
json.course_group_count @course.course_groups_count

@ -10,9 +10,11 @@ json.results do
# 去除开头标点符号
reg = /^[,。?:;‘’!“”—……、]/
# 附件的替换
atta_reg = /!\[\]\(\/api\/attachments\/\d+\)/
highlights[:description]&.first&.sub!(reg, '').sub!(atta_reg, '')
highlights[:content]&.first&.sub!(reg, '').sub!(atta_reg, '')
atta_reg = /!\[.*]\(\/api\/attachments\/\d+\)/
highlights[:description]&.first&.sub!(reg, '')
highlights[:description]&.map{|des| des.gsub!(atta_reg, '')}
highlights[:content]&.first&.sub!(reg, '')
highlights[:content]&.map{|des| des.gsub!(atta_reg, '')}
json.content highlights
end

@ -8,9 +8,12 @@ json.shixun_list do
# 去除开头标点符号
reg = /^[,。?:;‘’!“”—……、]/
# 附件的替换
atta_reg = /!\[\]\(\/api\/attachments\/\d+\)/
highlights[:description]&.first&.sub!(reg, '')&.sub!(atta_reg, '')
highlights[:content]&.first&.sub!(reg, '')&.sub!(atta_reg, '')
atta_reg = /!\[.*]\(\/api\/attachments\/\d+\)/
highlights[:description]&.first&.sub!(reg, '')
highlights[:description]&.map{|des| des.gsub!(atta_reg, '')}
highlights[:content]&.first&.sub!(reg, '')
highlights[:content]&.map{|des| des.gsub!(atta_reg, '')}
json.title highlights.delete(:name)&.join('...') || obj.searchable_title
json.description highlights[:description]&.join('...') || Util.extract_content(obj.description)[0..300]&.sub!(atta_reg, '')

@ -28,5 +28,6 @@ if @subject.excellent
if @subject.max_course_end_date.nil? || @subject.max_course_end_date < Date.today
json.student_count @subject.student_count
json.participant_count @subject.participant_count
json.has_participate @subject.has_participate?
end
end

@ -4,5 +4,5 @@ json.name user.full_name
json.grade user.grade
json.identity user&.user_extension&.identity
# json.email user.mail # 邮箱原则上不暴露的,如果实在需要的话只能对某些具体的接口公开
json.image_url url_to_avatar(user)
json.image_url image_tag(url_to_avatar(user))
json.school user.school_name

@ -1,6 +1,6 @@
json.id @user.id
json.name @user.full_name
json.avatar_url url_to_avatar(@user)
json.avatar_url image_tag(url_to_avatar(@user))
json.is_logged_user @user.logged_user?
json.experience @user.experience
json.grade @user.grade

@ -10,7 +10,7 @@
"2_1_end": "你提交的职业认证申请,审核已通过"
"2_2_end": "你提交的职业认证申请,审核未通过<br/><span>原因:%{reason}</span>"
CancelUserAuthentication_end: "取消了你的实名认证:%s %s"
CancelUserProCertification_end: "取消了你的实名认证:%s %s"
CancelUserProCertification_end: "取消了你的职业认证:%s %s"
JoinCourse:
"9_end": "申请加入课堂:%s教师"
"7_end": "申请加入课堂:%s助教"
@ -58,8 +58,8 @@
"2_end": "你提交的试用授权申请,审核未通过<br/><span>原因:%{reason}</span>"
Apply_end: "提交了试用授权申请"
Course_end: "你创建了课堂:%s"
Course:
Delete_end: "你删除了课堂%s"
DeleteCourse_end: "你删除了课堂:%s"
DeleteCourseMember_end: "%s 将从课堂中删除了:%s"
Shixun_end: "你创建了实训:%s"
Subject_end: "你创建了实践课程:%s"
ArchiveCourse_end: "你的课堂已经归档:%s"
@ -185,13 +185,13 @@
NearlyEnd_end: "作业的提交截止时间快到啦:%{name}"
AppealNearlyEnd_end: "作品的匿评申诉时间快到啦:%{name}"
EvaluationNearlyEnd_end: "作业的匿评截止时间快到啦:%{name}"
StudentWork:
true_end: "提交了作品:%s"
false_end: "重新提交了作品,建议您重新评阅:%s"
StudentWork_end: "提交了作品:%s"
ResubmitStudentWork_end: "重新提交了作品,建议您重新评阅作品:%s"
StudentWorksScore:
1_end: "评阅了你的作品:%s"
2_end: "评阅了你的作品:%s"
3_end: "有人匿评了你的作品:%s"
AdjustScore_end: "调整了你的作品得分:%s"
ChallengeWorkScore_end: "调整了你的作品分数:%s"
StudentWorksScoresAppeal:
UserAppealResult:

@ -539,6 +539,7 @@ Rails.application.routes.draw do
post 'relate_project'
get 'cancel_relate_project'
post 'revise_attachment'
delete 'delete_work'
end
member do
@ -883,12 +884,22 @@ Rails.application.routes.draw do
member do
post :agree
post :refuse
post :revoke
end
collection do
post :batch_agree
end
end
resources :professional_authentications, only: [:index] do
member do
post :agree
post :refuse
post :revoke
end
collection do
post :batch_agree
end
end
resources :shixun_authorizations, only: [:index] do

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -65,8 +65,8 @@
"<label>" + imageLang.alt + "</label>" +
"<input type=\"text\" value=\"" + selection + "\" data-alt />" +
"<br/>" +
"<label>" + imageLang.link + "</label>" +
"<input type=\"text\" value=\"http://\" data-link />" +
"<label class=\"image-link\">" + imageLang.link + "</label>" +
"<input class=\"image-link\" type=\"text\" value=\"http://\" data-link />" +
"<br/>" +
( (settings.imageUpload) ? "</form>" : "</div>");

@ -1,4 +1,4 @@
document.write("<link href='//at.alicdn.com/t/font_653600_qa9lwwv74z.css' rel='stylesheet' type='text/css'/>");
document.write("<link href='https://at.alicdn.com/t/font_653600_qa9lwwv74z.css' rel='stylesheet' type='text/css'/>");
/*!
* JavaScript Cookie v2.2.0

@ -1,8 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<!-- width=device-width, initial-scale=1 , shrink-to-fit=no -->
<!--<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests" />-->
<!-- width=device-width, initial-scale=1 , shrink-to-fit=no -->
<!-- <meta name="viewport" content=""> -->
<meta name="theme-color" content="#000000">
<!--<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">-->

@ -72,6 +72,13 @@ html, body {
/* 某些情况下被cm盖住了 */
z-index: 99;
}
/* 图片点击放大的场景,隐藏图片链接 */
.editormd-image-click-expand .editormd-image-dialog {
height: 234px !important;
}
.editormd-image-click-expand .editormd-image-dialog .image-link {
display: none;
}
/* 解决鼠标框选时,左边第一列没高亮的问题 */
.CodeMirror .CodeMirror-lines pre.CodeMirror-line, .CodeMirror .CodeMirror-lines pre.CodeMirror-line-like {
padding: 0 12px ;

@ -2,7 +2,7 @@ import React,{Component} from "React";
import { Form, Select, Input, Button,Checkbox,Upload,Icon,message,Modal, Table, Divider, Tag,DatePicker,Radio,Tooltip,Spin, Pagination} from "antd";
import {Link} from 'react-router-dom';
import locale from 'antd/lib/date-picker/locale/zh_CN';
import { WordsBtn, ConditionToolTip, queryString,getImageUrl, on, off} from 'educoder';
import { WordsBtn, ConditionToolTip, queryString,getImageUrl, on, off, NoneData} from 'educoder';
import axios from 'axios';
import Modals from '../../modals/Modals';
import CoursesListType from '../coursesPublic/CoursesListType';
@ -817,10 +817,8 @@ class CommonWorkList extends Component{
<Spin size="large" spinning={this.state.isSpin}>
<div id="forum_list" className="forum_table">
<div className="mh650 edu-back-white">
<div className="edu-tab-con-box clearfix edu-txt-center">
<img className="edu-nodata-img mb20" src={getImageUrl("images/educoder/nodata.png")}/>
<p className="edu-nodata-p mb30">暂时还没有相关数据哦</p>
</div>
<NoneData></NoneData>
</div>
</div>
</Spin>

@ -479,7 +479,7 @@ class NewWorkForm extends Component{
<InputNumber className="winput-240-40" placeholder="请填写每组最大人数" value={max_num} max={10}
onChange={this.max_num_change} style={{width:'180px'}} />
</ConditionToolTip>
<label className="color-grey-9 ml20 font-14">项目管理员角色的成员都可以提交作品提交作品时需要关联同组成员组内成员作品共享</label>
<label className="color-grey-9 ml20 font-14">学生提交作品时需要关联同组成员组内成员作品共享</label>
</p>
<p className="mt20">
<ConditionToolTip condition={has_commit || has_project} title={'已有关联项目或作品,不能修改'}>
@ -488,7 +488,7 @@ class NewWorkForm extends Component{
>基于项目实施</Checkbox>
</ConditionToolTip>
<label className="color-grey-9 ml12 font-14">勾选后各小组必须在educoder平台创建项目教师可随时观察平台对各小组最新进展的实时统计</label>
<label className="color-grey-9 ml12 font-14">选中则必须在本平台创建项目项目管理员可以提交作品不选中无需在平台创建项目任意小组成员均可以提交作品</label>
</p>
</div>
)}

@ -250,7 +250,7 @@ class CommonReply extends Component{
}
`}</style>
<MemoDetailMDEditor ref="editor" memo={memo} usingMockInput={true} placeholder="说点什么"
height={160} showError={true}
height={160} showError={true} imageExpand={true}
replyComment={this.replyComment}
commentsLength={comments ? comments.length : 0}
></MemoDetailMDEditor>

@ -22,7 +22,7 @@ import 'moment/locale/zh-cn';
import './yslexercisetable.css';
import {getImageUrl, toPath} from 'educoder';
import CheckBoxGroup from "../../page/component/CheckBoxGroup";
import NoneData from '../../../modules/courses/coursesPublic/NoneData'
const Search = Input.Search;
const RadioGroup = Radio.Group;
const CheckboxGroup = Checkbox.Group;
@ -1217,6 +1217,7 @@ class Studentshavecompletedthelist extends Component {
)
},
],
exercise_status:0,
}
// console.log("Studentshavecompletedthelist");
// console.log(props.current_status);
@ -1277,6 +1278,20 @@ class Studentshavecompletedthelist extends Component {
}catch (e) {
}
try {
if(this.props.Commonheadofthetestpaper.exercise_status !== undefined){
this.setState({
exercise_status:this.props.Commonheadofthetestpaper.exercise_status,
})
}else{
this.setState({
exercise_status:0,
})
}
}catch (e) {
}
}
componentWillReceiveProps = (nextProps) => {
@ -2065,11 +2080,11 @@ class Studentshavecompletedthelist extends Component {
this.setState({
loadingstate: false,
})
console.log(response);
console.log(1997);
// console.log(response);
// console.log(1997);
this.Generatenewdatasy(response.data.exercise_users, response);
}).catch((error) => {
console.log(error)
// console.log(error)
this.setState({
loadingstate: false,
})
@ -2472,7 +2487,7 @@ class Studentshavecompletedthelist extends Component {
render() {
const isAdmin = this.props.isAdmin();
let {data, datas, page, columns, course_groupyslsthree, columnstwo, styletable, course_groupyslstwodatas, limit, course_groupysls, course_groupyslstwodata, course_groupyslstwo, teacherlists, Teacherliststudentlist, order, columnss, course_groupsdatas, course_groups, Evaluationarray, unlimited, unlimiteds, unlimitedtwo, teacherlist, searchtext, loadingstate, review, nocomment, commented, unsubmitted, submitted, columnsys, exercise_users,mylistansum} = this.state;
let {data, datas, page, columns, course_groupyslsthree, columnstwo, styletable,exercise_status, course_groupyslstwodatas, limit, course_groupysls, course_groupyslstwodata, course_groupyslstwo, teacherlists, Teacherliststudentlist, order, columnss, course_groupsdatas, course_groups, Evaluationarray, unlimited, unlimiteds, unlimitedtwo, teacherlist, searchtext, loadingstate, review, nocomment, commented, unsubmitted, submitted, columnsys, exercise_users,mylistansum} = this.state;
// console.log("Studentshavecompletedthelist");
// console.log(this.props.current_status);
return (
@ -2483,202 +2498,211 @@ class Studentshavecompletedthelist extends Component {
" min-width": " 1200px",
}}>
{/*老师*/}
<div className="edu-back-white" >
<ul className="clearfix" style={{padding: '10px 30px 10px 30px'}}>
{
exercise_status===0 || exercise_status===1 ?
<div className="edu-back-white">
<NoneData></NoneData>
</div>
:
<div>
<div className="edu-back-white" >
<ul className="clearfix" style={{padding: '10px 30px 10px 30px'}}>
{/*你的评阅:*/}
{
Teacherliststudentlist === undefined || Teacherliststudentlist.exercise_types.subjective === 0 ?
<li className="clearfix mt10">
<span className="fl mr10 color-grey-8 ">作品状态</span>
<span className="fl "><a id="graduation_comment_no_limit"
className={unlimiteds === 0 ? "pl10 pr10 mr20 check_on" : "pl10 pr10 mr20 "}
onClick={() => this.notlimiteds()}>不限</a></span>
<CheckboxGroup value={course_groupyslstwo}
onChange={(e) => this.checkeboxstwo(e, course_groupyslstwodata && course_groupyslstwodata)}>
{
course_groupyslstwodata.map((item, key) => {
return (
<span key={key}><Checkbox className="fl mt5"
key={item.id}
value={item.id}>{item.tu}<span>({Teacherliststudentlist === undefined ? "0" : key === 0 ? Teacherliststudentlist.exercise_types.unanswer_users : Teacherliststudentlist.exercise_types.answer_users})</span></Checkbox></span>
)
})
}
</CheckboxGroup>
<div className="fr mr5 search-new" style={{marginBottom: '1px'}}>
<Search
placeholder="请输入姓名或学号搜索"
id="subject_search_input"
autoComplete="off"
value={searchtext}
onKeyUp={(e) => this.onSearchKeywordKeyUp(e)}
onInput={this.inputSearchValues}
onSearch={this.searchValues}
></Search>
</div>
</li>
:
<div>
<li className="clearfix mt10">
<span className="fl mr10 color-grey-8 ">你的评阅</span>
<span className="fl "><a id="graduation_comment_no_limit"
className={unlimited === 0 ? "pl10 pr10 mr20 check_on" : "pl10 pr10 mr20 "}
onClick={() => this.notlimited()}>不限</a></span>
<CheckboxGroup value={course_groupyslsthree}
onChange={(e) => this.checkeboxs(e, course_groupyslstwodata && course_groupyslstwodata)}>
{
course_groupyslstwodatas.map((item, key) => {
return (
<span key={key}><Checkbox className="fl mt5"
key={item.id}
value={item.id}>{item.tu}<span>({Teacherliststudentlist === undefined ? "0" : key === 0 ? Teacherliststudentlist.exercise_types.unreview_counts : Teacherliststudentlist.exercise_types.review_counts})</span></Checkbox></span>
)
})
}
</CheckboxGroup>
<div className="fr mr5 search-new" style={{marginBottom: '1px'}}>
<Search
placeholder="请输入姓名或学号搜索"
id="subject_search_input"
autoComplete="off"
value={searchtext}
onKeyUp={(e) => this.onSearchKeywordKeyUp(e)}
onInput={this.inputSearchValues}
onSearch={this.searchValues}
></Search>
</div>
</li>
{/*作品状态*/}
<li className="clearfix mt10">
<span className="fl mr10 color-grey-8 ">作品状态</span>
<span className="fl "><a id="graduation_comment_no_limit"
className={unlimiteds === 0 ? "pl10 pr10 mr20 check_on" : "pl10 pr10 mr20 "}
onClick={() => this.notlimiteds()}>不限</a></span>
<CheckboxGroup value={course_groupyslstwo}
onChange={(e) => this.checkeboxstwo(e, course_groupyslstwodata && course_groupyslstwodata)}>
{
course_groupyslstwodata.map((item, key) => {
return (
<span key={key}><Checkbox className="fl mt5"
key={item.id}
value={item.id}>{item.tu}<span>({Teacherliststudentlist === undefined ? "0" : key === 0 ? Teacherliststudentlist.exercise_types.unanswer_users : Teacherliststudentlist.exercise_types.answer_users})</span></Checkbox></span>
)
})
}
</CheckboxGroup>
</li>
</div>
{/*你的评阅:*/}
{
Teacherliststudentlist === undefined || Teacherliststudentlist.exercise_types.subjective === 0 ?
<li className="clearfix mt10">
<span className="fl mr10 color-grey-8 ">作品状态</span>
<span className="fl "><a id="graduation_comment_no_limit"
className={unlimiteds === 0 ? "pl10 pr10 mr20 check_on" : "pl10 pr10 mr20 "}
onClick={() => this.notlimiteds()}>不限</a></span>
<CheckboxGroup value={course_groupyslstwo}
onChange={(e) => this.checkeboxstwo(e, course_groupyslstwodata && course_groupyslstwodata)}>
{
course_groupyslstwodata.map((item, key) => {
return (
<span key={key}><Checkbox className="fl mt5"
key={item.id}
value={item.id}>{item.tu}<span>({Teacherliststudentlist === undefined ? "0" : key === 0 ? Teacherliststudentlist.exercise_types.unanswer_users : Teacherliststudentlist.exercise_types.answer_users})</span></Checkbox></span>
)
})
}
</CheckboxGroup>
<div className="fr mr5 search-new" style={{marginBottom: '1px'}}>
<Search
placeholder="请输入姓名或学号搜索"
id="subject_search_input"
autoComplete="off"
value={searchtext}
onKeyUp={(e) => this.onSearchKeywordKeyUp(e)}
onInput={this.inputSearchValues}
onSearch={this.searchValues}
></Search>
</div>
</li>
:
<div>
<li className="clearfix mt10">
<span className="fl mr10 color-grey-8 ">你的评阅</span>
<span className="fl "><a id="graduation_comment_no_limit"
className={unlimited === 0 ? "pl10 pr10 mr20 check_on" : "pl10 pr10 mr20 "}
onClick={() => this.notlimited()}>不限</a></span>
<CheckboxGroup value={course_groupyslsthree}
onChange={(e) => this.checkeboxs(e, course_groupyslstwodata && course_groupyslstwodata)}>
{
course_groupyslstwodatas.map((item, key) => {
return (
<span key={key}><Checkbox className="fl mt5"
key={item.id}
value={item.id}>{item.tu}<span>({Teacherliststudentlist === undefined ? "0" : key === 0 ? Teacherliststudentlist.exercise_types.unreview_counts : Teacherliststudentlist.exercise_types.review_counts})</span></Checkbox></span>
)
})
}
</CheckboxGroup>
<div className="fr mr5 search-new" style={{marginBottom: '1px'}}>
<Search
placeholder="请输入姓名或学号搜索"
id="subject_search_input"
autoComplete="off"
value={searchtext}
onKeyUp={(e) => this.onSearchKeywordKeyUp(e)}
onInput={this.inputSearchValues}
onSearch={this.searchValues}
></Search>
</div>
</li>
{/*作品状态*/}
<li className="clearfix mt10">
<span className="fl mr10 color-grey-8 ">作品状态</span>
<span className="fl "><a id="graduation_comment_no_limit"
className={unlimiteds === 0 ? "pl10 pr10 mr20 check_on" : "pl10 pr10 mr20 "}
onClick={() => this.notlimiteds()}>不限</a></span>
<CheckboxGroup value={course_groupyslstwo}
onChange={(e) => this.checkeboxstwo(e, course_groupyslstwodata && course_groupyslstwodata)}>
{
course_groupyslstwodata.map((item, key) => {
return (
<span key={key}><Checkbox className="fl mt5"
key={item.id}
value={item.id}>{item.tu}<span>({Teacherliststudentlist === undefined ? "0" : key === 0 ? Teacherliststudentlist.exercise_types.unanswer_users : Teacherliststudentlist.exercise_types.answer_users})</span></Checkbox></span>
)
})
}
</CheckboxGroup>
</li>
</div>
}
{/*分班情况*/}
{course_groups === undefined ? "" : course_groups === null ? "" : course_groups.length < 2 ? "" : JSON.stringify(course_groups) === "[]" ? "" :
<li className="clearfix mt10">
<tr>
<td className="w80" style={{"vertical-align": "top"}}><span
className=" mr10 color-grey-8 ">分班情况</span></td>
<td className="w70" style={{"vertical-align": "top"}}><span><a
id="graduation_comment_no_limit"
className={unlimitedtwo === 0 ? "pl10 pr10 mr20 check_on" : "pl10 pr10 mr20 "}
onClick={() => this.funtaskstatustwos()}>不限</a></span>
</td>
<td>
<CheckboxGroup value={course_groupysls}
onChange={(e) => this.funtaskstatustwo(e, course_groups && course_groups)}
style={{paddingTop: '4px', display: "inline"}}>
{
course_groups.map((item, key) => {
return (
<span key={key}><Checkbox className="fl mt5"
key={item.exercise_group_id}
value={item.exercise_group_id}>{item.exercise_group_name}<span>({item.exercise_group_students})</span></Checkbox></span>
)
})
}
</CheckboxGroup>
}
{/*分班情况*/}
{course_groups === undefined ? "" : course_groups === null ? "" : course_groups.length < 2 ? "" : JSON.stringify(course_groups) === "[]" ? "" :
<li className="clearfix mt10">
<tr>
<td className="w80" style={{"vertical-align": "top"}}><span
className=" mr10 color-grey-8 ">分班情况</span></td>
<td className="w70" style={{"vertical-align": "top"}}><span><a
id="graduation_comment_no_limit"
className={unlimitedtwo === 0 ? "pl10 pr10 mr20 check_on" : "pl10 pr10 mr20 "}
onClick={() => this.funtaskstatustwos()}>不限</a></span>
</td>
<td>
<CheckboxGroup value={course_groupysls}
onChange={(e) => this.funtaskstatustwo(e, course_groups && course_groups)}
style={{paddingTop: '4px', display: "inline"}}>
{
course_groups.map((item, key) => {
return (
<span key={key}><Checkbox className="fl mt5"
key={item.exercise_group_id}
value={item.exercise_group_id}>{item.exercise_group_name}<span>({item.exercise_group_students})</span></Checkbox></span>
)
})
}
</CheckboxGroup>
</td>
</tr>
</td>
</tr>
</li>
}
</li>
}
</ul>
</ul>
<div id="graduation_work_list" style={{padding: '0px 30px 10px 30px'}}>
<div className="clearfix">
<div id="graduation_work_list" style={{padding: '0px 30px 10px 30px'}}>
<div className="clearfix">
<span
className="fl color-grey-6 font-12"><span
style={{color: '#FF6800'}}>{Teacherliststudentlist === undefined ? "0" : Teacherliststudentlist.exercise_types.total_users}</span><span
className="color-orange-tip"></span>{Teacherliststudentlist === undefined ? "0" : Teacherliststudentlist.exercise_types.exercise_all_users} </span>
<div className="fr color-grey-6 edu-menu-panel">
<ul>
<li className="edu-position edu-position-hidebox">
<a className="font-12">
{order === "end_at" ? "时间" : order === "score" ? "成绩" : order === "student_id" ? "学号" : ""}排序</a>
<i className="iconfont icon-xiajiantou ml5 font-12"></i>
<ul className="edu-position-hide undis mt10">
<li><a onClick={(e) => this.funordersy("end_at")} data-remote="true"
className=" font-12" style={{textAlign: "center "}}>提交时间</a></li>
<li><a onClick={(e) => this.funordersy("score")} data-remote="true"
className=" font-12" style={{textAlign: "center "}}>最终成绩</a></li>
<li><a onClick={(e) => this.funordersy("student_id")} data-remote="true"
className=" font-12" style={{textAlign: "center "}}>学生学号</a></li>
</ul>
</li>
</ul>
</div>
<div className="fr color-grey-6 edu-menu-panel">
<ul>
<li className="edu-position edu-position-hidebox">
<a className="font-12">
{order === "end_at" ? "时间" : order === "score" ? "成绩" : order === "student_id" ? "学号" : ""}排序</a>
<i className="iconfont icon-xiajiantou ml5 font-12"></i>
<ul className="edu-position-hide undis mt10">
<li><a onClick={(e) => this.funordersy("end_at")} data-remote="true"
className=" font-12" style={{textAlign: "center "}}>提交时间</a></li>
<li><a onClick={(e) => this.funordersy("score")} data-remote="true"
className=" font-12" style={{textAlign: "center "}}>最终成绩</a></li>
<li><a onClick={(e) => this.funordersy("student_id")} data-remote="true"
className=" font-12" style={{textAlign: "center "}}>学生学号</a></li>
</ul>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
{JSON.stringify(data) !== "[]" ?
<div className={"justify break_full_word new_li edu-back-white"}
style={{minHeight: "480px"}}>
<style>{`
{JSON.stringify(data) !== "[]" ?
<div className={"justify break_full_word new_li edu-back-white"}
style={{minHeight: "480px"}}>
<style>{`
.ant-spin-nested-loading > div > .ant-spin .ant-spin-dot {
top: 72%;}
}
`}</style>
<div className="edu-table edu-back-white">
{data === undefined ? "" : <Table
dataSource={data}
columns={columnsys}
className="mysjysltable1"
pagination={false}
loading={loadingstate}
// onChange={this.TablePaginationsy}
/>}
</div>
</div>
<div className="edu-table edu-back-white">
{data === undefined ? "" : <Table
dataSource={data}
columns={columnsys}
className="mysjysltable1"
pagination={false}
loading={loadingstate}
// onChange={this.TablePaginationsy}
/>}
</div>
</div>
:
<div id="forum_list" className="forum_table">
<div className="minH-560 edu-back-white">
<div className="edu-tab-con-box clearfix edu-txt-center">
<img className="edu-nodata-img mb20"
src={getImageUrl("images/educoder/nodata.png")}/>
<p className="edu-nodata-p mb30">暂时还没有相关数据哦</p>
</div>
</div>
:
<div id="forum_list" className="forum_table">
<div className="minH-560 edu-back-white">
<div className="edu-tab-con-box clearfix edu-txt-center">
<img className="edu-nodata-img mb20"
src={getImageUrl("images/educoder/nodata.png")}/>
<p className="edu-nodata-p mb30">暂时还没有相关数据哦</p>
</div>
</div>
</div>
}
</div>
}
</div>
{
Teacherliststudentlist && Teacherliststudentlist.exercise_types.total_users && Teacherliststudentlist.exercise_types.total_users > limit ?
<div className="edu-txt-center mt30 mb50">
<Pagination showQuickJumper current={page} onChange={this.paginationonChange}
pageSize={limit}
total={Teacherliststudentlist.exercise_types.total_users}></Pagination>
</div>
{
Teacherliststudentlist && Teacherliststudentlist.exercise_types.total_users && Teacherliststudentlist.exercise_types.total_users > limit ?
<div className="edu-txt-center mt30 mb50">
<Pagination showQuickJumper current={page} onChange={this.paginationonChange}
pageSize={limit}
total={Teacherliststudentlist.exercise_types.total_users}></Pagination>
</div>
: ""
}
</div>
: ""
}
</div>
@ -2691,16 +2715,22 @@ class Studentshavecompletedthelist extends Component {
<div>
<div className=" clearfix "
style={{"margin": "0 auto", "padding-bottom": "100px", " min-width": " 1200px"}}>
<div className={"educontent mb20"}>
{
exercise_status === 0 || exercise_status === 1 ?
<div className="edu-back-white">
<NoneData></NoneData>
</div>
:
<div className={"educontent mb20"}>
<div className="edu-back-white" id="graduation_work_list"
style={{
padding: '0px 30px 10px 30px',
"height": "50px",
"margin-bottom": "10px"
}}>
<div className="edu-back-white" id="graduation_work_list"
style={{
padding: '0px 30px 10px 30px',
"height": "50px",
"margin-bottom": "10px"
}}>
<div className="clearfix ">
<div className="clearfix ">
<span className="fl color-grey-6 font-12 mt10">
<span className="color-orange-tip"
style={{color: '#FF6800'}}>{Teacherliststudentlist === undefined ? "0" : Teacherliststudentlist.exercise_types.answer_users}</span><span
@ -2716,45 +2746,45 @@ class Studentshavecompletedthelist extends Component {
</span>}
</span>
</div>
</div>
</div>
</div>
{JSON.stringify(datas) === "[]" ?
<div id="forum_list" className="forum_table">
<div className="mh650 edu-back-white">
<div className="edu-tab-con-box clearfix edu-txt-center">
<img className="edu-nodata-img mb20"
src={getImageUrl("images/educoder/nodata.png")}/>
<p className="edu-nodata-p mb30">暂时还没有相关数据哦</p>
</div>
</div>
{JSON.stringify(datas) === "[]" ?
<div id="forum_list" className="forum_table">
<div className="mh650 edu-back-white">
<div className="edu-tab-con-box clearfix edu-txt-center">
<img className="edu-nodata-img mb20"
src={getImageUrl("images/educoder/nodata.png")}/>
<p className="edu-nodata-p mb30">暂时还没有相关数据哦</p>
</div>
</div>
</div>
:
<div className={"justify break_full_word new_li edu-back-white"}
style={{minHeight: "480px"}}>
<style>{`
</div>
:
<div className={"justify break_full_word new_li edu-back-white"}
style={{minHeight: "480px"}}>
<style>{`
.ant-spin-nested-loading > div > .ant-spin .ant-spin-dot {
top: 72%;}
}
`}</style>
<div className="edu-table edu-back-white minH-560">
{datas === undefined ? "" : <Table
dataSource={datas}
columns={columnss}
className="mysjysltable2"
pagination={false}
loading={false}
/>}
</div>
</div>
}
<div className="edu-table edu-back-white minH-560">
{datas === undefined ? "" : <Table
dataSource={datas}
columns={columnss}
className="mysjysltable2"
pagination={false}
loading={false}
/>}
</div>
</div>
}
</div>
</div>
}
</div>
</div>
@ -2766,10 +2796,17 @@ class Studentshavecompletedthelist extends Component {
"padding-bottom": "100px",
" min-width": " 1200px"
}}>
<div className={"educontent mb20 edu-back-white"}>
<style>
{
`
{
exercise_status === 0 || exercise_status === 1 ?
<div className="edu-back-white">
<NoneData></NoneData>
</div>
:
<div>
<div className={"educontent mb20 edu-back-white"}>
<style>
{
`
.edu-table .ant-table-tbody > tr > td {
height: 58px;
}
@ -2786,40 +2823,40 @@ class Studentshavecompletedthelist extends Component {
padding: 9px;
}
`
}
</style>
<div className={"justify break_full_word new_li edu-back-white ysltableows"}
>
{data === undefined ? "" : <Table
dataSource={data}
columns={columnstwo}
className="mysjysltable3"
pagination={false}
loading={false}
showHeader={false}
/>}
</div>
{JSON.stringify(datas) === "[]" ?
<div id="forum_list" className="forum_table ">
<div className="mh650 edu-back-white">
<div className="edu-tab-con-box clearfix edu-txt-center">
<img className="edu-nodata-img mb20"
src={getImageUrl("images/educoder/nodata.png")}/>
<p className="edu-nodata-p mb30">暂时还没有相关数据哦</p>
}
</style>
<div className={"justify break_full_word new_li edu-back-white ysltableows"}
>
{data === undefined ? "" : <Table
dataSource={data}
columns={columnstwo}
className="mysjysltable3"
pagination={false}
loading={false}
showHeader={false}
/>}
</div>
</div>
{JSON.stringify(datas) === "[]" ?
</div>
:
<div className="edu-back-white">
< div id="graduation_work_list" style={{
padding: '0px 30px 10px 30px',
"margin-top": "20px",
"margin-bottom": "10px"
}}>
<div id="forum_list" className="forum_table ">
<div className="mh650 edu-back-white">
<div className="edu-tab-con-box clearfix edu-txt-center">
<img className="edu-nodata-img mb20"
src={getImageUrl("images/educoder/nodata.png")}/>
<p className="edu-nodata-p mb30">暂时还没有相关数据哦</p>
</div>
</div>
<div className="clearfix">
</div>
:
<div className="edu-back-white">
< div id="graduation_work_list" style={{
padding: '0px 30px 10px 30px',
"margin-top": "20px",
"margin-bottom": "10px"
}}>
<div className="clearfix">
<span className="fl color-grey-6 font-12"><span
className="color-orange-tip"
style={{color: '#FF6800'}}>{Teacherliststudentlist === undefined ? "0" : Teacherliststudentlist.exercise_types.answer_users}</span><span
@ -2832,32 +2869,32 @@ class Studentshavecompletedthelist extends Component {
<span
style={{color: '#FF6800'}}> {Teacherliststudentlist === undefined ? "0" : Teacherliststudentlist.exercise_types.exercise_end_time}</span>}
</span>
<div className="fr color-grey-6 edu-menu-panel">
<ul>
<li className="edu-position edu-position-hidebox">
<a className="font-12 ">
{order === "end_at" ? "时间" : order === "score" ? "成绩" : order === "student_id" ? "学号" : ""}排序</a>
<i className="iconfont icon-xiajiantou ml5 font-12 color-grey-6"></i>
<ul className="edu-position-hide undis mt10">
<li><a onClick={(e) => this.funorder("end_at")} data-remote="true"
className=" font-12" style={{textAlign: "center "}}>提交时间</a>
</li>
<li><a onClick={(e) => this.funorder("score")} data-remote="true"
className=" font-12" style={{textAlign: "center "}}>最终成绩</a>
</li>
<li><a onClick={(e) => this.funorder("student_id")} data-remote="true"
className=" font-12" style={{textAlign: "center "}}>学生学号</a>
</li>
</ul>
</li>
</ul>
</div>
</div>
</div>
<div className={"justify break_full_word new_li edu-back-white"}
style={{minHeight: "480px"}}>
<style>{`
<div className="fr color-grey-6 edu-menu-panel">
<ul>
<li className="edu-position edu-position-hidebox">
<a className="font-12 ">
{order === "end_at" ? "时间" : order === "score" ? "成绩" : order === "student_id" ? "学号" : ""}排序</a>
<i className="iconfont icon-xiajiantou ml5 font-12 color-grey-6"></i>
<ul className="edu-position-hide undis mt10">
<li><a onClick={(e) => this.funorder("end_at")} data-remote="true"
className=" font-12" style={{textAlign: "center "}}>提交时间</a>
</li>
<li><a onClick={(e) => this.funorder("score")} data-remote="true"
className=" font-12" style={{textAlign: "center "}}>最终成绩</a>
</li>
<li><a onClick={(e) => this.funorder("student_id")} data-remote="true"
className=" font-12" style={{textAlign: "center "}}>学生学号</a>
</li>
</ul>
</li>
</ul>
</div>
</div>
</div>
<div className={"justify break_full_word new_li edu-back-white"}
style={{minHeight: "480px"}}>
<style>{`
.ant-spin-nested-loading > div > .ant-spin .ant-spin-dot {
top: 72%;}
}
@ -2877,30 +2914,32 @@ class Studentshavecompletedthelist extends Component {
padding: 9px;
}
`}</style>
<div className="edu-table edu-back-white minH-560 ysltableowss">
{datas === undefined ? "" : <Table
dataSource={datas}
columns={columns}
pagination={false}
className="mysjysltable4"
loading={loadingstate}
/>}</div>
</div>
<div className="edu-table edu-back-white minH-560 ysltableowss">
{datas === undefined ? "" : <Table
dataSource={datas}
columns={columns}
pagination={false}
className="mysjysltable4"
loading={loadingstate}
/>}</div>
</div>
</div>
</div>
}
</div>
}
</div>
{
mylistansum && mylistansum > limit ?
<div className="edu-txt-center mt30 mb20">
<Pagination showQuickJumper current={page}
onChange={this.paginationonChanges} pageSize={limit}
total={mylistansum}></Pagination>
{
mylistansum && mylistansum > limit ?
<div className="edu-txt-center mt30 mb20">
<Pagination showQuickJumper current={page}
onChange={this.paginationonChanges} pageSize={limit}
total={mylistansum}></Pagination>
</div>
: ""
}
</div>
: ""
}
</div>

@ -436,7 +436,7 @@ class Testpapersettinghomepage extends Component{
/>
{
// 教师列表
parseInt(tab[0])==0 && <Studentshavecompletedthelist {...this.props} {...this.state} triggerRef={this.bindRef} setcourse_groupysls={(value)=>this.setcourse_groupysls(value)} current_status = {this.state.current_status}></Studentshavecompletedthelist>
parseInt(tab[0])==0 && <Studentshavecompletedthelist {...this.props} {...this.state} triggerRef={this.bindRef} setcourse_groupysls={(value)=>this.setcourse_groupysls(value)} current_status = {this.state.current_status} Commonheadofthetestpaper={this.state.Commonheadofthetestpaper}></Studentshavecompletedthelist>
}
{/*统计结果*/}

@ -233,7 +233,7 @@ class Bullsubdirectory extends Component{
{
whethertoeditysl === false?
<div>
<div>
<div className="fudonyingxiangysls">
<div className="fudonyingxiangysl">
<div style={{marginRight:"60px"}}>
<span className="ysltitbt">{myname}</span>

@ -70,6 +70,10 @@
.fudonyingxiangysl{
width: 100%;
}
.fudonyingxiangysls{
display: flex;
flex-direction:column;
}
.yslbianji{
padding-top: 31px;

@ -382,7 +382,7 @@ class GraduateTopicPostWorksNew extends Component{
)}
</Form.Item>
<span className="tag color-grey9 ">(项目管理员角色的成员都可以提交作品提交作品时需要关联同组成员组内成员作品共享)</span>
<span className="tag color-grey9 ">(学生提交作品时需要关联同组成员组内成员作品共享)</span>
<Form.Item
label=""
className=" "
@ -394,7 +394,7 @@ class GraduateTopicPostWorksNew extends Component{
<Checkbox >基于项目实施</Checkbox>
)}
</Form.Item>
<span className="tag color-grey9 ">(勾选后各小组必须在educoder平台创建项目教师可随时观察平台对各小组最小进展的实时统计)</span>
<span className="tag color-grey9 ">(选中则必须在本平台创建项目项目管理员可以提交作品不选中无需在平台创建项目任意小组成员均可以提交作品)</span>
</div>
<div className="formBlock">

@ -86,13 +86,13 @@ class Trainingjobsetting extends Component {
latepenaltytype: false,
unifiedsetting: true,
allowreplenishment: undefined,
completionefficiencyscore: true,
completionefficiencyscore: false,
whethertopay: false,
proportion: undefined,
level: undefined,
ealuation: false,
latededuction: undefined,
latedeductiontwo: "20",
latedeductiontwo: "0",
database: false,
datasheet: false,
databasetwo: undefined,
@ -120,8 +120,10 @@ class Trainingjobsetting extends Component {
showmodel:false,
code_review:false,
testscripttiptype:false,
end_timebool:false,
late_timesbool:false,
work_efficiencys:false,
}
// console.log("获取到的值")
// console.log("Trainingjobsetting")
@ -283,7 +285,7 @@ class Trainingjobsetting extends Component {
allowreplenishment: result.data.allow_late,
latededuction: result.data.late_penalty,
level: result.data.answer_open_evaluation === true ? "满分" : "扣分",
completionefficiencyscore: result.data.work_efficiency,
work_efficiencys: result.data.work_efficiency,
latedeductiontwo: result.data.eff_score,
proportion: result.data.shixun_evaluation === 0 ? "均分比例" : result.data.shixun_evaluation === 1 ? "经验值比例" : result.data.shixun_evaluation === 2 ? "自定义分值" : "",
publicwork: result.data.work_public,
@ -634,7 +636,7 @@ class Trainingjobsetting extends Component {
late_penalty: parseInt(this.state.latededuction), //迟交扣分
late_time: moment(this.state.late_time).format('YYYY-MM-DD HH:mm'), //结束时间
answer_open_evaluation: this.state.level === "满分" ? true : false, //扣分项
work_efficiency: this.state.completionefficiencyscore, //完成效率评分占比
work_efficiency: this.state.work_efficiencys, //完成效率评分占比
eff_score: this.state.completionefficiencyscore === true ? this.state.latedeductiontwo : undefined,//占比分
shixun_evaluation: this.state.proportion === "均分比例" ? 0 : this.state.proportion === "经验值比例" ? 1 : this.state.proportion === "自定义分值" ? 2 : 0,
challenge_settings: array,
@ -659,6 +661,7 @@ class Trainingjobsetting extends Component {
flagPageEditsthrees:false,
flagPageEditsfor:false,
whethertopay:false,
completionefficiencyscore:false,
})
this.refs.targetElementTrainingjobsetting.scrollIntoView()
@ -1003,6 +1006,7 @@ class Trainingjobsetting extends Component {
this.state.latedeductiontwo=20;
this.setState({
completionefficiencyscore: e.target.checked,
work_efficiencys:e.target.checked,
latedeductiontwo: 20,
})
//均分比例
@ -1019,6 +1023,7 @@ class Trainingjobsetting extends Component {
this.state.latedeductiontwo=0;
this.setState({
completionefficiencyscore: e.target.checked,
work_efficiencys:e.target.checked,
latedeductiontwo: 0,
})
//均分比例
@ -1067,7 +1072,7 @@ class Trainingjobsetting extends Component {
// //占比分
changeTopicNametwo = (value) => {
// console.log("2e.target.value", value)
// console.log("TrainingjobsettingTrainingjobsetting", value)
if (value === "" || value === undefined) {
return
}
@ -1694,15 +1699,66 @@ class Trainingjobsetting extends Component {
if(this.state.allowreplenishment === false){
whethertopays=false;
}
this.setState({
flagPageEditsbox:true,
flagPageEdit: true,
whethertopay:whethertopays,
flagPageEditstwo:releasetime,
flagPageEditsthrees:deadline,
flagPageEditsfor:endtime,
unifiedsetting:this.state.unifiedsetting,
})
if(this.state.jobsettingsdata!==undefined){
}
try {
if(this.state.jobsettingsdata&& this.state.jobsettingsdata.data.homework_status[0]==="未发布"){
this.setState({
flagPageEditsbox:true,
flagPageEdit: true,
whethertopay:whethertopays,
flagPageEditstwo:releasetime,
flagPageEditsthrees:deadline,
flagPageEditsfor:endtime,
completionefficiencyscore:true,
work_efficiencys:true,
unifiedsetting:this.state.unifiedsetting,
latedeductiontwo:20,
});
}else {
this.setState({
flagPageEditsbox:true,
flagPageEdit: true,
whethertopay:whethertopays,
flagPageEditstwo:releasetime,
flagPageEditsthrees:deadline,
flagPageEditsfor:endtime,
unifiedsetting:this.state.unifiedsetting,
});
if(this.state.work_efficiencys===true){
this.setState({
completionefficiencyscore:true,
})
}else{
this.setState({
completionefficiencyscore:false,
})
}
}
}catch (e) {
this.setState({
flagPageEditsbox:true,
flagPageEdit: true,
whethertopay:whethertopays,
flagPageEditstwo:releasetime,
flagPageEditsthrees:deadline,
flagPageEditsfor:endtime,
unifiedsetting:this.state.unifiedsetting,
});
if(this.state.work_efficiencys===true){
this.setState({
completionefficiencyscore:true,
})
}else{
this.setState({
completionefficiencyscore:false,
})
}
}
if(this.state.proportion === "自定义分值"){
this.setState({
boolUnitetwoname:"自定义分值",
@ -1733,6 +1789,8 @@ class Trainingjobsetting extends Component {
hand__e_tip: "",
hand_flags: false,
handclass: undefined,
completionefficiencyscore:false,
latedeductiontwo:0,
unit_e_tip: "",
})
this.refs.targetElementTrainingjobsetting.scrollIntoView();
@ -1847,7 +1905,7 @@ class Trainingjobsetting extends Component {
const dataformat = 'YYYY-MM-DD HH:mm';
let {flagPageEdit,testscripttiptype,publish_timebool,end_timebool,late_timesbool,flagPageEdits,flagPageEditstwo,flagPageEditsbox,whethertopay,handclass,flagPageEditsthrees, flagPageEditsfor,rules,rulest,unifiedsetting,group_settings, course_group,unit_e_tip, borreds,borredss,unit_p_tip, end_time, late_time, score_open, publish_time, starttimetype, modalsType, modalsTopval, loadtype, modalSave, endtimetype, latetimetype, allowlate, latepenaltytype, jobsettingsdata, endOpen, mystyle, mystyles} = this.state;
let {flagPageEdit,testscripttiptype,publish_timebool,end_timebool,late_timesbool,work_efficiencys,flagPageEdits,flagPageEditstwo,flagPageEditsbox,whethertopay,handclass,flagPageEditsthrees, flagPageEditsfor,rules,rulest,unifiedsetting,group_settings, course_group,unit_e_tip, borreds,borredss,unit_p_tip, end_time, late_time, score_open, publish_time, starttimetype, modalsType, modalsTopval, loadtype, modalSave, endtimetype, latetimetype, allowlate, latepenaltytype, jobsettingsdata, endOpen, mystyle, mystyles} = this.state;
console.log(publish_timebool);
console.log(!flagPageEditstwo);
const radioStyle = {
@ -1875,6 +1933,8 @@ class Trainingjobsetting extends Component {
// }
// console.log(this.props.isAdmin())
// console.log(this.state.code_review===false)
// console.log("引入的分值");
// console.log(this.state.work_efficiencys);
return (
<div className=" clearfix " ref='targetElementTrainingjobsetting' style={{margin: "auto", minWidth:"1200px"}}>
{this.state.showmodel===true?<ShixunWorkModal
@ -2129,7 +2189,7 @@ class Trainingjobsetting extends Component {
<div className=" clearfix edu-back-white poll_list mt10" style={{marginLeft:" 40px"}}>
<Checkbox disabled={!flagPageEdit} className=" font-13 mt10"
onChange={this.onChangeeffectiveness}
checked={this.state.completionefficiencyscore} style={{"color":"#666666"}}>效率分<span
checked={this.state.work_efficiencys} style={{"color":"#666666"}}>效率分<span
className={"font-14 color-grey-c font-14 ml15"} style={{"text-align":"left"}}>(选中则学生最终成绩包含效率分)</span>
</Checkbox>
<div>
@ -2139,7 +2199,7 @@ class Trainingjobsetting extends Component {
</div>
<div className=" mt20" style={{marginLeft:"75px"}}>
<span className="c_grey mr10" style={{"color":"#999999"}}>分值</span>
<InputNumber min={0} disabled={!flagPageEdit} max={100} className="ml10 h40 mr10 color-grey-9"
<InputNumber min={0} disabled={!this.state.completionefficiencyscore} max={100} className="ml10 h40 mr10 color-grey-9"
style={{width: "100px","color":"#999999"}}
onChange={this.changeTopicNametwo}
value={this.state.latedeductiontwo}/>

@ -1064,8 +1064,7 @@ class ShixunHomework extends Component{
<div className="edu-back-white">
<p className="clearfix padding30 bor-bottom-greyE">
<p style={{height: '20px'}}>
{/*<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>
<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>
<li className="fr">
{datas===undefined?"":datas.homeworks && datas.homeworks.length>1?this.props.isAdminOrCreator()===true?datas&&datas.category_name===undefined||datas&&datas.category_name===null?
<span>

@ -39,20 +39,20 @@ class EcStudentList extends Component {
let major_id=this.props.match.params.major_id;
let year_id=this.props.match.params.year_id;
const url ='/ec_major_schools/'+major_id+'/academic_years/'+year_id+'/student_lists_data';
axios.get(url, {
withCredentials: true,
}).then((response) => {
if(response.status===200){
this.setState({
majorschoollist:response.data,
ismanager:response.data.ismanager,
})
}
})
.catch(function (error) {
console.log(error);
});
// const url ='/ec_major_schools/'+major_id+'/academic_years/'+year_id+'/student_lists_data';
// axios.get(url, {
// withCredentials: true,
// }).then((response) => {
// if(response.status===200){
// this.setState({
// majorschoollist:response.data,
// ismanager:response.data.ismanager,
// })
// }
// })
// .catch(function (error) {
// console.log(error);
// });
// let majorschoollist={
// ec_students: [{index: 1, student_name: "同意", student_id: "s20111458"},
// {index: 1, student_name: "同意", student_id: "s20111458"},

@ -130,7 +130,7 @@ class MemoDetailMDEditor extends Component {
}
}
render() {
const { match, history, memo, placeholder, className } = this.props
const { match, history, memo, placeholder, className, imageExpand } = this.props
const { isInited, errorMsg } = this.state
if (!memo) {
return <div></div>
@ -185,7 +185,8 @@ class MemoDetailMDEditor extends Component {
`
} */}
</style>
<div nhname={`new_message_${memo.id}`} className={`commentInput commentInputs ${className}`}
<div nhname={`new_message_${memo.id}`}
className={`commentInput commentInputs ${className} ${imageExpand && 'editormd-image-click-expand' }`}
style={{ padding: '30px',boxSizing:"border-box", display: isInited ? '' : 'none', paddingBottom: '40px' }} >
<div id="memo_comment_editorMd" className="editorMD" style={{ marginBottom: '0px'
, border: errorMsg ? '1px solid red' : '1px solid #ddd'}}>

@ -479,6 +479,8 @@ class MessagSub extends Component{
return '';
case "PublicCourseStart":
return window.open(`/courses/${item.container_id}/informs`);
case "SubjectStartCourse":
return window.open(`/paths/${item.container_id}`);
default :
return window.open("/")
}

@ -1,47 +1,56 @@
import React, { Component } from 'react';
import {getImageUrl} from 'educoder';
import { Spin, Icon , Modal} from 'antd';
class Modals extends Component {
constructor(props) {
super(props);
this.state = {
funmodalsType:false,
istype:false
}
}
render() {
const antIcons = <Icon type="loading" style={{ fontSize: 24 }} spin />
return(
<Modal
className={this.props.className}
keyboard={false}
title="提示"
visible={this.props.modalsType===undefined?false:this.props.modalsType}
closable={false}
footer={null}
destroyOnClose={true}
centered={true}
width="530px"
>
<Spin indicator={antIcons} spinning={this.props.antIcon===undefined?false:this.props.antIcon} >
<div className="task-popup-content">
<p className="task-popup-text-center font-16">{this.props.modalsTopval}</p>
<p className="task-popup-text-center font-16 mt5">{this.props.modalsBottomval}</p>
{this.props.loadtype===true?
<div className="clearfix edu-txt-center mt20">
<a className="task-btn task-btn-orange pop_close" onClick={this.props.modalSave}>知道啦</a>
</div>
:
<div className="clearfix mt30 edu-txt-center">
<a className="task-btn mr30" onClick={this.props.modalCancel}>取消</a>
<a className="task-btn task-btn-orange" onClick={this.props.modalSave}>{this.props.okText || '确定'}</a>
</div>
}
</div>
</Spin>
</Modal>
)
}
}
import React, { Component } from 'react';
import {getImageUrl} from 'educoder';
import { Spin, Icon , Modal} from 'antd';
class Modals extends Component {
constructor(props) {
super(props);
this.state = {
funmodalsType:false,
istype:false
}
}
render() {
const antIcons = <Icon type="loading" style={{ fontSize: 24 }} spin />
return(
<Modal
className={this.props.className}
keyboard={false}
title="提示"
visible={this.props.modalsType===undefined?false:this.props.modalsType}
closable={false}
footer={null}
destroyOnClose={true}
centered={true}
width="530px"
>
{this.props.modalsType===true?<style>
{
`
body{
overflow: hidden !important;
}
`
}
</style>:""}
<Spin indicator={antIcons} spinning={this.props.antIcon===undefined?false:this.props.antIcon} >
<div className="task-popup-content">
<p className="task-popup-text-center font-16">{this.props.modalsTopval}</p>
<p className="task-popup-text-center font-16 mt5">{this.props.modalsBottomval}</p>
{this.props.loadtype===true?
<div className="clearfix edu-txt-center mt20">
<a className="task-btn task-btn-orange pop_close" onClick={this.props.modalSave}>知道啦</a>
</div>
:
<div className="clearfix mt30 edu-txt-center">
<a className="task-btn mr30" onClick={this.props.modalCancel}>取消</a>
<a className="task-btn task-btn-orange" onClick={this.props.modalSave}>{this.props.okText || '确定'}</a>
</div>
}
</div>
</Spin>
</Modal>
)
}
}
export default Modals;

@ -144,11 +144,7 @@ class MainContent extends Component {
{/* readRepoTimeout 如果读取代码超时,显示重新加载按钮,重新拉取代码 */}
{
st === 0
?
readRepoTimeout === true ? <div className="readRepoFailed">
代码加载失败<a className="retry"
onClick={() => this.props.fetchRepositoryCode(this.props, null, null, true, true)}>重试</a>
</div> :
?
<React.Fragment>
<div style={{display: (codeLoading ? 'block' : 'none'), textAlign: 'center'}}>
<CircularProgress size={40} thickness={3}

@ -319,7 +319,8 @@ class MainContentContainer extends Component {
readingRepoTimes = readingRepoTimes + 1;
if(readingRepoTimes > 9) {
this.setState({
readRepoTimeout: true
readRepoTimeout: true,
codeLoading: false
})
readingRepoTimes = 0;
showSnackbar(`网络异常,请稍后重试。`);

@ -474,7 +474,9 @@ class CodeRepositoryView extends Component {
<span id="return_last_code">
</span>
{ challenge.pathIndex !== -1 && game.status === 2 && tabIndex === 0 && <a href="javascript:void(0);" className="iconButton" id="reset_success_game_code" onClick={showResetPassedCodeDialog}>
{ challenge.pathIndex !== -1 && game.status === 2 && tabIndex === 0 &&
this.props.readRepoTimeout !== true &&
<a href="javascript:void(0);" className="iconButton" id="reset_success_game_code" onClick={showResetPassedCodeDialog}>
<Tooltip title={ "加载上次通过的代码"} disableFocusListener={true}>
<i className="iconfont icon-fanhuishangcidaima font-20 "></i>
</Tooltip>
@ -482,7 +484,7 @@ class CodeRepositoryView extends Component {
}
{
challenge.pathIndex !== -1 && tabIndex === 0 &&
challenge.pathIndex !== -1 && tabIndex === 0 && this.props.readRepoTimeout !== true &&
<a href="javascript:void(0);" className="iconButton" id="reset_game_code" onClick={showResetCodeDialog}>
<Tooltip title={ "恢复初始代码"} disableFocusListener={true}>
<i className="iconfont icon-zhongzhi font-20 "></i>
@ -491,7 +493,7 @@ class CodeRepositoryView extends Component {
}
{
tabIndex === 0 &&
tabIndex === 0 && this.props.readRepoTimeout !== true &&
<a href="javascript:void(0);" className="iconButton" id="setting" onClick={() => showSettingDrawer(true)}>
<Tooltip title={ "设置"} disableFocusListener={true}>
<i className="iconfont icon-shezhi " style={{fontSize: '19px'}}></i>
@ -510,6 +512,7 @@ class CodeRepositoryView extends Component {
<div className="cl"></div>
</ul>
<div className="cl"></div>
<div id="codetab_con_1" style={{display: 'block', flex: 'auto'}} style={ tabIndex === 0 ? {display: 'block'} : {display: 'none'} }>
{/* 没必要显示这个,注释掉了 */}
{/* { !isEditablePath &&
@ -519,13 +522,20 @@ class CodeRepositoryView extends Component {
</div>
</Tooltip>
} */}
<div className="codemirrorBackground"
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> */}
<TPIMonaco {...this.props}></TPIMonaco>
{this.props.readRepoTimeout === true ? <div className="readRepoFailed">
代码加载失败<a className="retry"
onClick={() => this.props.fetchRepositoryCode(this.props, null, null, true, true)}>重试</a>
</div> :
<React.Fragment>
<div className="codemirrorBackground"
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> */}
<TPIMonaco {...this.props}></TPIMonaco>
</React.Fragment>
}
</div>
<div id="codetab_con_81" className="undis -relative"
style={ { color: '#fff', display: tabIndex === STABLE_SSH_TAB_ID ? 'block' : 'none', 'marginLeft': '2px'} }>

@ -336,7 +336,7 @@ class DetailCards extends Component{
showparagraphindex
}=this.state;
const antIcon = <Icon type="loading" style={{ fontSize: 24 }} spin />;
// console.log("zzz"+this.props.MenuItemsindextype)
return(
<div>
{AccountProfiletype===true?<AccountProfile
@ -495,7 +495,7 @@ class DetailCards extends Component{
:
<li className={showparagraph===false?"none":"fr status_li"}>
{
showparagraphkey===key&&showparagraphindex===index?<div>
showparagraphkey===key&&showparagraphindex===index?this.props.detailInfoList&&this.props.detailInfoList.allow_statistics===false&&this.props.MenuItemsindextype===2?"":<div>
<Link to={'/shixuns/'+line.identifier+'/challenges'} className="mr30 color-blue_4C shixun_detail pointer fl" target="_blank">查看详情</Link>
{line.shixun_status==="暂未公开"?"":<a onClick={()=>this.startgameid(line.identifier)} className="btn_auto user_bluebg_btn fl" id="shixun_operation" >开始实战</a>}
</div>:""

@ -17,7 +17,7 @@
box-sizing: border-box;
}
.userNavs{
line-height: 96px;
line-height: 75px;
background: #fff;
height:96px;
background:rgba(255,255,255,1);
@ -66,4 +66,16 @@
text-overflow: ellipsis;
white-space: nowrap;
height: 40px;
}
}
.mb100{
margin-bottom: 100px !important;
}
.task-btn-28BE6C{
background: #28BE6C !important;
color: #fff!important;
}
.mt43{
margin-top: 43px;
}

@ -5,10 +5,12 @@ import SendPanel from "./sendPanel.js";
import { getImageUrl } from 'educoder';
import axios from 'axios';
import Modals from '../../modals/Modals';
import AccountProfile from"../../user/AccountProfile";
import OpenCourse from './OpenCourse';
import Jointheclass from '../../modals/Jointheclass'
import Jointheclass from '../../modals/Jointheclass';
import './DetailTop.css';
const Search = Input.Search;
const RadioGroup = Radio.Group;
class DetailTop extends Component{
@ -26,7 +28,9 @@ class DetailTop extends Component{
MenuItemskey:1,
courseslist:[],
Pathcourseid:undefined,
OpenCourseTypes:false
OpenCourseTypes:false,
putappointmenttype:false,
getappointmenttype:false
}
}
componentDidMount(){
@ -48,33 +52,43 @@ class DetailTop extends Component{
})
}else{
this.props.courses.map((item,key)=>{
if(listtype===false){
keys=key+1
if(item.course_status.status===0) {
listtype=true
return (
courseslist.push(item)
)
}
}
})
let type=undefined;
this.props.courses.map((item,key)=>{
if(listtype===false){
let arr=[]
keys=key+1
if(item.course_status.status===2) {
type=key+1
arr.push(item)
}
courseslist=arr;
})
this.props.courses.map((item,key)=>{
let arr=[]
if(listtype===false){
keys=key+1
if(item.course_status.status===0) {
listtype=true
return (
courseslist.push(item)
)
// courseslist.push(item)
arr.push(item)
courseslist=arr
}
}
})
console.log(courseslist)
}
if(courseslist.length!=0){
this.props.getMenuItemsindex(keys,courseslist[0].course_status.status)
}
}
this.setState({
courseslist:courseslist,
MenuItemskey:keys,
@ -156,7 +170,8 @@ class DetailTop extends Component{
Modalstype:false,
Modalsbottomval:'',
loadtype:false,
deletepathtype:false
deletepathtype:false,
putappointmenttype:false
})
}
@ -219,6 +234,8 @@ class DetailTop extends Component{
)
}
})
this.props.getMenuItemsindex(keys,courseslist[0].course_status.status)
this.setState({
MenuItemskey:keys,
courseslist:courseslist,
@ -245,6 +262,32 @@ class DetailTop extends Component{
pathcousestypeid:typeid
})
}
putappointment=()=>{
if(this.props.checkIfLogin()===false){
this.props.showLoginDialog()
return
}
if(this.props.current_user&&this.props.current_user.profile_completed===false){
this.setState({
AccountProfiletype:true
})
return
}
this.setState({
Modalstype:true,
Modalstopval:"是否确认立即预约?",
Modalsbottomval:"",
cardsModalcancel:()=>this.cardsModalcancel(),
putappointmenttype:true,
loadtype:false
})
}
ysljoinmodalCancel=()=>{
this.setState({
yslJointhe:false
@ -267,9 +310,40 @@ class DetailTop extends Component{
OpenCourseTypes:false
})
}
getappointment=()=>{
let pathid=this.props.match.params.pathId;
let url=`/paths/${pathid}/appointment.json`
axios.post(url).then((response) => {
if (response.status === 200) {
if(response.data.status===0){
this.setState({
getappointmenttype:true
})
this.cardsModalcancel()
// this.props.getlistdatas()
this.props.showNotification(response.data.message)
}else{
this.props.showNotification(response.data.message)
}
}
}).catch((error) => {
console.log(error)
this.cardsModalcancel()
})
}
hideAccountProfile=()=>{
this.setState({
AccountProfiletype:false
})
}
render(){
let{detailInfoList}=this.props;
let{Modalstype,Modalstopval,cardsModalcancel,OpenCourseTypes,Modalsbottomval,cardsModalsavetype,loadtype}=this.state;
let{Modalstype,Modalstopval,cardsModalcancel,putappointmenttype,Modalsbottomval,cardsModalsavetype,loadtype,getappointmenttype,AccountProfiletype}=this.state;
const radioStyle = {
display: 'block',
height: '30px',
@ -292,15 +366,25 @@ class DetailTop extends Component{
let applypath=this.props.detailInfoList&&this.props.detailInfoList.participant_count!=undefined&&this.props.detailInfoList&&this.props.detailInfoList.allow_statistics===false;
let coursestypes=this.props.courses!=undefined&&this.props.courses.length===0;
let isadminallow_statistics=this.props.courses&&this.props.courses.length===0&&this.props.detailInfoList&&this.props.detailInfoList.allow_statistics===true;
return(
<div className={this.props.courses===undefined||this.props.courses.length===0?"subhead":"subhead mb70"}>
<div className={this.props.courses===undefined||this.props.courses.length===0?"subhead":applypath===false?"subhead mb70":this.state.MenuItemskey===this.props.courses.length?"subhead mb100":"subhead mb70"}>
{AccountProfiletype===true?<AccountProfile
hideAccountProfile={()=>this.hideAccountProfile()}
{...this.props}
{...this.state}
/>:""}
<Modals
modalsType={Modalstype}
modalsTopval={Modalstopval}
modalsBottomval={Modalsbottomval}
modalCancel={cardsModalcancel}
modalSave={cardsModalsavetype===true?this.reovkissuePaths:this.cardsModalsave}
modalSave={cardsModalsavetype===true?()=>this.reovkissuePaths():putappointmenttype===true?()=>this.getappointment():()=>this.cardsModalsave()}
loadtype={loadtype}
>
</Modals>
@ -309,7 +393,7 @@ class DetailTop extends Component{
{
detailInfoList &&
<div className={this.props.courses===undefined||this.props.courses.length===0?"subhead_content":"subhead_content pt100"}>
<div className={this.props.courses===undefined?"subhead_content":this.props.courses.length===0?"subhead_content pt40":"subhead_content pt100"}>
<div className="font-28 color-white clearfix">
{/*<Tooltip placement="bottom" title={detailInfoList.name.length>27?detailInfoList.name:""}>*/}
@ -428,9 +512,7 @@ class DetailTop extends Component{
</div>
{this.props.courses===undefined||this.props.courses.length===0?"":<div className="userNavs mt20">
<li className={"fl pd4020"}>
{this.props.courses===undefined||isadminallow_statistics===true?"":<div className="userNavs mt20" style={applypath===false?{}:this.state.MenuItemskey===this.props.courses.length?{height:'135px'}:{}}>
<style>
{
`
@ -453,32 +535,32 @@ class DetailTop extends Component{
`
}
</style>
{this.props.courses===undefined||this.props.courses.length===0?"":<li className={"fl pd4020 mt10"}>
{this.props.courses===undefined?"":this.state.courseslist.map((item,key)=>{
if(item.course_identity<4){
return(
<Tooltip placement="bottom" title={"编辑课堂"} key={key}>
<a href={`/courses/${item.course_id}/newgolds/settings`} target={"_blank"}>
<i className="iconfont icon-bianji1 newbianji1"></i>
</a>
</Tooltip>
)}})
}
{this.state.courseslist.map((item,key)=>{
if(item.course_identity<4){
return(
<Tooltip placement="bottom" title={"编辑课堂"} key={key}>
<a href={`/courses/${item.course_id}/newgolds/settings`} target={"_blank"}>
<i className="iconfont icon-bianji1 newbianji1"></i>
</a>
</Tooltip>
)}})
}
<Dropdown
overlay={menu}
onVisibleChange={this.onVisibleChanges}
>
<a className={"alist"}>
<span className={"color-orange"}> {this.state.MenuItemskey} </span>次开课 <Icon className="aIcons" type={!this.state.onVisibleChangestype?"down":"up"} />
</a>
</Dropdown>
</li>
<style>
{
`
<Dropdown
overlay={menu}
onVisibleChange={this.onVisibleChanges}
>
<a className={"alist"}>
<span className={"color-orange"}> {this.state.MenuItemskey} </span>次开课 <Icon className="aIcons" type={!this.state.onVisibleChangestype?"down":"up"} />
</a>
</Dropdown>
</li>}
<style>
{
`
.pdt28{
padding-top: 28px;
}
@ -494,12 +576,12 @@ class DetailTop extends Component{
font-size: 14px;
}
`
}
</style>
<li className={"ml20"}>
{this.state.courseslist.map((item,key)=>{
return(
<div className={"ant-breadcrumb pdt28"} key={key}>
}
</style>
{this.props.courses===undefined||this.props.courses.length===0?"":<li className={"ml20"}>
{this.state.courseslist.map((item,key)=>{
return(
<div className={"ant-breadcrumb pdt28"} key={key}>
<span>
<div className="ant-breadcrumb-link fl mr23">
<div className={"pathtime"}>
@ -512,7 +594,7 @@ class DetailTop extends Component{
<div className="fl solidright"></div>
</span>
<span>
<span>
<div className="ant-breadcrumb-link fl mr23 ml23">
<div className={"pathtime"}>
结课时间
@ -524,7 +606,7 @@ class DetailTop extends Component{
<div className="fl solidright"></div>
</span>
<span>
<span>
<div className="ant-breadcrumb-link fl mr23 ml23">
<div className={"pathtime"}>
报名人数
@ -534,17 +616,15 @@ class DetailTop extends Component{
</div>
</div>
</span>
</div>
)
})
}
</li>
</div>
)
})
}
<li className={"fr mr25"}>
<style>
{
`
</li>}
<style>
{
`
.user-colorgrey-9b{color:#9B9B9B}
.user-colorgrey-green{color:#7ED321}
.background191{
@ -565,40 +645,110 @@ class DetailTop extends Component{
.courseslistsa{
color:#fff !important;
}
.pathbtensbox{
width: 215px !important;
height: 46px !important;
background: rgba(76,172,255,1);
border-radius: 4px;
line-height: 46px !important;
}
.lineHeight1{
line-height: 1px;
}
.font153{
font-size: 14px;
font-weight: 400;
color: rgba(153,153,153,1);
margin-left: 30px;
}
.absolutewidth{
position: absolute;
top: 19px;
right: 71px;
}
.relativewidth{
position: relative;
width: 100%;
}
.padding040{
padding: 0 43px;
}
.mt26{
margin-top:26px;
}
.mt10block{
margin-top: 10px;
display: inline-block;
}
`
}
</style>
{this.state.courseslist.map((item,key)=>{
}
</style>
{this.props.courses===undefined||this.props.courses.length===0?"":<li className={"fr padding040"}>
{/*
height: 158px;
}*/}
{this.state.courseslist.map((item,key)=>{
return(
<div key={key}>
{applypath===false?"":this.state.MenuItemskey===this.props.courses.length||coursestypes===true?
this.props.detailInfoList&&this.props.detailInfoList.has_participate===false?
getappointmenttype===true?<span className={coursestypes===true?"fr user_default_btn background191 font-18 pathbtensbox mt5":"fr user_default_btn background191 font-18 pathbtensbox mt26"}>预约报名成功</span>:<a className={coursestypes===true?"fr user_default_btn task-btn-28BE6C font-18 pathbtensbox mt5":"fr user_default_btn task-btn-28BE6C font-18 pathbtensbox mt26"} onClick={()=>this.putappointment()}></a>:
<span className={coursestypes===true?"fr user_default_btn background191 font-18 pathbtensbox mt5":"fr user_default_btn background191 font-18 pathbtensbox mt26"}>预约报名成功</span>:""}
{/*{item.course_status.status===0?<div className="mr51 shixun_detail pointer fl user-colorgrey-green pathdefault">即将开课</div>:""}*/}
{item.course_status.status===1?<div className="mr51 shixun_detail pointer fl color-orange pathdefault mt10">{item.course_status.time}</div>:""}
{item.course_status.status===2&&item.course_identity<6?<div className="mr20 shixun_detail pointer fl user-colorgrey-9b pathdefault mt10">已结束</div>:""}
{/*<div className="fr user_default_btn background191 font-18 mt28 pathbtens pathdefault">已结束</div>*/}
{item.course_status.status===0?
item.course_identity<5?<a className="fr user_default_btn task-btn-orange font-18 mt28 pathbtens courseslistsa mr20" href={item.first_category_url} target="_blank">
进入课堂
</a>:item.course_identity<6?<div className="fr user_default_btn background191 font-18 mt28 pathbtens pathdefault mr20"></div>
:<a className="fr user_default_btn task-btn-orange font-18 mt28 pathbtens mr20" onClick={()=>this.JoinnowCourse(item.course_id)}>立即报名</a>:""}
{item.course_status.status===1?
item.course_identity<5?<a className="courseslistsa fr user_default_btn task-btn-orange font-18 mt28 pathbtens mr20" href={item.first_category_url} target="_blank">
进入课堂
</a>:item.course_identity<6?<a className="courseslistsa fr user_default_btn task-btn-orange font-18 mt28 pathbtens mr20" href={item.first_category_url} target="_blank">
立即学习
</a>:<a className="fr user_default_btn task-btn-orange font-18 mt28 pathbtens mr20" onClick={()=>this.JoinnowCourse(item.course_id,item.course_status.status)}></a>:""}
{item.course_status.status===2?
item.course_identity<6?<a className="fr user_default_btn task-btn-orange font-18 mt28 pathbtens courseslistsa mr20" href={item.first_category_url} target="_blank">
进入课堂
</a>:<div className="mr20 shixun_detail pointer fl user-colorgrey-9b pathdefault mt10"></div>:""}
</div>
)})}
</li>}
{applypath===false?"":this.state.MenuItemskey===this.props.courses.length?<div className={"clear"}></div>:""}
{applypath===false?"":this.props.courses.length===0?"":this.state.MenuItemskey===this.props.courses.length||coursestypes===true?<span className={coursestypes===true?"fr lineHeight1 relativewidth mt43":"fl lineHeight1 relativewidth"}>
<span className={"fr mr30"}>当前预约报名人数<span className={"color-red mr5"}>{getappointmenttype===true?this.props.detailInfoList&&this.props.detailInfoList.participant_count+1:this.props.detailInfoList&&this.props.detailInfoList.participant_count}</span></span>
<span className={"font153 fr mr12"}>当预约报名人数达到 {this.props.detailInfoList&&this.props.detailInfoList.student_count} 人时即将开课</span>
{/*{this.props.detailInfoList&&this.props.detailInfoList.has_participate===false?*/}
{/*getappointmenttype===true?<span className={coursestypes===true?"fr user_default_btn background191 font-18 pathbtensbox absolutewidth mt5":"fr user_default_btn background191 font-18 pathbtensbox absolutewidth"}>预约报名成功</span>:<a className={coursestypes===true?"fr user_default_btn task-btn-28BE6C font-18 pathbtensbox absolutewidth mt5":"fr user_default_btn task-btn-28BE6C font-18 pathbtensbox absolutewidth"} onClick={()=>this.putappointment()}>期待开课并预约报名</a>:*/}
{/*<span className={coursestypes===true?"fr user_default_btn background191 font-18 pathbtensbox absolutewidth mt5":"fr user_default_btn background191 font-18 pathbtensbox absolutewidth"}>预约报名成功</span>}*/}
</span>
:""}
{applypath===true&&this.props.courses.length===0?this.state.MenuItemskey===this.props.courses.length||coursestypes===true?<span className={coursestypes===true?"fl ml20 lineHeight0 relativewidth":"fl ml20 lineHeight0 relativewidth"}>
<span className={"mt10block"}>当前预约报名人数<span className={"color-red mr5"}>{getappointmenttype===true?this.props.detailInfoList&&this.props.detailInfoList.participant_count+1:this.props.detailInfoList&&this.props.detailInfoList.participant_count}</span></span>
<span className={"font153 mt10block"}>当预约报名人数达到 {this.props.detailInfoList&&this.props.detailInfoList.student_count} 人时即将开课</span>
{this.props.detailInfoList&&this.props.detailInfoList.has_participate===false?
getappointmenttype===true?<span className={coursestypes===true?"fr user_default_btn background191 font-18 pathbtensbox absolutewidth mt5":"fr user_default_btn background191 font-18 pathbtensbox absolutewidth"}>预约报名成功</span>:<a className={coursestypes===true?"fr user_default_btn task-btn-28BE6C font-18 pathbtensbox absolutewidth mt5":"fr user_default_btn task-btn-28BE6C font-18 pathbtensbox absolutewidth"} onClick={()=>this.putappointment()}></a>:
<span className={coursestypes===true?"fr user_default_btn background191 font-18 pathbtensbox absolutewidth mt5":"fr user_default_btn background191 font-18 pathbtensbox absolutewidth"}>预约报名成功</span>}
</span>:"":""}
return(
<div key={key}>
{item.course_status.status===0?<div className="mr51 shixun_detail pointer fl user-colorgrey-green pathdefault">即将开课</div>:""}
{item.course_status.status===1?<div className="mr51 shixun_detail pointer fl color-orange pathdefault">{item.course_status.time}</div>:""}
{item.course_status.status===2&&item.course_identity<6?<div className="mr51 shixun_detail pointer fl user-colorgrey-9b pathdefault">已结束</div>:""}
{item.course_status.status===0?
item.course_identity<5?<a className="fr user_default_btn task-btn-orange font-18 mt28 pathbtens courseslistsa" href={item.first_category_url} target="_blank">
进入课堂
</a>:item.course_identity<6?<div className="fr user_default_btn background191 font-18 mt28 pathbtens pathdefault"></div>
:<a className="fr user_default_btn task-btn-orange font-18 mt28 pathbtens" onClick={()=>this.JoinnowCourse(item.course_id)}>立即报名</a>:""}
{item.course_status.status===1?
item.course_identity<5?<a className="courseslistsa fr user_default_btn task-btn-orange font-18 mt28 pathbtens" href={item.first_category_url} target="_blank">
进入课堂
</a>:item.course_identity<6?<a className="courseslistsa fr user_default_btn task-btn-orange font-18 mt28 pathbtens" href={item.first_category_url} target="_blank">
立即学习
</a>:<a className="fr user_default_btn task-btn-orange font-18 mt28 pathbtens" onClick={()=>this.JoinnowCourse(item.course_id,item.course_status.status)}></a>:""}
{item.course_status.status===2?
item.course_identity<6?<a className="fr user_default_btn task-btn-orange font-18 mt28 pathbtens courseslistsa" href={item.first_category_url} target="_blank">
进入课堂
</a>:<div className="fr user_default_btn background191 font-18 mt28 pathbtens pathdefault"></div>:""}
</div>
)})}
</li>
</div>}
</div>

@ -85,6 +85,8 @@ class PathDetailIndex extends Component{
items: getItems(10),
pathtopskey:1,
dataquerys:{},
MenuItemsindex:1,
MenuItemsindextype:0
}
this.onDragEnd = this.onDragEnd.bind(this);
@ -147,7 +149,10 @@ class PathDetailIndex extends Component{
}
componentDidMount(){
this.getlistdatas()
}
getlistdatas=()=>{
const query = this.props.location.search;
// const type = query.split('?chinaoocTimestamp=');
// console.log("Eduinforms12345");
@ -254,7 +259,13 @@ class PathDetailIndex extends Component{
console.log(error);
})
};
getMenuItemsindex=(key,status)=>{
this.setState({
MenuItemsindex:key,
MenuItemsindextype:status
})
}
getdatasindex=(key)=>{
// yslwebobject 后端需要的接口
let pathid=this.props.match.params.pathId;
@ -460,9 +471,13 @@ class PathDetailIndex extends Component{
members,
tags,
courses,
MenuItemsindex,
MenuItemsindextype
} = this.state
// console.log(MenuItemsindex)
// console.log(MenuItemsindextype===2&&detailInfoList&&detailInfoList.allow_statistics===false)
return(
<div className="newContainer">
<style>
@ -487,7 +502,7 @@ class PathDetailIndex extends Component{
>
</Modals>
<div className="newMain clearfix">
<DetailTop {...this.state} {...this.props} getdatasindex={(key)=>this.getdatasindex(key)}></DetailTop>
<DetailTop {...this.state} {...this.props} getdatasindex={(key)=>this.getdatasindex(key)} getMenuItemsindex={(key,status)=>this.getMenuItemsindex(key,status)} getlistdatas={()=>this.getlistdatas()}></DetailTop>
<div className="educontent clearfix mb80">
<div className="with65 fl">
<div className="produce-content mb10">

@ -865,7 +865,7 @@ submittojoinclass=(value)=>{
<li><Link to={`/users/${this.props.current_user===undefined?"":this.props.current_user.login}/shixuns`}>我的实训项目</Link></li>
<li><Link to={`/users/${this.props.current_user===undefined?"":this.props.current_user.login}/paths`}>我的实践课程</Link></li>
<li><Link to={`/users/${this.props.current_user===undefined?"":this.props.current_user.login}/projects`}>我的开发项目</Link></li>
<li><Link to={`/users/${this.props.current_user===undefined?"":this.props.current_user.login}/package`}>我的众包</Link></li>
{/*<li><Link to={`/users/${this.props.current_user===undefined?"":this.props.current_user.login}/package`}>我的众包</Link></li>*/}
<li style={{display: this.props.Headertop === undefined ? 'none' : this.props.Headertop.customer_management_url===null || this.props.Headertop.customer_management_url===""? 'none' : 'block'}}>
<a href={this.props.Headertop === undefined ? '' : this.props.Headertop.customer_management_url}>客户管理</a>
</li>

@ -317,14 +317,14 @@ export default class TPMMDEditor extends Component {
let {
showError
} = this.state;
let { mdID, className, noStorage } = this.props;
let { mdID, className, noStorage, imageExpand } = this.props;
let _style = {}
if (showError) {
_style.border = '1px solid red'
}
return (
<React.Fragment>
<div className={`df ${className}`} >
<div className={`df ${className} ${imageExpand && 'editormd-image-click-expand' }`} >
{/* padding10-20 */}
<div className="edu-back-greyf5 radius4" id={`mdEditor_${mdID}`} style={{..._style}}>
<textarea style={{display: 'none'}} id={`mdEditors_${mdID}`} name="content"></textarea>

@ -50,10 +50,10 @@ class InfosBanner extends Component{
</p>
<p className="mt15">
<Tooltip placement='bottom' title={ data && data.professional_certification ?"已职业认证":"未职业认证"}>
<i className={ data && data.professional_certification ? "iconfont icon-shenfenzhenghaomaguizheng font-18 user-colorgrey-green mr20 ml2":"iconfont icon-shenfenzhenghaomaguizheng font-18 user-colorgrey-B8 mr20 ml2"}></i>
<i className={ data && data.professional_certification ? "iconfont icon-shenfenzhenghaomaguizheng font-18 user-colorgrey-blue mr20 ml2":"iconfont icon-shenfenzhenghaomaguizheng font-18 user-colorgrey-B8 mr20 ml2"}></i>
</Tooltip>
<Tooltip placement='bottom' title={ data && data.authentication ?"已实名认证":"未实名认证"}>
<i className={ data && data.authentication ? "iconfont icon-renzhengshangjia font-18 user-colorgrey-green":"iconfont icon-renzhengshangjia font-18 user-colorgrey-B8"}></i>
<i className={ data && data.authentication ? "iconfont icon-renzhengshangjia font-18 user-colorgrey-blue":"iconfont icon-renzhengshangjia font-18 user-colorgrey-B8"}></i>
</Tooltip>
</p>
</div>
@ -111,11 +111,11 @@ class InfosBanner extends Component{
onClick={() => this.setState({moduleName: 'projects'})}
to={`/users/${username}/projects`}>开发项目</Link>
</li>
<li className={`${moduleName == 'package' ? 'active' : '' }`}>
<Link
onClick={() => this.setState({moduleName: 'package'})}
to={`/users/${username}/package`}>众包</Link>
</li>
{/*<li className={`${moduleName == 'package' ? 'active' : '' }`}>*/}
{/* <Link*/}
{/* onClick={() => this.setState({moduleName: 'package'})}*/}
{/* to={`/users/${username}/package`}>众包</Link>*/}
{/*</li>*/}
{((is_current && current_user && current_user.is_teacher ) || current_user && current_user.admin)
&& <li className={`${moduleName == 'videos' ? 'active' : '' }`}>
<Link

@ -168,6 +168,7 @@
}
.user-colorgrey-B8{color:#B8B8B8}
.user-colorgrey-green{color:#7ED321}
.user-colorgrey-blue{color:#98EBFF}
.user_yellow_btn {
color: #fff!important;
background-color: #FF8E02;

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe CourseDeleteStudentNotifyJob, type: :job do
pending "add some examples to (or delete) #{__FILE__}"
end

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe CreateSubjectCourseStudentJob, type: :job do
pending "add some examples to (or delete) #{__FILE__}"
end

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe ResubmitStudentWorkNotifyJob, type: :job do
pending "add some examples to (or delete) #{__FILE__}"
end
Loading…
Cancel
Save