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

dev_aliyun_beta
杨树林 5 years ago
commit 7b5f790bbb

@ -19,6 +19,13 @@
//= require_tree ./i18n
//= require_tree ./admins
$.ajaxSetup({
beforeSend: function(xhr) {
xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'));
}
});
// ******** select2 global config ********
$.fn.select2.defaults.set('theme', 'bootstrap4');
$.fn.select2.defaults.set('language', 'zh-CN');
@ -53,7 +60,6 @@ $(document).on("turbolinks:before-cache", function () {
$('[data-toggle="tooltip"]').tooltip('hide');
$('[data-toggle="popover"]').popover('hide');
});
// var progressBar = new Turbolinks.ProgressBar();
// $(document).on('ajax:send', function(event){

@ -27,10 +27,11 @@ $(document).on('turbolinks:load', function() {
});
// modal visited fire
$refuseModal.on('shown.bs.modal', function(){
$refuseModal.find('.modal-body input[name="reason"]').focus();
$refuseModal.find('.modal-body textarea[name="reason"]').focus();
});
$refuseModal.on('hide.bs.modal', function () {
$applyIdInput.val('');
$refuseModal.find('.modal-body textarea[name="reason"]').val('');
$form.data('url', '');
})

@ -1,16 +1,15 @@
$(document).on('turbolinks:load', function() {
if ($('body.admins-shixun-settings-index-page').length > 0) {
$(".shixun-settings-list-container").on("change", '.shixun-settings-select', function () {
var s_value = $(this).val();
var s_name = $(this).attr("name");
var json = {};
json[s_name] = s_value;
$.ajax({
url: "/admins/shixun_settings",
type: "GET",
dataType:'script',
data: json
})
let searchContainer = $(".shixun-settings-list-form");
let searchForm = $("form.search-form",searchContainer);
searchContainer.on('change', '.shixun-settings-select', function(){
searchForm.find('input[type="submit"]').trigger('click');
});
//导出
searchContainer.on('click',"#shixun-settings-export",function () {
window.location.href = "/admins/shixun_settings.xls?" + searchForm.serialize();
});
$(".shixun-settings-list-container").on("change", '.shixun-setting-form', function () {
@ -27,7 +26,12 @@ $(document).on('turbolinks:load', function() {
dataType:'script',
data: json
})
})
});
$("select#settings-tag-choosed").select2({
placeholder: "请选择分类",
allowClear: true
});
$('.modal.admin-upload-file-modal').on('upload:success', function(e, data){
var $imageElement = $('.shixun-image-' + data.source_id);

@ -4,5 +4,10 @@ $(document).on('turbolinks:load', function() {
placeholder: "请选择分类",
allowClear: true
});
$(".shixuns-list-form").on("click","#shixuns-export",function () {
let search_form = $(".search-form");
window.location.href = "/admins/shixuns.xls?" + search_form.serialize();
})
}
});

@ -0,0 +1,14 @@
class Admins::MyshixunsController < Admins::BaseController
def index
params[:sort_by] = params[:sort_by].presence || 'created_at'
params[:sort_direction] = params[:sort_direction].presence || 'desc'
myshixuns = Admins::MyshixunQuery.call(params)
@myshixuns = paginate myshixuns.includes(:last_executable_task, :last_task, shixun: :user, user: { user_extension: :school })
myshixun_ids = @myshixuns.map(&:id)
@finish_game_count = Game.where(myshixun_id: myshixun_ids, status: 2).group(:myshixun_id).count
@total_score = Game.where(myshixun_id: myshixun_ids, status: 2).where('final_score > 0').group(:myshixun_id).sum(:final_score)
end
end

@ -9,6 +9,16 @@ class Admins::ShixunSettingsController < Admins::BaseController
@pending_shixuns = shixun_settings.where(status:1).size
@processed_shixuns = shixun_settings.where(status:2).size
@closed_shixuns = shixun_settings.where(status:3).size
@sort_json = {
can_copy: params[:can_copy].present? ? params[:can_copy] : false,
webssh: params[:webssh].present? ? params[:webssh] : "0",
hidden: params[:hidden].present? ? params[:hidden] : false,
homepage_show: params[:homepage_show].present? ? params[:homepage_show] : false,
task_pass: params[:task_pass].present? ? params[:task_pass] : false,
code_hidden: params[:code_hidden].present? ? params[:code_hidden] : false
}
@shixuns_type_check = MirrorRepository.pluck(:type_name,:id)
@shixun_tags = TagRepertoire.order("name asc").pluck(:name,:id)
@params_page = params[:page] || 1
@ -22,6 +32,7 @@ class Admins::ShixunSettingsController < Admins::BaseController
send_data(shixun_list_xls(shixun_settings), :type => 'application/octet-stream', :filename => filename_for_content_disposition(filename))
}
end
end
def update

@ -127,7 +127,7 @@ class ExerciseBankQuestionsController < ApplicationController
normal_status("创建成功")
rescue Exception => e
uid_logger_error(e.message)
tip_exception("试卷问题创建失败!")
tip_exception(e.message)
raise ActiveRecord::Rollback
end
end
@ -311,7 +311,7 @@ class ExerciseBankQuestionsController < ApplicationController
normal_status(0,"试卷更新成功")
rescue Exception => e
uid_logger_error(e.message)
tip_exception("页面调用失败!")
tip_exception(e.message)
raise ActiveRecord::Rollback
end
end
@ -347,7 +347,7 @@ class ExerciseBankQuestionsController < ApplicationController
end
rescue Exception => e
uid_logger_error(e.message)
tip_exception("问题移动失败!")
tip_exception(e.message)
end
end
end
@ -364,7 +364,7 @@ class ExerciseBankQuestionsController < ApplicationController
normal_status(0, "删除成功")
rescue Exception => e
uid_logger_error(e.message)
tip_exception("删除失败")
tip_exception(e.message)
end
end
end
@ -372,7 +372,7 @@ class ExerciseBankQuestionsController < ApplicationController
private
def bank_admin
tip_exception(403, "无权限") unless @bank.user_id == current_user.id || current_user.admin?
tip_exception(403, "无权限") unless @exercise.user_id == current_user.id || current_user.admin?
end
def get_exercise

@ -24,28 +24,34 @@ class ExerciseBanksController < ApplicationController
def choose_shixun
search = params[:search]
if !current_user.admin? #当不为管理员的时候
user_school_id = current_user.school_id #当前用户的学校id
if user_school_id.present?
none_shixun_ids = ShixunSchool.where("school_id != #{user_school_id}").pluck(:shixun_id)
@publish_shixuns = Shixun.where.not(id: none_shixun_ids).unhidden
end
type = params[:type]
# 超级管理员用户显示所有未隐藏的实训、非管理员显示所有已发布的实训(对本单位公开且未隐藏未关闭)
if current_user.admin?
@shixuns = Shixun.unhidden
else
@publish_shixuns = Shixun.unhidden
none_shixun_ids = ShixunSchool.where("school_id != #{current_user.school_id}").pluck(:shixun_id)
@shixuns = Shixun.where.not(id: none_shixun_ids).unhidden
end
if search.present?
@publish_shixuns = @publish_shixuns.search_by_name(search)
# 实训的所有标签
@tags = TagRepertoire.select([:id, :name]).joins(:shixuns).where(shixuns: {id: @shixuns}).distinct
if params[:search] && params[:search].strip != ""
@shixuns = @shixuns.joins(:user).where("shixuns.name like ? or concat(users.lastname, users.firstname) like ?",
"%#{search}%", "%#{search}%").distinct
end
@shixuns = @publish_shixuns.joins(:challenges).where("challenges.st != 0").distinct
# 全部页面,需返回
@shixuns_count = @shixuns.count
unless type.blank? || type == "all"
@shixuns = @shixuns.joins(:shixun_tag_repertoires).where(shixun_tag_repertoires: {tag_repertoire_id: type}).distinct
end
# 分页
@page = params[:page] || 1
@limit = params[:limit] || 8
@shixuns = @shixuns.select([:id, :name, :status, :myshixuns_count, :identifier, :user_id, :trainee])
@total_count = @shixuns.size
@shixuns = @shixuns.page(@page).per(@limit)
## 分页参数
page = params[:page] || 1
@shixuns = @shixuns.reorder("shixuns.created_at desc").includes(:challenges, user: [user_extension: :school]).page(page).per(10)
end
#确认实训的选择

@ -54,7 +54,7 @@ class PollBankQuestionsController < ApplicationController
normal_status("创建成功")
rescue Exception => e
uid_logger_error(e.message)
tip_exception("问卷的问题创建失败!")
tip_exception(e.message)
raise ActiveRecord::Rollback
end
end
@ -67,13 +67,14 @@ class PollBankQuestionsController < ApplicationController
p_answer = params[:question_answers]
p_other_answer = params[:question_other_answer]
p_answer_count = p_answer.count
@poll_current_answers = @poll_question.exercise_bank_choices.count
@poll_question.exercise_bank_choices.each do |an|
if (p_answer_count < @poll_current_answers) && (p_answer_count..@poll_current_answers).to_a.include?(an.choice_position)
an.destroy
end
end
(1..p_answer_count).each do |i|
answer = @poll_question.exercise_bank_choices.find_by_custom("choice_position",i).first
answer = @poll_question.exercise_bank_choices.find_choice_custom("choice_position",i).first
if answer # 判断该位置的answer是否存在存在则更新.不存在则跳到下一步
answer.choice_text = p_answer[i-1]
answer.choice_position = i
@ -87,7 +88,7 @@ class PollBankQuestionsController < ApplicationController
end
end
if p_other_answer #判断答案的其他选项是否存在
other_answer = @poll_question.exercise_bank_choices.find_by_custom("choice_text","").first
other_answer = @poll_question.exercise_bank_choices.find_choice_custom("choice_text","").first
if other_answer.blank?
question_option = {
:choice_position => p_answer_count + 1,
@ -104,7 +105,7 @@ class PollBankQuestionsController < ApplicationController
normal_status("问卷更新成功")
rescue Exception => e
uid_logger_error(e.message)
tip_exception("更新失败")
tip_exception(e.message)
raise ActiveRecord::Rollback
end
end
@ -113,7 +114,7 @@ class PollBankQuestionsController < ApplicationController
private
def bank_admin
tip_exception(403, "无权限") unless @bank.user_id == current_user.id || current_user.admin?
tip_exception(403, "无权限") unless @poll.user_id == current_user.id || current_user.admin?
end
def get_poll
@ -126,30 +127,30 @@ class PollBankQuestionsController < ApplicationController
end
def poll_questions_params
params.require(:poll_question).permit(:question_title,:question_type,:is_necessary,:question_number,:max_choices,:min_choices)
params.permit(:question_title,:question_type,:is_necessary,:question_number,:max_choices,:min_choices)
end
def validates_params
normal_status(-1, "问题标题不能为空!") if params[:question_title].blank?
normal_status(-1, "是否要求必答的值不能为空!") if params[:is_necessary].blank?
normal_status(-1, "问题类型不能为空!") if params[:question_type].blank?
tip_exception(-1, "问题标题不能为空!") if params[:question_title].blank?
tip_exception(-1, "是否要求必答的值不能为空!") if params[:is_necessary].blank?
tip_exception(-1, "问题类型不能为空!") if params[:question_type].blank?
if params[:min_choices].present? && params[:max_choices].present? && (params[:min_choices].to_i > params[:max_choices].to_i)
normal_status(-1, "最小可选不能大于最大可选!")
tip_exception(-1, "最小可选不能大于最大可选!")
elsif params[:question_answers].present? && (params[:max_choices].to_i > params[:question_answers].count)
normal_status(-1, "选择题的最大可选项不能大于答案数!")
tip_exception(-1, "选择题的最大可选项不能大于答案数!")
elsif [1,3].include?(params[:question_type]) && (params[:max_choices].to_i > 0 || params[:min_choices].to_i > 0)
normal_status(-1, "单选题或主观题不能有最大或最小选择数!")
tip_exception(-1, "单选题或主观题不能有最大或最小选择数!")
elsif params[:question_type] == 3 && (params[:question_answers] || params[:question_other_answer])
normal_status(-1, "主观问题不需要可选答案!")
tip_exception(-1, "主观问题不需要可选答案!")
elsif params[:question_type] != 3
if params[:question_answers].present? && params[:question_answers].include?("")
normal_status(-1, "选择题不能有空值!")
tip_exception(-1, "选择题不能有空值!")
elsif params[:question_other_answer].present? && params[:question_other_answer].length > 0
normal_status(-1, "其他选项不能有值!")
tip_exception(-1, "其他选项不能有值!")
elsif params[:question_type] == 1 && params[:question_answers].count < 2
normal_status(-1, "单选题选项不能小于2")
tip_exception(-1, "单选题选项不能小于2")
elsif params[:question_type] == 2 && params[:question_answers].count < 3
normal_status(-1, "多选题选项不能小于3")
tip_exception(-1, "多选题选项不能小于3")
end
end
end

@ -655,15 +655,15 @@ class StudentWorksController < ApplicationController
# 查重作品调分
def adjust_review_score
tip_exception("缺少type参数") if params[:type].blank? || !["review", "report"].include?(params[:type])
if params[:type] == "review" && (params[:score].nil? || params[:challenge_id].nil? || params[:code_rate].nil? || params[:copy_user_id].nil?)
if params[:type] == "review" && (params[:score].blank? || params[:challenge_id].blank? || params[:code_rate].blank? || params[:copy_user_id].blank?)
tip_exception("参数错误score和challenge_id和code_rate和copy_user_id不能为空")
elsif params[:type] == "report" && (params[:score].nil? || params[:challenge_id].nil?)
tip_exception("参数错误score和challenge_id")
elsif params[:type] == "report" && (params[:score].blank? || params[:challenge_id].blank?)
tip_exception("参数错误score和challenge_id不能为空")
end
challenge_setting = @homework.homework_challenge_settings.find_by(challenge_id: params[:challenge_id])
challenge = challenge_setting&.challenge
tip_exception("不能小于零") if params[:score] < 0
tip_exception("不能大于关卡分值:#{challenge_setting.score}") if challenge_setting.score < params[:score]
tip_exception("不能小于零") if params[:score].to_i < 0
tip_exception("不能大于关卡分值:#{challenge_setting.score}") if challenge_setting.score < params[:score].to_i
ActiveRecord::Base.transaction do
begin

@ -1,6 +1,6 @@
class ExerciseBankQuestion < ApplicationRecord
belongs_to :exercise_bank
belongs_to :shixun
belongs_to :shixun, optional: true
has_many :exercise_bank_shixun_challenges,:dependent => :destroy
has_many :exercise_bank_choices, :dependent => :destroy
has_many :exercise_bank_standard_answers, :dependent => :destroy

@ -7,6 +7,9 @@ class Myshixun < ApplicationRecord
belongs_to :user
belongs_to :shixun, counter_cache: true
has_one :last_executable_task, -> { where(status: [0, 1]).reorder(created_at: :asc) }, class_name: 'Game'
has_one :last_task, -> { all }, class_name: 'Game'
validates_uniqueness_of :shixun_id, :scope => :user_id, :message => "shixun_id and user_id unique error"
scope :finished, lambda { where(status: 1) }
scope :search_myshixun_user, ->(user_id){where(user_id:user_id)}

@ -0,0 +1,26 @@
class Admins::MyshixunQuery < ApplicationQuery
include CustomSortable
attr_reader :params
sort_columns :created_at, default_by: :created_at, default_direction: :desc
def initialize(params)
@params = params
end
def call
objs = Myshixun.all
keyword = params[:keyword].to_s.strip
if keyword.present?
like_sql = 'users.login LIKE :keyword OR CONCAT(users.lastname, users.firstname) LIKE :keyword OR '\
'schools.name LIKE :keyword OR shixuns.name LIKE :keyword OR CONCAT(teacher.lastname, teacher.firstname) Like :keyword'
objs = objs.joins(:shixun, user: { user_extension: :school })
.joins('JOIN users teacher ON teacher.id = shixuns.user_id')
.where(like_sql, keyword: "%#{keyword}%")
end
custom_sort(objs, params[:sort_by], params[:sort_direction])
end
end

@ -5,15 +5,15 @@
<div class="box search-form-container department-list-form">
<%= form_tag(admins_departments_path, method: :get, class: 'form-inline search-form flex-1', remote: true) do %>
<div class="form-check mr-3">
<%= hidden_field_tag(:with_member, false) %>
<%= hidden_field_tag(:with_member, false,id:'') %>
<%= check_box_tag(:with_member, true, params[:with_member].to_s == 'true', class: 'form-check-input') %>
<label class="form-check-label" for="with_member">有部门管理员</label>
</div>
<div class="form-check mr-3">
<%= hidden_field_tag(:with_identifier, false) %>
<%= hidden_field_tag(:with_identifier, false,id:'') %>
<%= check_box_tag(:with_identifier, true, params[:with_identifier].to_s == 'true', class: 'form-check-input') %>
<label class="form-check-label" for="with_member">有统计链接</label>
<label class="form-check-label" for="with_identifier">有统计链接</label>
</div>
<%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: '部门/单位名称检索') %>

@ -0,0 +1,14 @@
<% define_admin_breadcrumbs do %>
<% add_admin_breadcrumb('学员实训列表') %>
<% end %>
<div class="box search-form-container myshixun-list-form">
<%= form_tag(admins_myshixuns_path, method: :get, class: 'form-inline search-form', remote: true) do %>
<%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-md-4 ml-3', placeholder: '学员UID/姓名/学校/实训名称/老师姓名检索') %>
<%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %>
<% end %>
</div>
<div class="box myshixun-list-container">
<%= render(partial: 'admins/myshixuns/shared/list', locals: { myshixuns: @myshixuns, finish_game_count: @finish_game_count, total_score: @total_score }) %>
</div>

@ -0,0 +1 @@
$('.myshixun-list-container').html("<%= j( render(partial: 'admins/myshixuns/shared/list', locals: { myshixuns: @myshixuns, finish_game_count: @finish_game_count, total_score: @total_score }) ) %>");

@ -0,0 +1,49 @@
<table class="table table-hover text-center myshixun-list-table">
<thead class="thead-light">
<tr>
<th width="6%">ID</th>
<th width="10%">标识</th>
<th width="22%" class="text-left">实训名称</th>
<th width="10%">实训老师</th>
<th width="6%">完成</th>
<th width="6%">经验值</th>
<th width="10%">学员姓名</th>
<th width="16%" class="text-left">学员单位</th>
<th width="14%"><%= sort_tag('开启时间', name: 'created_at', path: admins_myshixuns_path) %></th>
</tr>
</thead>
<tbody>
<% if myshixuns.present? %>
<% myshixuns.each do |myshixun| %>
<tr class="myshixun-item-<%= myshixun.id %>">
<td><%= myshixun.id %></td>
<td>
<% current_task = myshixun.last_executable_task || myshixun.last_task %>
<%= link_to "/myshixuns/#{myshixun.identifier}/stages/#{current_task.identifier}", target: '_blank' do %>
<%= myshixun.identifier %>
<% end %>
</td>
<td class="text-left">
<%= link_to "/shixuns/#{myshixun.shixun.identifier}", target: '_blank' do %>
<%= overflow_hidden_span myshixun.shixun.name, width: 280 %>
<% end %>
</td>
<td><%= myshixun.shixun.user.real_name %></td>
<td><%= finish_game_count.fetch(myshixun.id, 0) %>/<%= myshixun.shixun.challenges_count %></td>
<td><%= total_score.fetch(myshixun.id, 0) %></td>
<td>
<%= link_to "/users/#{myshixun.user.login}", target: '_blank' do %>
<%= overflow_hidden_span myshixun.user.real_name, width: 80 %>
<% end %>
</td>
<td class="text-left"><%= overflow_hidden_span myshixun.user&.school_name, width: 150 %></td>
<td><%= myshixun.created_at&.strftime('%Y-%m-%d %H:%M') %></td>
</tr>
<% end %>
<% else %>
<%= render 'admins/shared/no_data_for_table' %>
<% end %>
</tbody>
</table>
<%= render partial: 'admins/shared/paginate', locals: { objects: myshixuns } %>

@ -8,14 +8,14 @@
</button>
</div>
<div class="modal-body">
<form class="admin-common-refuse-form">
<%= form_tag(admins_path, method: :post, class: 'admin-common-refuse-form') do %>
<%= hidden_field_tag(:apply_id, nil) %>
<div class="form-group">
<label for="reason" class="col-form-label">原因:</label>
<%= text_area_tag(:reason, nil, class: 'form-control', placeholder: '我得说点儿什么最多200字') %>
</div>
<div class="error text-danger"></div>
</form>
<% end %>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>

@ -25,6 +25,7 @@
<li><%= sidebar_item(admins_shixuns_path, '实训列表', icon: 'jsfiddle', controller: 'admins-shixuns') %></li>
<li><%= sidebar_item(admins_shixun_settings_path, '实训配置', icon: 'cog', controller: 'admins-shixun_settings') %></li>
<li><%= sidebar_item(admins_mirror_repositories_path, '镜像管理', icon: 'cubes', controller: 'admins-mirror_repositories') %></li>
<li><%= sidebar_item(admins_myshixuns_path, '学员实训列表', icon: 'server', controller: 'admins-myshixuns') %></li>
<% end %>
</li>

@ -13,7 +13,7 @@
</div>
<div class="form-group mr-2">
<label for="tag-choosed">技术平台:</label>
<%= select_tag(:tag, options_for_select(@shixuns_type_check.unshift(["",nil])), class: 'form-control',id:"tag-choosed") %>
<%= select_tag(:tag, options_for_select(@shixuns_type_check.unshift(["",nil])), class: 'form-control',id:"settings-tag-choosed") %>
</div>
<div class="form-group mr-2">
<label>搜索类型:</label>
@ -21,47 +21,47 @@
<%= select_tag(:search_type, options_for_select(auto_trial_options), class: 'form-control') %>
</div>
<%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: '输入关键字搜索') %>
<%= submit_tag('搜索', class: 'btn btn-primary ml-3') %>
<%= submit_tag('搜索', class: 'btn btn-primary ml-3','data-disable-with': '搜索中...') %>
<%= link_to "清除",admins_shixun_settings_path(status:nil,tag:nil,search_type:nil,keyword:nil),class: "btn btn-default" %>
<div class="">
<a href="<%= admins_shixun_settings_path( :format => "xls") %>" class="btn btn-primary export-absolute" id="shixun_xls">导出</a>
<a href="javascript:void(0)" class="btn btn-primary export-absolute" id="shixun-settings-export" data-disable-with = '导出中...'>导出</a>
</div>
</div>
<div class="d-flex mt-3">
<div class="mr-5">
<label for="can_copy">
<%= check_box_tag :can_copy,true,false,remote:true,class:"shixun-settings-select" %>
<%= check_box_tag :can_copy,!@sort_json[:can_copy],@sort_json[:can_copy],class:"shixun-settings-select" %>
<span class="only_view">只看可复制</span>
</label>
</div>
<div class="mr-5">
<label for="webssh">
<%= check_box_tag :webssh,1,false,remote:true, class:"shixun-settings-select" %>
<%= check_box_tag :webssh,(@sort_json[:webssh] == "0" ? "1" : "0"),(@sort_json[:webssh] == "1"), class:"shixun-settings-select" %>
<span class="only_view">只看可ssh</span>
</label>
</div>
<div class="mr-5">
<label for="hidden">
<%= check_box_tag :hidden,true,false,remote:true, class:"shixun-settings-select" %>
<%= check_box_tag :hidden,!@sort_json[:hidden],@sort_json[:hidden], class:"shixun-settings-select" %>
<span class="only_view">只看已隐藏</span>
</label>
</div>
<div class="mr-5">
<label for="homepage_show">
<%= check_box_tag :homepage_show,true,false,remote:true, class:"shixun-settings-select" %>
<%= check_box_tag :homepage_show,!@sort_json[:homepage_show],@sort_json[:homepage_show], class:"shixun-settings-select" %>
<span class="only_view">只看首页显示</span>
</label>
</div>
<div class="mr-5">
<label for="task_pass">
<%= check_box_tag :task_pass, true, false, remote:true, class:"shixun-settings-select" %>
<%= check_box_tag :task_pass, !@sort_json[:task_pass],@sort_json[:task_pass], class:"shixun-settings-select" %>
<span class="only_view">只看可跳关</span>
</label>
</div>
<div class="mr-5">
<label for="code_hidden">
<%= check_box_tag :code_hidden, true, false, remote:true, class:"shixun-settings-select" %>
<%= check_box_tag :code_hidden, !@sort_json[:code_hidden],@sort_json[:code_hidden], class:"shixun-settings-select" %>
<span class="only_view">只看已隐藏文件目录</span>
</label>
</div>

