Merge branch 'dev_aliyun' of https://bdgit.educoder.net/Hjqreturn/educoder into dev_aliyun

dev_forum
jingquan huang 5 years ago
commit 9091740f2a

@ -39,6 +39,8 @@ gem 'pdfkit'
gem 'wkhtmltopdf-binary' gem 'wkhtmltopdf-binary'
#gem 'iconv' #gem 'iconv'
# markdown 转html
gem 'redcarpet', '~> 3.4'
gem 'rqrcode', '~> 0.10.1' gem 'rqrcode', '~> 0.10.1'
gem 'rqrcode_png' gem 'rqrcode_png'

@ -193,6 +193,7 @@ GEM
rb-inotify (0.9.10) rb-inotify (0.9.10)
ffi (>= 0.5.0, < 2) ffi (>= 0.5.0, < 2)
rchardet (1.8.0) rchardet (1.8.0)
redcarpet (3.4.0)
redis (4.1.0) redis (4.1.0)
redis-actionpack (5.0.2) redis-actionpack (5.0.2)
actionpack (>= 4.0, < 6) actionpack (>= 4.0, < 6)
@ -328,6 +329,7 @@ DEPENDENCIES
rails (~> 5.2.0) rails (~> 5.2.0)
rails-i18n (~> 5.1) rails-i18n (~> 5.1)
rchardet (~> 1.8) rchardet (~> 1.8)
redcarpet (~> 3.4)
redis-rails redis-rails
roo-xls roo-xls
rqrcode (~> 0.10.1) rqrcode (~> 0.10.1)

@ -427,6 +427,24 @@ class ApplicationController < ActionController::Base
container.to_json container.to_json
end end
# 实训中间层pod配置
def shixun_container_limit shixun
container = []
shixun.shixun_service_configs.each do |config|
mirror = config.mirror_repository
if mirror.name.present?
container << {:image => mirror.name,
:cpuLimit => config.cpu_limit,
:cpuRequest => config.lower_cpu_limit,
:memoryLimit => "#{config.memory_limit}M",
:memoryRequest => "#{config.request_limit}M",
:resourceLimit => "#{config.resource_limit}K",
:type => mirror.try(:main_type) == "1" ? "main" : "sub"}
end
end
container.to_json
end
# 毕设任务列表的赛选 # 毕设任务列表的赛选
def course_work(task, **option) def course_work(task, **option)
logger.info("#############{option}") logger.info("#############{option}")

@ -153,7 +153,7 @@ class ChallengesController < ApplicationController
@challenges = Challenge.fields_for_list.where(shixun_id: @shixun.id) @challenges = Challenge.fields_for_list.where(shixun_id: @shixun.id)
@editable = current_user.manager_of_shixun?(@shixun) && @shixun.status == 0 @editable = @shixun.status == 0 # before_action有判断权限如果没发布则肯定是管理人员
@user = current_user @user = current_user
end end
@ -289,7 +289,7 @@ class ChallengesController < ApplicationController
def challenge_params def challenge_params
params.require(:challenge).permit(:subject, :task_pass, :difficulty, :score, :st, :modify_time, :test_set_average, params.require(:challenge).permit(:subject, :task_pass, :difficulty, :score, :st, :modify_time, :test_set_average,
:path, :exec_path, :show_type, :original_picture_path, :test_set_score, :path, :exec_path, :show_type, :original_picture_path, :test_set_score,
:expect_picture_path, :picture_path, :web_route, :answer) :expect_picture_path, :picture_path, :web_route, :answer, :exec_time)
end end
def chooce_params def chooce_params

@ -33,7 +33,7 @@ class GamesController < ApplicationController
is_teacher = @user.is_teacher? is_teacher = @user.is_teacher?
# 实训超时设置 # 实训超时设置
time_limit = @shixun.exec_time time_limit = game_challenge.exec_time
# 上一关、下一关 # 上一关、下一关
prev_game = @game.prev_of_current_game(@shixun.id, @game.myshixun_id, game_challenge.position) prev_game = @game.prev_of_current_game(@shixun.id, @game.myshixun_id, game_challenge.position)
@ -66,7 +66,7 @@ class GamesController < ApplicationController
shixun_tomcat = edu_setting('cloud_bridge') shixun_tomcat = edu_setting('cloud_bridge')
service_host = edu_setting('vnc_url') service_host = edu_setting('vnc_url')
uri = "#{shixun_tomcat}/bridge/vnc/getvnc" uri = "#{shixun_tomcat}/bridge/vnc/getvnc"
params = {tpiID: @myshixun.id, :containers => "#{Base64.urlsafe_encode64(container_limit(@shixun.mirror_repositories))}"} params = {tpiID: @myshixun.id, :containers => "#{Base64.urlsafe_encode64(shixun_container_limit(@shixun))}"}
res = uri_post uri, params res = uri_post uri, params
if res && res['code'].to_i != 0 if res && res['code'].to_i != 0
raise("实训云平台繁忙繁忙等级99") raise("实训云平台繁忙繁忙等级99")
@ -547,7 +547,7 @@ class GamesController < ApplicationController
br_params = {:tpiID => "#{@myshixun.id}", :tpiGitURL => "#{gitUrl}", :buildID => "#{@game.id}", br_params = {:tpiID => "#{@myshixun.id}", :tpiGitURL => "#{gitUrl}", :buildID => "#{@game.id}",
:instanceChallenge => "#{step}", :testCases => "#{testCases}", :resubmit => "#{resubmit}", :instanceChallenge => "#{step}", :testCases => "#{testCases}", :resubmit => "#{resubmit}",
:times => params[:first].to_i, :podType => @shixun.webssh, :content_modified => content_modified, :times => params[:first].to_i, :podType => @shixun.webssh, :content_modified => content_modified,
:containers => "#{Base64.urlsafe_encode64(container_limit(@shixun.mirror_repositories))}", :containers => "#{Base64.urlsafe_encode64(shixun_container_limit(@shixun))}",
:persistenceName => @shixun.identifier, :tpmScript => "#{tpmScript}", :persistenceName => @shixun.identifier, :tpmScript => "#{tpmScript}",
:timeLimit => "#{@shixun.exec_time}", :isPublished => (@shixun.status < 2 ? 0 : 1) } :timeLimit => "#{@shixun.exec_time}", :isPublished => (@shixun.status < 2 ? 0 : 1) }