@ -3,7 +3,7 @@
<% end %>
<div class="box search-form-container shixuns-list-form">
<%= form_tag(admins_shixuns_path, method: :get, class: 'form-inline search-form', remote: true) do %>
<%= form_tag(admins_shixuns_path, method: :get, class: 'form-inline search-form',remote:true) do %>
<div class="form-group mr-2">
<label for="status">状态:</label>
<% status_options = [['全部', ''], ["编辑中(#{@editing_shixuns})", "editing"], ["待审核(#{@pending_shixuns})", 'pending'], ["已发布(#{@processed_shixuns})", 'processed'],["已关闭(#{@closed_shixuns})",'closed']] %>
@ -21,11 +21,10 @@
<%= select_tag(:search_type, options_for_select(auto_trial_options), class: 'form-control') %>
</div>
<%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: '输入关键字搜索') %>
<%= submit_tag('搜索', class: 'btn btn-primary ml-3') %>
<%= submit_tag('搜索', class: 'btn btn-primary ml-3','data-disable-with': '搜索中...') %>
<%= link_to "清除",admins_shixuns_path(status:nil,tag:nil,search_type:nil,keyword:nil),class: "btn btn-default" %>
<% end %>
<a href="<%= admins_shixuns_path( :format => "xls") %>" class="btn btn-primary" id="shixun_xls">导出</a>
<% end %>
<a href="javascript:void(0)" class="btn btn-primary" id="shixuns-export" data-disable-with = '导出中...'>导出</a>
</div>
<div class="box shixuns-list-container">