@ -186,6 +186,7 @@ class HomeworkCommonsController < ApplicationController
@work_count = @student_works.size @work_count = @student_works.size
@work_excel = @student_works @work_excel = @student_works
@students = @course.students
# 分页参数 # 分页参数
page = params[:page] || 1 page = params[:page] || 1
@ -236,94 +237,51 @@ class HomeworkCommonsController < ApplicationController
end end
def update_score def update_score
student_works = @homework.student_works begin
myshixuns = Myshixun.where(shixun_id: @homework.homework_commons_shixun&.shixun_id, user_id: @course.students.pluck(:user_id)) if @homework.unified_setting
myshixuns = Myshixun.where(shixun_id: @homework.homework_commons_shixun&.shixun_id). student_works = @homework.student_works
joins("join course_members on myshixuns.user_id=course_members.user_id").where(course_members: {course_id: @course.id, role: 4}).includes(:games) user_ids = @course.students.pluck(:user_id)
myshixuns.find_each(batch_size: 100) do |myshixun| else
work = student_works.select{|work| work.user_id == myshixun.user_id}.first user_ids = @course.students.where(course_group_id: @homework.published_settings.pluck(:course_group_id)).pluck(:user_id)
setting_time = @homework.homework_group_setting work.user_id student_works = @homework.student_works.where(user_id: user_ids)
end
if setting_time.end_time.present? && (setting_time.end_time > Time.now || (@homework.allow_late && @homework.late_time && @homework.late_time > Time.now))
#logger.info("#############setting_time: #{setting_time.end_time}")
user_total_score = 0
pass_consume_time = 0
final_score = 0
homework.homework_challenge_settings.each do |setting|
game = myshixun.games.where(:challenge_id => setting.challenge_id, :status => 2).first
unless game.nil?
pass_consume_time += (game.cost_time / 60.0).to_f
user_total_score += game.final_score.to_i < 0 ? 0 : game.challenge.score.to_i
adjust_score = work.challenge_work_scores.where(:challenge_id => setting.challenge_id).last
final_score += adjust_score.present? ? adjust_score.score : (homework.homework_detail_manual.answer_open_evaluation ? setting.score : (game.final_score > 0 ? game.real_score(setting.score) : 0))
end
end
if work.work_status == 0
is_complete = myshixun.is_complete? && (myshixun.done_time < setting_time.end_time)
work.work_status = setting_time.end_time > Time.now ? 1 : (is_complete ? 1 : 2)
work.late_penalty = setting_time.end_time > Time.now ? 0 : (is_complete ? 0 : homework.late_penalty)
work.commit_time = myshixun.created_at > setting_time.publish_time ? setting_time.publish_time : myshixun.created_at
work.myshixun_id = myshixun.id
end
games = myshixun.games.where(:challenge_id => homework.homework_challenge_settings.map(&:challenge_id))
myshixun_endtime = games.select{|game| game.status == 2}.size == games.size ? games.map(&:end_time).max : nil
if myshixun_endtime.present?
min_efficiency_changed = min_efficiency_changed.present? ? min_efficiency_changed : false
work.compelete_status = 1
work.cost_time = myshixun_endtime.to_i - setting_time.publish_time.to_i
efficiency = (pass_consume_time == 0 ? 0 : Math.log((user_total_score / pass_consume_time.to_f) + 1.0))
work.efficiency = format("%.2f", efficiency)
# 如果作业的最大效率值有变更则更新所有作品的效率分 myshixuns = Myshixun.where(shixun_id: params[:shixun_id], user_id: user_ids).
if homework.work_efficiency && homework.max_efficiency < work.efficiency includes(:games).where(games: {challenge_id: @homework.homework_challenge_settings.pluck(:challenge_id)})
homework.update_column("max_efficiency", work.efficiency) challenge_settings = @homework.homework_challenge_settings
end myshixuns.find_each(batch_size: 100) do |myshixun|
work = student_works.select{|work| work.user_id == myshixun.user_id}.first
if work && myshixun && (work.update_time.nil? || work.update_time < myshixun.updated_at)
games = myshixun.games.where(challenge_id: challenge_settings.pluck(:challenge_id))
HomeworksService.new.update_myshixun_work_score work, myshixun, games, @homework, challenge_settings
end end
work.update_time = Time.now
work.final_score = final_score
score = work.final_score + work.eff_score - work.late_penalty
work.work_score = format("%.2f",(score < 0 ? 0 : score).to_f) unless work.ultimate_score
#logger.info("#############work_score: #{score}")
work.save!
end end
end @homework.update_attribute('calculation_time', Time.now)
@homework.student_works.each do || normal_status("更新成功")
rescue Exception => e
uid_logger(e.message)
tip_exception(e.message)
raise ActiveRecord::Rollback
end end
end end
def update_student_score def update_student_score
work = @homework.students_works.find_by(user_id: current_user.id) work = @homework.student_works.find_by(user_id: current_user.id)
myshixun = Myshixun.find_by(shixun_id: params[:shixun_id], user_id: current_user.id) myshixun = Myshixun.find_by(shixun_id: params[:shixun_id], user_id: current_user.id)
if work && myshixun ActiveRecord::Base.transaction do
# 判断作品是否关联过myshixun begin
if work.myshixun_id.nil? if work && myshixun && (work.update_time.nil? || work.update_time < myshixun.updated_at)
work.myshixun_id = myshixun.id challenge_settings = @homework.homework_challenge_settings
work.update_time = myshixun.updated_at games = myshixun.games.where(challenge_id: challenge_settings.pluck(:challenge_id))
setting_time = @homework.homework_group_setting myshixun.user_id HomeworksService.new.update_myshixun_work_score work, myshixun, games, @homework, challenge_settings
games = myshixun.games.where(:challenge_id => @homework.homework_challenge_settings.pluck(:challenge_id)) normal_status("更新成功")
myshixun_endtime = games.select{|game| game.status == 2}.size == games.size ? games.map(&:end_time).max : nil else
compelete_status = 0 normal_status("已是最新成绩")
if myshixun_endtime.present? && myshixun_endtime < setting_time.end_time
if myshixun_endtime < setting_time.publish_time
compelete_status = 2
else
compelete_status = 1
end
end
games.each do |game|
unless game.nil?
pass_consume_time += (game.cost_time / 60.0).to_f
user_total_score += game.final_score.to_i < 0 ? 0 : game.challenge.score.to_i
adjust_score = work.challenge_work_scores.where(:challenge_id => setting.challenge_id).last
final_score += adjust_score.present? ? adjust_score.score : (homework.homework_detail_manual.answer_open_evaluation ? setting.score : (game.final_score > 0 ? game.real_score(setting.score) : 0))
end
end end
rescue Exception => e
uid_logger(e.message)
tip_exception(e.message)
raise ActiveRecord::Rollback
end end
end end
end end
@ -1036,7 +994,7 @@ class HomeworkCommonsController < ApplicationController
if homework.course_acts.size == 0 if homework.course_acts.size == 0
homework.course_acts << CourseActivity.new(user_id: homework.user_id, course_id: homework.course_id) homework.course_acts << CourseActivity.new(user_id: homework.user_id, course_id: homework.course_id)
end end
# 发消息
HomeworkCommonPushNotifyJob.perform_later(homework.id, tiding_group_ids) HomeworkCommonPushNotifyJob.perform_later(homework.id, tiding_group_ids)
else else
create_homework_group_settings(homework) create_homework_group_settings(homework)
@ -1057,6 +1015,7 @@ class HomeworkCommonsController < ApplicationController
homework.save! homework.save!
# 更新学生状态及成绩
HomeworkPublishUpdateWorkStatusJob.perform_later(tiding_group_ids, homework.id) HomeworkPublishUpdateWorkStatusJob.perform_later(tiding_group_ids, homework.id)
end end
normal_status(0, "发布成功") normal_status(0, "发布成功")

@ -128,7 +128,7 @@ class MessagesController < ApplicationController
def destroy def destroy
begin begin
return normal_status(403, "您没有权限进行该操作") unless @message.author == current_user || current_user.teacher_of_course?(@message.board.course) return normal_status(403, "您没有权限进行该操作") if current_user.course_identity(@message.board.course) >= 5 || @message.author != current_user
@message.destroy! @message.destroy!
rescue Exception => e rescue Exception => e
uid_logger_error(e.message) uid_logger_error(e.message)

@ -217,7 +217,7 @@ class MyshixunsController < ApplicationController
shixun_tomcat = edu_setting('tomcat_webssh') shixun_tomcat = edu_setting('tomcat_webssh')
uri = "#{shixun_tomcat}/bridge/webssh/getConnectInfo" uri = "#{shixun_tomcat}/bridge/webssh/getConnectInfo"
params = {tpiID:@myshixun.id, podType:@myshixun.shixun.try(:webssh), params = {tpiID:@myshixun.id, podType:@myshixun.shixun.try(:webssh),
containers:(Base64.urlsafe_encode64(container_limit @myshixun.shixun.mirror_repositories))} containers:(Base64.urlsafe_encode64(shixun_container_limit @myshixun.shixun))}
res = uri_post uri, params res = uri_post uri, params
if res && res['code'].to_i != 0 if res && res['code'].to_i != 0
tip_exception("实训云平台繁忙繁忙等级92") tip_exception("实训云平台繁忙繁忙等级92")