@ -1,10 +1,17 @@
json.shixun_counts @shixuns_count
json.shixun_list @shixuns do |shixun|
json.shixun_id shixun.id
json.identifier shixun.identifier
json.shixun_name shixun.name
json.myshixuns_count shixun.myshixuns_count
json.school shixun.user&.school_name
json.creator shixun.user&.full_name
json.level level_to_s(shixun.trainee)
end
json.shixuns do
json.array! @shixuns do |s|
json.shixun_id s.id
json.shixun_name s.name
json.shixun_user s.user.real_name
json.shixun_user_count s.myshixuns_count
end
end
json.tags @tags do |tag|
json.tag_id tag.id
json.tag_name tag.name
end
json.shixuns_count @total_count
json.search_tags @search_tags

@ -1,4 +1,4 @@
json.status 0
json.message "调分成功"
json.work_score number_with_precision @work.work_score, 1
json.challenge_score number_with_precision @work.final_score, 1
json.work_score number_with_precision(@work.work_score, precision: 1)
json.challenge_score number_with_precision(@work.final_score, precision: 1)

@ -2,6 +2,7 @@ json.homework_common_id @homework.id
json.category @homework.category_info
json.course_name @course.name
json.work_id @work.id
json.work_efficiency @homework.work_efficiency
if @shixun
json.shixun_name @shixun.name
# 总体评价