@ -179,6 +179,16 @@ class ShixunsController < ApplicationController
ShixunTagRepertoire.create!(:tag_repertoire_id => str.tag_repertoire_id, :shixun_id => @new_shixun.id) ShixunTagRepertoire.create!(:tag_repertoire_id => str.tag_repertoire_id, :shixun_id => @new_shixun.id)
end end
# 同步配置
@shixun.shixun_service_configs.each do |config|
ShixunServiceConfig.create!(:shixun_id => @new_shixun.id,
:cpu_limit => config.cpu_limit,
:lower_cpu_limit => config.lower_cpu_limit,
:memory_limit => config.memory_limit,
:request_limit => config.request_limit,
:mirror_repository_id => config.mirror_repository_id)
end
# fork版本库 # fork版本库
logger.info("###########fork_repo_path: ######{@repo_path}") logger.info("###########fork_repo_path: ######{@repo_path}")
project_fork(@new_shixun, @repo_path, current_user.login) project_fork(@new_shixun, @repo_path, current_user.login)
@ -315,9 +325,13 @@ class ShixunsController < ApplicationController
# 镜像-实训关联表 # 镜像-实训关联表
ShixunMirrorRepository.create!(:shixun_id => @shixun.id, :mirror_repository_id => main_type.to_i) if main_type.present? ShixunMirrorRepository.create!(:shixun_id => @shixun.id, :mirror_repository_id => main_type.to_i) if main_type.present?
# 实训主镜像服务配置
ShixunServiceConfig.create!(:shixun_id => @shixun.id, :mirror_repository_id => main_type.to_i)
if sub_type.present? if sub_type.present?
sub_type.each do |mirror| sub_type.each do |mirror|
ShixunMirrorRepository.create!(:shixun_id => @shixun.id, :mirror_repository_id => mirror) ShixunMirrorRepository.create!(:shixun_id => @shixun.id, :mirror_repository_id => mirror)
# 实训子镜像服务配置
ShixunServiceConfig.create!(:shixun_id => @shixun.id, :mirror_repository_id => mirror)
end end
end end
@ -363,11 +377,6 @@ class ShixunsController < ApplicationController
end end
def update def update
h = {test_set_permission: params[:test_set_permission], code_hidden: params[:code_hidden],
task_pass: params[:task_pass], hide_code: params[:hide_code], forbid_copy: params[:forbid_copy]}
s_params = shixun_params.merge(h)
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
begin begin
@shixun.shixun_mirror_repositories.destroy_all @shixun.shixun_mirror_repositories.destroy_all
@ -380,8 +389,8 @@ class ShixunsController < ApplicationController
end end
end end
@shixun.update_attributes(s_params) @shixun.update_attributes(shixun_params)
@shixun.shixun_info.update_attributes(description: params[:description], evaluate_script: params[:evaluate_script]) @shixun.shixun_info.update_attributes(shixun_info_params)
@shixun.shixun_schools.delete_all @shixun.shixun_schools.delete_all
if params[:scope_partment].present? && params[:user_scope].to_i == 1 if params[:scope_partment].present? && params[:user_scope].to_i == 1
arr = [] arr = []
@ -395,6 +404,13 @@ class ShixunsController < ApplicationController
use_scope = 0 use_scope = 0
end end
@shixun.update_attributes!(:use_scope => use_scope) @shixun.update_attributes!(:use_scope => use_scope)
# 超级管理员和运营人员才能保存 中间层服务器pod信息的配置
if current_user.admin? || current_user.business?
@shixun.shixun_service_configs.destroy_all
params[:shixun_service_configs].each do |config|
@shixun.shixun_service_configs.create!(config)
end
end
rescue Exception => e rescue Exception => e
uid_logger_error(e.message) uid_logger_error(e.message)
tip_exception("实训保存失败") tip_exception("实训保存失败")
@ -430,6 +446,7 @@ class ShixunsController < ApplicationController
@choice_small_type = @shixun.small_mirror_id @choice_small_type = @shixun.small_mirror_id
@main_type = shixun_main_type @main_type = shixun_main_type
@small_type = shixun_small_type @small_type = shixun_small_type
@configs = @shixun.shixun_service_configs
#@mirror_script = MirrorScript.select([:id, :script_type]).find(@shixun.mirror_script_id).attributes if @shixun.mirror_script_id && @shixun.mirror_script_id != 0 #@mirror_script = MirrorScript.select([:id, :script_type]).find(@shixun.mirror_script_id).attributes if @shixun.mirror_script_id && @shixun.mirror_script_id != 0
# @shixun_main_mirror = @shixun.show_shixun_mirror # @shixun_main_mirror = @shixun.show_shixun_mirror
# @script_type = @shixun.script_tag.try(:script_type) || "无" # @script_type = @shixun.script_tag.try(:script_type) || "无"
@ -718,7 +735,13 @@ private
def shixun_params def shixun_params
raise("实训名称不能为空") if params[:name].blank? raise("实训名称不能为空") if params[:name].blank?
params.require(:shixun).permit(:name, :trainee, :webssh, :can_copy, :use_scope, :vnc, :test_set_permission, params.require(:shixun).permit(:name, :trainee, :webssh, :can_copy, :use_scope, :vnc, :test_set_permission,
:task_pass, :repo_name, :multi_webssh, :opening_time, :mirror_script_id) :task_pass, :repo_name, :multi_webssh, :opening_time, :mirror_script_id, :code_hidden,
:hide_code, :forbid_copy)
end
def shixun_info_params
raise("实训描述不能为空") if params[:description].blank?
raise("评测脚本不能为空") if params[:evaluate_script].blank?
params.require(:shixun_info).permit(:description, :evaluate_script)
end end
def find_shixun def find_shixun

@ -334,6 +334,24 @@ module ApplicationHelper
raw arr.join('') raw arr.join('')
end end
def to_markdown(text)
request_url = request.base_url
return nil if text.blank?
options = {
:autolink => true,
:no_intra_emphasis => true,
:fenced_code_blocks => true,
:lax_html_blocks => true,
:strikethrough => true,
:superscript => true,
:tables => true
}
markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML,options)
m_t = markdown.render(text)
m_t&.include?("src=\"") ? m_t&.gsub("src=\"","src=\"#{request_url}") : m_t
end
end end

@ -20,7 +20,7 @@ class Challenge < ApplicationRecord
# acts_as_attachable # acts_as_attachable
scope :base_attrs, -> { select([:id, :subject, :position, :shixun_id, :st, :score, :path, :task_pass, :modify_time, scope :base_attrs, -> { select([:id, :subject, :position, :shixun_id, :st, :score, :path, :task_pass, :modify_time,
:web_route, :answer]) } :web_route, :answer, :exec_time]) }
scope :choose_type, -> { where(st: 1) } scope :choose_type, -> { where(st: 1) }
scope :practice_type, -> { where(st: 0) } scope :practice_type, -> { where(st: 0) }

@ -1,5 +1,7 @@
class Shixun < ApplicationRecord class Shixun < ApplicationRecord
# status: 0编辑 1申请发布 2正式发布 3关闭 -1软删除 # status: 0编辑 1申请发布 2正式发布 3关闭 -1软删除
# hide_code 隐藏代码窗口
# code_hidden: 隐藏代码目录
has_many :challenges, dependent: :destroy has_many :challenges, dependent: :destroy
has_many :myshixuns, :dependent => :destroy has_many :myshixuns, :dependent => :destroy
has_many :shixun_members, dependent: :destroy has_many :shixun_members, dependent: :destroy
@ -30,6 +32,8 @@ class Shixun < ApplicationRecord
has_one :shixun_info, dependent: :destroy has_one :shixun_info, dependent: :destroy
belongs_to :user belongs_to :user
# 实训服务配置
has_many :shixun_service_configs, :dependent => :destroy
scope :search_by_name, ->(keyword) { where("name like ? or description like ? ", scope :search_by_name, ->(keyword) { where("name like ? or description like ? ",

@ -0,0 +1,4 @@
class ShixunServiceConfig < ApplicationRecord
belongs_to :shixun
belongs_to :mirror_repository
end

@ -272,4 +272,67 @@ class HomeworksService
end end
end end
end end
# 计算实训作品成绩
def update_myshixun_work_score work, myshixun, games, homework, challenge_settings
user_total_score = 0
pass_consume_time = 0
final_score = 0
setting_time = homework.homework_group_setting myshixun.user_id
homework_end_or_late_time = homework.allow_late ? homework.late_time : setting_time.end_time
games.each do |game|
# 在截止时间前通关的关卡才考虑得分
if game.status == 2 && game.end_time <= homework_end_or_late_time
challenge_setting = challenge_settings.select{|setting| setting.challenge_id == game.challenge_id}.first
pass_consume_time += (game.cost_time / 60.0).to_f
user_total_score += game.final_score.to_i < 0 ? 0 : game.challenge.score.to_i
adjust_score = work.challenge_work_scores.where(:challenge_id => game.challenge_id).last
final_score += if adjust_score.present?
adjust_score.score
elsif homework.homework_detail_manual.answer_open_evaluation
challenge_setting.score
elsif game.final_score > 0
game.real_score(challenge_setting.score)
else
0
end
end
end
myshixun_endtime = games.select{|game| game.status == 2}.size == games.size ? games.map(&:end_time).max : nil
if myshixun_endtime.present?
work.cost_time = myshixun_endtime.to_i - setting_time.publish_time.to_i
efficiency = (pass_consume_time == 0 ? 0 : Math.log((user_total_score / pass_consume_time.to_f) + 1.0))
work.efficiency = format("%.2f", efficiency)
if myshixun_endtime <= homework_end_or_late_time
work.compelete_status = myshixun_endtime < setting_time.publish_time ? 2 : 1
# 如果作业的最大效率值有变更则更新所有作品的效率分
homework.update_column("max_efficiency", work.efficiency) if homework.work_efficiency && homework.max_efficiency < work.efficiency
end
end
if work.work_status == 0
is_complete = myshixun_endtime && (myshixun_endtime < setting_time.end_time)
if is_complete || (!homework.allow_late && myshixun.created_at < setting_time.end_time)
work.work_status = 1
elsif homework.allow_late && myshixun.created_at < homework.late_time
work.work_status = 2
end
work.late_penalty = work.work_status == 2 ? homework.late_penalty : 0
work.commit_time = myshixun.created_at > setting_time.publish_time ? setting_time.publish_time : myshixun.created_at
work.myshixun_id = myshixun.id
end
work.update_time = myshixun.updated_at
work.final_score = final_score
score = work.final_score + work.eff_score - work.late_penalty
work.work_score = format("%.2f",(score < 0 ? 0 : score).to_f) unless work.ultimate_score
#logger.info("#############work_score: #{score}")
work.calculation_time = Time.now
work.save!
end
end end

@ -44,7 +44,6 @@
<span class="mr15">实训题<span class="mlr5"><%= @exercise_ques_shixun_count %></span>题, <span class="mr15">实训题<span class="mlr5"><%= @exercise_ques_shixun_count %></span>题,
共<span class="mlr5"><%= @exercise_ques_shixun_scores %></span>分</span> 共<span class="mlr5"><%= @exercise_ques_shixun_scores %></span>分</span>
<% end %> <% end %>
<% if @exercise_ques_count > 0 %> <% if @exercise_ques_count > 0 %>
<span class="pull-right"> <span class="pull-right">
共<span class="text-orange mlr5"><%= @exercise_ques_scores %></span>分 共<span class="text-orange mlr5"><%= @exercise_ques_scores %></span>分
@ -59,7 +58,7 @@
<div class="mbt10"> <div class="mbt10">
<% @exercise_questions.each do |q| %> <% @exercise_questions.each do |q| %>
<div class="bdc"> <div class="bdc">
<div class="pbt10"> <div class="pbt5">
<div class="pbt5"> <div class="pbt5">
<span class="mr5 text-blue"><%= q.question_number %>、</span> <span class="mr5 text-blue"><%= q.question_number %>、</span>
<span class="text-blue"> <span class="text-blue">
@ -68,41 +67,39 @@
<span class="text-gray mlr5">(<%= q&.question_score %>分)</span> <span class="text-gray mlr5">(<%= q&.question_score %>分)</span>
</div> </div>
<div class="pbt5"> <div class="pbt5">
<% q_title = q.question_title&.html_safe %>
<% if q.question_type == 5 %> <% if q.question_type == 5 %>
<% q_name = q.shixun_name&.html_safe %> <span class="ques-title" ><%= to_markdown(q.shixun_name) %></span>
<span class="ques-title"><%= q_name&.include?("src=\"") ? q_name&.gsub("src=\"","src=\"#{@request_url}") : q_name %></span>
<div class="mt8 text-gray"> <div class="mt8 text-gray">
<span><%= q_title&.include?("src=\"") ? q_title&.gsub("src=\"","src=\"#{@request_url}") : q_title %></span> <span><%= to_markdown(q.question_title) %></span>
</div> </div>
<% else %> <% else %>
<span class="ques-title"><%= q_title&.include?("src=\"") ? q_title&.gsub("src=\"","src=\"#{@request_url}") : q_title %></span> <span class="ques-title"><%= to_markdown(q.question_title) %></span>
<% end %> <% end %>
</div> </div>
<div class="pbt5"> <div class="pbt5">
<% if q.question_type == 0 %> <% if q.question_type == 0 %>
<% q.exercise_choices.each_with_index do |s,index| %> <% q.exercise_choices.each do |s| %>
<p class="pbt5"> <div class="pbt5 clearfix">
<span class="choose-radio"></span> <span class="choose-radio pull-left line-24 mt5"></span>
<span class="mr15"><%= convert_to_char((index+1).to_s)%></span><%= s.choice_text%> <span class="inline-block pull-left line-24 ml10"><%= to_markdown(s.choice_text) %></span>
</p> </div>
<% end %> <% end %>
<% elsif q.question_type == 1 %> <% elsif q.question_type == 1 %>
<% q.exercise_choices.each_with_index do |s,index| %> <% q.exercise_choices.each do |s| %>
<p class="pbt5"> <div class="pbt5 clearfix">
<span class="choose-checkbox"></span> <span class="choose-checkbox pull-left line-24 mt5"></span>
<span class="mr20"><%= convert_to_char((index+1).to_s)%></span><%= s.choice_text%> <span class="inline-block pull-left line-24 ml10"><%= to_markdown(s.choice_text) %></span>
</p> </div>
<% end %> <% end %>
<% elsif q.question_type == 2 %> <% elsif q.question_type == 2 %>
<p class="pbt5"> <div class="pbt5 clearfix">
<% q.exercise_choices.each_with_index do |s,index| %> <% q.exercise_choices.each do |s| %>
<span class="mr15"> <span class="mr15 clearfix">
<span class="choose-radio"></span> <span class="choose-radio "></span>
<span class="mlr5"><%= s.choice_text %></span> <span class="mlr5 inline-block"><%= s.choice_text %></span>
</span> </span>
<% end %> <% end %>
</p> </div>
<% elsif q.question_type == 3 %> <% elsif q.question_type == 3 %>
<% st_counts = q.exercise_standard_answers.pluck(:exercise_choice_id).uniq %> <% st_counts = q.exercise_standard_answers.pluck(:exercise_choice_id).uniq %>
<% st_counts.each_with_index do |s,index| %> <% st_counts.each_with_index do |s,index| %>
@ -134,4 +131,5 @@
</div> </div>
</div> </div>
</body> </body>
</html> </html>

@ -44,6 +44,9 @@ p{
.mbt10{ .mbt10{
margin: 10px 0; margin: 10px 0;
} }
.mt5{
margin-top:5px;
}
.pull-right{ .pull-right{
float:right; float:right;
} }
@ -82,9 +85,15 @@ p{
.ml20{ .ml20{
margin-left:20px; margin-left:20px;
} }
.ml10{
margin-left:10px;
}
.mr3{ .mr3{
margin-right:3px; margin-right:3px;
} }
.mr8{
margin-right:8px;
}
.mr15{ .mr15{
margin-right:15px; margin-right:15px;
} }
@ -309,6 +318,13 @@ textarea{
clear:both; clear:both;
zoom:1; zoom:1;
} }
.line-24{
line-height: 24px;
}
.line-24 p{
margin-bottom:0;
}

@ -167,41 +167,39 @@
<% end %> <% end %>
</div> </div>
<div class="pbt5"> <div class="pbt5">
<% q_title = q.question_title&.html_safe %> <% if q.question_type == 5 %>
<% if q_type == 5 %> <span class="ques-title" ><%= to_markdown(q.shixun_name) %></span>
<% q_name = q.shixun_name&.html_safe %>
<span class="ques-title"><%= q_name&.include?("src=\"") ? q_name&.gsub("src=\"","src=\"#{@request_url}") : q_name %></span>
<div class="mt8 text-gray"> <div class="mt8 text-gray">
<span><%= q_title&.include?("src=\"") ? q_title&.gsub("src=\"","src=\"#{@request_url}") : q_title %></span> <span><%= to_markdown(q.question_title) %></span>
</div> </div>
<% else %> <% else %>
<span class="ques-title"><%= q_title&.include?("src=\"") ? q_title&.gsub("src=\"","src=\"#{@request_url}") : q_title %></span> <span class="ques-title"><%= to_markdown(q.question_title) %></span>
<% end %> <% end %>
</div> </div>
</div> </div>
<div class="pbt5"> <div class="pbt5">
<% if q_type == 0 %> <% if q_type == 0 %>
<% q.exercise_choices.each_with_index do |s,index| %> <% q.exercise_choices.each do |s| %>
<% check_answer = (user_answer.present? && (s.id == user_answer.first.exercise_choice_id)) ? "choose-answer" : '' %> <% check_answer = (user_answer.present? && (s.id == user_answer.first.exercise_choice_id)) ? "choose-answer" : '' %>
<p class="pbt5"> <div class="pbt5 clearfix">
<span class="choose-radio <%= check_answer %>"></span> <span class="choose-radio <%= check_answer %> pull-left line-24 mt5"></span>
<span class="mr15"><%= convert_to_char((index+1).to_s)%></span><%= s.choice_text%> <span class="inline-block pull-left line-24 ml10"><%= to_markdown(s.choice_text) %></span>
</p> </div>
<% end %> <% end %>
<% elsif q_type == 1 %> <% elsif q_type == 1 %>
<% q.exercise_choices.each_with_index do |s,index| %> <% q.exercise_choices.each do |s| %>
<% check_answer = (user_answer.present? && (user_answer.pluck(:exercise_choice_id).include?(s.id))) ? true : false %> <% check_answer = (user_answer.present? && (user_answer.pluck(:exercise_choice_id).include?(s.id))) ? true : false %>
<p class="pbt5"> <div class="pbt5 clearfix">
<% if check_answer %> <% if check_answer %>
<span class="choose-checkbox choose-answer-multi" ></span> <span class="choose-checkbox choose-answer-multi pull-left line-24 mt5" ></span>
<% else %> <% else %>
<span class="choose-checkbox"></span> <span class="choose-checkbox pull-left line-24 mt5"></span>
<% end %> <% end %>
<span class="mr15"><%= convert_to_char((index+1).to_s)%></span><%= s.choice_text%> <span class="inline-block pull-left line-24 ml10"><%= to_markdown(s.choice_text) %></span>
</p> </div>
<% end %> <% end %>
<% elsif q_type == 2 %> <% elsif q_type == 2 %>
<p class="pbt5"> <div class="pbt5 clearfix">
<% q.exercise_choices.each do |s| %> <% q.exercise_choices.each do |s| %>
<% if user_answer.present? && (s.id == user_answer.first.exercise_choice_id) %> <% if user_answer.present? && (s.id == user_answer.first.exercise_choice_id) %>
<% check_answer = 'choose-answer' %> <% check_answer = 'choose-answer' %>
@ -213,7 +211,7 @@
<span class="mlr5"><%= s.choice_text %></span> <span class="mlr5"><%= s.choice_text %></span>
</span> </span>
<% end %> <% end %>
</p> </div>
<% elsif q_type == 3 %> <% elsif q_type == 3 %>
<% st_counts = q.exercise_standard_answers.pluck(:exercise_choice_id).uniq %> <% st_counts = q.exercise_standard_answers.pluck(:exercise_choice_id).uniq %>
<% st_counts.each_with_index do |s,index| %> <% st_counts.each_with_index do |s,index| %>
@ -224,13 +222,13 @@
<% end %> <% end %>
<p class="pbt10 flex-nowrap"> <p class="pbt10 flex-nowrap">
<span class="pull-left line-34">答案(填空<%= index+1 %></span> <span class="pull-left line-34">答案(填空<%= index+1 %></span>
<span class="null-answer"><%= check_answer&.html_safe %></span> <span class="null-answer"><%= to_markdown(check_answer) %></span>
</p> </p>
<% end %> <% end %>
<% elsif q_type == 4 %> <% elsif q_type == 4 %>
<% check_answer = (user_answer.present? ? user_answer.first.answer_text : '--') %> <% check_answer = (user_answer.present? ? user_answer.first.answer_text : '--') %>
<p class="flex-nowrap"> <p class="flex-nowrap">
<span class="null-answer main-height"><%= check_answer&.html_safe %></span> <span class="null-answer main-height"><%= to_markdown(check_answer) %></span>
</p> </p>
<% else %> <% else %>
<div class="mbt10"> <div class="mbt10">

@ -7,7 +7,7 @@ json.chooses do
end end
if @tab == 0 if @tab == 0
# 本关任务tab的编辑模式 # 本关任务tab的编辑模式
json.(@challenge, :id, :subject, :task_pass, :difficulty, :score) json.(@challenge, :id, :subject, :task_pass, :difficulty, :score, :exec_time)
json.tags @challenge.challenge_tags.map(&:name) json.tags @challenge.challenge_tags.map(&:name)
elsif @tab == 1 elsif @tab == 1
# 评测设置的编辑模式 # 评测设置的编辑模式

@ -11,4 +11,5 @@ json.homework_id homework.id
json.homework_type homework.homework_type json.homework_type homework.homework_type
if homework.homework_type == "practice" if homework.homework_type == "practice"
json.shixun_identifier homework.shixuns.take.try(:identifier) json.shixun_identifier homework.shixuns.take.try(:identifier)
json.shixun_id homework.shixuns.take.try(:id)
end end

@ -16,6 +16,7 @@ json.work_public @homework.work_public
if @user_course_identity < Course::STUDENT if @user_course_identity < Course::STUDENT
json.calculation_time @homework.calculation_time if @homework.homework_type == "practice"
# 教师身份的评阅、提交状态、分班过滤 # 教师身份的评阅、提交状态、分班过滤
if @homework.homework_type != "practice" if @homework.homework_type != "practice"
json.teacher_comment teacher_comment @homework, @current_user.id json.teacher_comment teacher_comment @homework, @current_user.id
@ -30,7 +31,7 @@ elsif @user_course_identity == Course::STUDENT
if @homework.homework_type == "practice" if @homework.homework_type == "practice"
json.(@work, :id, :work_status, :update_time, :ultimate_score) json.(@work, :id, :work_status, :update_time, :ultimate_score)
json.calculation_time @work.calculation_time
json.late_penalty @work.late_penalty if @homework.allow_late json.late_penalty @work.late_penalty if @homework.allow_late
json.cost_time @work.myshixun.try(:total_cost_time) json.cost_time @work.myshixun.try(:total_cost_time)
json.work_score work_score_format(@work.work_score, true, @score_open) json.work_score work_score_format(@work.work_score, true, @score_open)
@ -94,7 +95,7 @@ if @homework.homework_type == "practice"
json.user_login work.user.try(:login) json.user_login work.user.try(:login)
json.user_name work.user.try(:real_name) json.user_name work.user.try(:real_name)
json.student_id work.user.try(:student_id) json.student_id work.user.try(:student_id)
json.group_name @course.course_student(work.user_id).try(:course_group_name) json.group_name @students.select{|student| student.user_id == work.user_id}.first.try(:course_group_name)
end end
elsif @homework.homework_type == "group" || @homework.homework_type == "normal" elsif @homework.homework_type == "group" || @homework.homework_type == "normal"
json.anonymous_comment @homework.anonymous_comment json.anonymous_comment @homework.anonymous_comment
@ -133,7 +134,7 @@ elsif @homework.homework_type == "group" || @homework.homework_type == "normal"
end end
json.student_id work.user.try(:student_id) json.student_id work.user.try(:student_id)
json.group_name @course.course_student(work.user_id).try(:course_group_name) json.group_name @students.select{|student| student.user_id == work.user_id}.first.try(:course_group_name)
if @homework.homework_type == "group" if @homework.homework_type == "group"
if @homework.homework_detail_group.base_on_project if @homework.homework_detail_group.base_on_project
json.project_info project_info work, @current_user, @user_course_identity json.project_info project_info work, @current_user, @user_course_identity

@ -29,6 +29,14 @@ json.shixun do
json.scope_partment @shixun.schools.map(&:name) # 公开范围 json.scope_partment @shixun.schools.map(&:name) # 公开范围
json.opening_time @shixun.opening_time json.opening_time @shixun.opening_time
json.forbid_copy @shixun.forbid_copy json.forbid_copy @shixun.forbid_copy
# 实训服务配置
json.shixun_service_configs do
json.array! @configs do |config|
json.name config.mirror_repository&.name
json.(config, :cpu_limit, :lower_cpu_limit, :memory_limit, :request_limit, :mirror_repository_id)
end
end
end end

@ -338,6 +338,8 @@ Rails.application.routes.draw do
get :publish_groups get :publish_groups
get :end_groups get :end_groups
post :alter_name post :alter_name
get :update_score
get :update_student_score
end end
collection do collection do

@ -0,0 +1,6 @@
class AddCalculationTimeToHomework < ActiveRecord::Migration[5.2]
def change
add_column :homework_commons, :calculation_time, :datetime
add_column :student_works, :calculation_time, :datetime
end
end

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