@ -850,6 +850,7 @@ Rails.application.routes.draw do
post :merge, on: :collection
end
resources :myshixuns, only: [:index]
end
resources :colleges, only: [] do

@ -0,0 +1,6 @@
class MigratePollBankQuestion < ActiveRecord::Migration[5.2]
def change
ExerciseBankQuestion.where(question_type: 0, exercise_bank_id: ExerciseBank.where(container_type: 'Poll').pluck(:id)).update_all(question_type: 1)
ExerciseBankQuestion.where(question_type: 1, exercise_bank_id: ExerciseBank.where(container_type: 'Poll').pluck(:id)).update_all(question_type: 2)
end
end

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -37597,10 +37597,11 @@ $(document).on('turbolinks:load', function() {
});
// modal visited fire
$refuseModal.on('shown.bs.modal', function(){
$refuseModal.find('.modal-body input[name="reason"]').focus();
$refuseModal.find('.modal-body textarea[name="reason"]').focus();
});
$refuseModal.on('hide.bs.modal', function () {
$applyIdInput.val('');
$refuseModal.find('.modal-body textarea[name="reason"]').val('');
$form.data('url', '');
})
@ -38423,17 +38424,16 @@ $(document).on('turbolinks:load', function() {
;
$(document).on('turbolinks:load', function() {
if ($('body.admins-shixun-settings-index-page').length > 0) {
$(".shixun-settings-list-container").on("change", '.shixun-settings-select', function () {
var s_value = $(this).val();
var s_name = $(this).attr("name");
var json = {};
json[s_name] = s_value;
$.ajax({
url: "/admins/shixun_settings",
type: "GET",
dataType:'script',
data: json
})
let searchContainer = $(".shixun-settings-list-form");
let searchForm = $("form.search-form",searchContainer);
searchContainer.on('change', '.shixun-settings-select', function(){
searchForm.find('input[type="submit"]').trigger('click');
});
//导出
searchContainer.on('click',"#shixun-settings-export",function () {
window.location.href = "/admins/shixun_settings.xls?" + searchForm.serialize();
});
$(".shixun-settings-list-container").on("change", '.shixun-setting-form', function () {
@ -38450,7 +38450,12 @@ $(document).on('turbolinks:load', function() {
dataType:'script',
data: json
})
})
});
$("select#settings-tag-choosed").select2({
placeholder: "请选择分类",
allowClear: true
});
$('.modal.admin-upload-file-modal').on('upload:success', function(e, data){
var $imageElement = $('.shixun-image-' + data.source_id);
@ -38467,6 +38472,11 @@ $(document).on('turbolinks:load', function() {
placeholder: "请选择分类",
allowClear: true
});
$(".shixuns-list-form").on("click","#shixuns-export",function () {
let search_form = $(".search-form");
window.location.href = "/admins/shixuns.xls?" + search_form.serialize();
})
}
});
$(document).on('turbolinks:load', function(){
@ -38803,6 +38813,13 @@ $(document).on('turbolinks:load', function(){
$.ajaxSetup({
beforeSend: function(xhr) {
xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'));
}
});
// ******** select2 global config ********
$.fn.select2.defaults.set('theme', 'bootstrap4');
@ -38838,7 +38855,6 @@ $(document).on("turbolinks:before-cache", function () {
$('[data-toggle="tooltip"]').tooltip('hide');
$('[data-toggle="popover"]').popover('hide');
});
// var progressBar = new Turbolinks.ProgressBar();
// $(document).on('ajax:send', function(event){

@ -37597,10 +37597,11 @@ $(document).on('turbolinks:load', function() {
});
// modal visited fire
$refuseModal.on('shown.bs.modal', function(){
$refuseModal.find('.modal-body input[name="reason"]').focus();
$refuseModal.find('.modal-body textarea[name="reason"]').focus();
});
$refuseModal.on('hide.bs.modal', function () {
$applyIdInput.val('');
$refuseModal.find('.modal-body textarea[name="reason"]').val('');
$form.data('url', '');
})
@ -38423,17 +38424,16 @@ $(document).on('turbolinks:load', function() {
;
$(document).on('turbolinks:load', function() {
if ($('body.admins-shixun-settings-index-page').length > 0) {
$(".shixun-settings-list-container").on("change", '.shixun-settings-select', function () {
var s_value = $(this).val();
var s_name = $(this).attr("name");
var json = {};
json[s_name] = s_value;
$.ajax({
url: "/admins/shixun_settings",
type: "GET",
dataType:'script',
data: json
})
let searchContainer = $(".shixun-settings-list-form");
let searchForm = $("form.search-form",searchContainer);
searchContainer.on('change', '.shixun-settings-select', function(){
searchForm.find('input[type="submit"]').trigger('click');
});
//导出
searchContainer.on('click',"#shixun-settings-export",function () {
window.location.href = "/admins/shixun_settings.xls?" + searchForm.serialize();
});
$(".shixun-settings-list-container").on("change", '.shixun-setting-form', function () {
@ -38450,7 +38450,12 @@ $(document).on('turbolinks:load', function() {
dataType:'script',
data: json
})
})
});
$("select#settings-tag-choosed").select2({
placeholder: "请选择分类",
allowClear: true
});
$('.modal.admin-upload-file-modal').on('upload:success', function(e, data){
var $imageElement = $('.shixun-image-' + data.source_id);
@ -38467,6 +38472,11 @@ $(document).on('turbolinks:load', function() {
placeholder: "请选择分类",
allowClear: true
});
$(".shixuns-list-form").on("click","#shixuns-export",function () {
let search_form = $(".search-form");
window.location.href = "/admins/shixuns.xls?" + search_form.serialize();
})
}
});
$(document).on('turbolinks:load', function(){
@ -38803,6 +38813,13 @@ $(document).on('turbolinks:load', function(){
$.ajaxSetup({
beforeSend: function(xhr) {
xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'));
}
});
// ******** select2 global config ********
$.fn.select2.defaults.set('theme', 'bootstrap4');
@ -38838,7 +38855,6 @@ $(document).on("turbolinks:before-cache", function () {
$('[data-toggle="tooltip"]').tooltip('hide');
$('[data-toggle="popover"]').popover('hide');
});
// var progressBar = new Turbolinks.ProgressBar();
// $(document).on('ajax:send', function(event){

@ -69,11 +69,18 @@ class ShixunWorkReport extends Component {
}
componentDidMount() {
let query = this.props.location.pathname;
const type = query.split('/');
this.setState({
shixuntypes:type[3],
spinning:true
})
this.getdatalist()
}
getdatalist=()=>{
let homeworkid=this.props.match.params.homeworkid;
let url = `/student_works/${homeworkid}/shixun_work_report.json`
let url = `/student_works/${homeworkid}/shixun_work_report.json`
axios.get(url).then((result) => {
if (result.data.status === 403||result.data.status === 401||result.data.status === 407||result.data.status === 408) {
@ -90,11 +97,7 @@ class ShixunWorkReport extends Component {
spinning:false
})
})
let query = this.props.location.pathname;
const type = query.split('/');
this.setState({
shixuntypes:type[3]
})
}
jumptopic=(anchorName)=>{
; if (anchorName) {
@ -154,11 +157,11 @@ class ShixunWorkReport extends Component {
<div style={{ width:'100%',height:'75px'}} >
<p className=" fl color-black mt25 summaryname">{data&&data.shixun_name}</p>
{/*{this.props.isAdmin()?<a className=" fr font-14 ml30 mt10 mr20 color-grey-9 ">导出实训报告数据</a>:""}*/}
{/*{this.props.isAdmin() ? <a*/}
{/*className="fr color-blue font-16"*/}
{/*onClick={()=>this.confirmysl(`/student_works/${homeworkid}/export_shixun_work_report.pdf`)}*/}
{/*>导出实训报告数据</a> : ""}*/}
<a onClick={this.goback} className="color-grey-6 fr font-16 ml30 mt15 mr20">返回</a>
{this.props.isAdmin() ? <a
className=" color-blue font-16 fr ml30 mt15 mr20"
onClick={()=>this.confirmysl(`/student_works/${homeworkid}/export_shixun_work_report.pdf`)}
>导出实训报告数据</a> : ""}
</div>
<div className="stud-class-set">
@ -179,8 +182,10 @@ class ShixunWorkReport extends Component {
<div className="font-16 color-dark-21 shixunreporttitle ml20 pd20">阶段成绩</div>
<OfficialAcademicTranscript
{...this.props}
data={data}
jumptopic={this.jumptopic}
getdatalist={()=>this.getdatalist()}
/>
</div>

@ -17,6 +17,7 @@ class ConclusionEvaluation extends Component {
render() {
let {data}=this.props;
let columns=[{
title: '总评',
dataIndex: 'type',
@ -34,7 +35,38 @@ class ConclusionEvaluation extends Component {
</span>
),
}, {
title: '作业成绩',
title: '关卡得分',
dataIndex: 'challenge_scores',
key: 'challenge_scores',
render: (text, record) => (
<span>
<Tooltip placement="bottom" title={
<pre>
分数{record.challenge_scores.challenge_score}/总分{record.challenge_scores.challenge_score_full}
</pre>
}>
<span style={{color:'#FF6800'}}>{record.challenge_scores.challenge_score}</span><span className={"color-grey-9"}>/{record.challenge_scores.challenge_score_full}</span>
</Tooltip>
</span>
),
},
{
title: '效率分',
dataIndex: 'eff_scores',
key: 'eff_scores',
render: (text, record) => (
<span>
<Tooltip placement="bottom" title={
<pre>
分数{record.eff_scores.eff_score}/总分{record.eff_score_full}
</pre>
}>
<span style={{color:'#FF6800'}}>{record.eff_scores.eff_score}</span><span className={"color-grey-9"}>/{record.eff_scores.eff_score_full}</span>
</Tooltip>
</span>
),
},{
title: '最终成绩',
dataIndex: 'grade',
key: 'grade',
render: (text, record) => (
@ -71,12 +103,31 @@ class ConclusionEvaluation extends Component {
let datas=[];
if(data&&data.eff_score_full===undefined){
columns.some((item,key)=> {
if (item.title === "关卡得分") {
columns.splice(key, 1)
return true
}
}
)
columns.some((item,key)=> {
if (item.title === "效率分") {
columns.splice(key, 1)
return true
}
}
)
}
datas.push({
type: data&&data.overall_appraisal,
empirical: {minute:data&&data.myself_experience,total:data&&data.total_experience},
grade: {minute:data&&data.work_score,total:data&&data.all_work_score},
elapsed: data&&data.time_consuming,
time:data&&data.evaluate_count
time:data&&data.evaluate_count,
eff_scores:{eff_score:data&&data.eff_score,eff_score_full:data&&data.eff_score_full},
challenge_scores:{challenge_score:data&&data.challenge_score,challenge_score_full:data&&data.challenge_score_full}
})
return (
<div>

@ -1,8 +1,8 @@
import React, {Component} from "react";
import {WordsBtn} from 'educoder';
import {Table} from "antd";
import {Table,InputNumber,Tooltip} from "antd";
import {Link,Switch,Route,Redirect} from 'react-router-dom';
import axios from 'axios';
class OfficialAcademicTranscript extends Component {
constructor(props) {
@ -22,6 +22,27 @@ class OfficialAcademicTranscript extends Component {
this.props.jumptopic(e);
}
editgame_scores=(score,id)=>{
if(score!=null&&score!=undefined&&score!=""){
let work_id=this.props.data.work_id;
let url=`/student_works/${work_id}/adjust_review_score.json`
axios.post(url,{
type:"report",
score:score,
challenge_id:id
}).then((result)=>{
if(result.data.status===0){
this.props.getdatalist()
this.props.showNotification(result.data.message);
}else{
this.props.showNotification(result.data.message);
}
}).catch((error)=>{
})
}
}
render() {
let {data}=this.props;
@ -37,13 +58,14 @@ class OfficialAcademicTranscript extends Component {
finishtime:item.finished_time,
elapsedtime:item.time_consuming,
empvalue:{myself:item.myself_experience,experience:item.experience},
game_scores:{game_score:item.game_score,game_score_full:item.game_score_full},
challenge_id:{id:item.challenge_id}
// adjustmentminute:asdasd
})
})
}
let columns=[{
title: '关卡',
dataIndex: 'customs',
@ -111,26 +133,54 @@ class OfficialAcademicTranscript extends Component {
render: (text, record) => (
<span>
<span style={{color:'#29BD8B'}}>{record.empvalue.myself}</span><span className={"color-grey-9"}>/{record.empvalue.experience}</span>
</span>
),
},{
title: '关卡得分',
key: 'game_scores',
dataIndex: 'game_scores',
render: (text, record) => (
<span>
<Tooltip placement="bottom" title={
<pre>
关卡得分{record.game_scores.game_score}/关卡满分{record.game_scores.game_score_full}
</pre>
}>
<span style={{color:'#29BD8B'}}>{record.game_scores.game_score}</span><span className={"color-grey-9"}>/{record.game_scores.game_score_full}</span>
</Tooltip>
</span>
),
},{
title: '调分',
key: 'adjustmentminute',
dataIndex: 'adjustmentminute',
render: (text, record) => (
<span>
<a><InputNumber size="small" defaultValue={record.game_scores.game_score}
onChange={(e) => this.editgame_scores(e,record.challenge_id.id)}
min={0} max={record.game_scores.game_score_full}
/></a>
{/*<a style={{textAlign: "center"}} className="color-blue font-14 mr20">查看</a>*/}
</span>
),
}];
// {
// title: '调分',
// key: 'adjustmentminute',
// dataIndex: 'adjustmentminute',
//
// render: (text, record) => (
// <span>
// <a>6小时 50分钟 6秒</a>
// </span>
// ),
// },
if(this.props.isAdmin()===false){
columns.some((item,key)=> {
if (item.title === "调分") {
columns.splice(key, 1)
return true
}
}
)
}
return (
<div>
{/*{data===undefined?"":""}*/}
<style>{`
.ant-table-thead > tr > th{
text-align: center;
@ -176,7 +226,7 @@ class OfficialAcademicTranscript extends Component {
text-align: left !important;
}
.TaskForms{
width: 500px;
width: 450px;
text-align: left !important;
padding: 16px !important;
}
@ -184,6 +234,11 @@ class OfficialAcademicTranscript extends Component {
width: 100%;
text-align: center;
}
.ant-input-number{
// margin-right: 20px;
border-radius: 0px;
width: 66px;
}
`}
</style>
{datas===undefined?"":<Table

Loading…
Cancel
Save