Merge branches 'dev_aliyun' and 'topic_bank' of https://bdgit.educoder.net/Hjqreturn/educoder into dev_Ysl

dev_aliyun_beta
杨树林 5 years ago
commit df4732c59a

@ -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,11 +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 input[name="reason"]').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-form").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();
})
}
});

@ -5,8 +5,6 @@ class Admins::BaseController < ApplicationController
layout 'admin'
skip_before_action :verify_authenticity_token
before_action :require_login, :require_admin!
after_action :rebind_event_if_ajax_render_partial

@ -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

@ -240,7 +240,7 @@ class ApplicationController < ActionController::Base
uid_logger("user_setup: " + (User.current.logged? ? "#{User.current.try(:login)} (id=#{User.current.try(:id)})" : "anonymous"))
if !User.current.logged? && Rails.env.development?
# User.current = User.find 1
User.current = User.find 1
end

@ -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 } %>

@ -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)

@ -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,11 +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 input[name="reason"]').val('');
$refuseModal.find('.modal-body textarea[name="reason"]').val('');
$form.data('url', '');
})
@ -38424,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-form").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 () {
@ -38451,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);
@ -38468,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(){
@ -38804,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');
@ -38839,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,11 +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 input[name="reason"]').val('');
$refuseModal.find('.modal-body textarea[name="reason"]').val('');
$form.data('url', '');
})
@ -38424,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-form").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 () {
@ -38451,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);
@ -38468,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(){
@ -38804,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');
@ -38839,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){

@ -32,7 +32,7 @@ module.exports = {
// See the discussion in https://github.com/facebookincubator/create-react-app/issues/343.s
// devtool: "cheap-module-eval-source-map",
// 开启调试
// devtool: "source-map", // 开启调试
devtool: "eval", // 开启调试
// These are the "entry points" to our application.
// This means they will be the "root" imports that are included in JS bundle.
// The first two entry points enable "hot" CSS and auto-refreshes for JS.

@ -154,11 +154,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,6 +179,7 @@ class ShixunWorkReport extends Component {
<div className="font-16 color-dark-21 shixunreporttitle ml20 pd20">阶段成绩</div>
<OfficialAcademicTranscript
{...this.props}
data={data}
jumptopic={this.jumptopic}
/>

@ -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,26 @@ class OfficialAcademicTranscript extends Component {
this.props.jumptopic(e);
}
editgame_scores=(score,id)=>{
if(score!=null&&score!=undefined){
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.showNotification(result.data.message);
}else{
this.props.showNotification(result.data.message);
}
}).catch((error)=>{
})
}
}
render() {
let {data}=this.props;
@ -37,13 +57,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 +132,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 +225,7 @@ class OfficialAcademicTranscript extends Component {
text-align: left !important;
}
.TaskForms{
width: 500px;
width: 450px;
text-align: left !important;
padding: 16px !important;
}
@ -184,6 +233,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

@ -298,7 +298,7 @@ class InfosTopics extends Component{
</Menu>
);
return(
<div className="educontent mb50 mt40 topicsmb141">
<div className="educontent mb50 mt40">
{/*提示*/}
<style>
{
@ -406,16 +406,6 @@ class InfosTopics extends Component{
</div>
</div>:<div className={"professional_certificationbox"}>
<style>
{
`
.topicsmb141{
margin-bottom: 141px !important;
}
`
}
</style>
<p className="clearfix ">
<div className={"stud-class-set pd115200 coursenavbox edu-back-white"}>
<div className={"sumbtongs mb10"}><img className={"topicsItemimg"} src={Withoutpermission}/></div>

@ -60,7 +60,7 @@ const PollNewQuestbank =Loadable({
});
const GtaskBanksEdit = Loadable({
loader: () => import('./GtaskBanksEditEdit'),
loader: () => import('./GtaskBanksEdit'),
loading: Loading,
})
@ -88,7 +88,7 @@ class BanksIndex extends Component{
<div className="educontent">
{
crumbData &&
<Breadcrumb separator=">" className="breadcrumb">
<Breadcrumb separator=">" className="breadcrumb mt22">
<Breadcrumb.Item href="/users/innov/banks">题库</Breadcrumb.Item>
{
crumbData.crumbArray && crumbData.crumbArray.map((item,key)=>{
@ -99,17 +99,24 @@ class BanksIndex extends Component{
}
</Breadcrumb>
}
<p className="clearfix mt30">
{
crumbData &&<p className="clearfix mt10 mb10 ">
<span className="fl font-24 color-grey-3 task-hide lineh-30" style={{maxWidth:'800px'}}>{crumbData && crumbData.title}</span>
{
crumbData && <span className="bank_is_public">{crumbData.is_public == true ? '公开':'私有'}</span>
}
</p>
<span className="bank_is_public">{crumbData.is_public == true ? '公开':'私有'}</span>
</p> }
<Switch {...this.props}>
{/*毕设任务编辑*/}
<Route path='/banks/gtask/:workId/edit'
render={
(props) => {
return (<GtaskBanksEdit {...this.props} {...props} {...this.state} {...common}/>)
}
}></Route>
<Route path='/banks/normal/:workId/edit'
<Route path='/banks/normal/:workId/edit'
render={
(props) => {
return (<HomeworkBanksEdit {...this.props} {...props} {...this.state} {...common}
@ -134,14 +141,7 @@ class BanksIndex extends Component{
}
}></Route>
{/*毕设任务编辑*/}
<Route path='/banks/gtask/:workId/edit'
render={
(props) => {
return (<GtaskBanksEdit {...this.props} {...props} {...this.state} {...common}/>)
}
}></Route>
{/*题库问卷编辑详情*/}
<Route path="/banks/poll/:workid/edit"
render={

@ -1,8 +1,9 @@
import React, { Component } from 'react';
import axios from 'axios'
import NewWorkForm from '../../../courses/busyWork/NewWorkForm';
import NewGtaskForm from './NewGtaskForm';
import NewWorkForm from "./HomeworkBanksEdit";
class GtaskBanksEditEdit extends Component {
class GtaskBanksEdit extends Component {
constructor(props){
super(props);
this.state = {
@ -24,14 +25,13 @@ class GtaskBanksEditEdit extends Component {
title:'编辑',
is_public:result && result.data && result.data.is_public,
crumbArray:[
{to:`/banks/task/${workId}/edit`,content:'详情'},
{to:`/banks/gtask/${workId}/edit`,content:'详情'},
{content:'编辑'}
]
}
this.props.initPublic(crumbData);
result.data.isEdit = true;
result.data.ref_attachments = result.data.reference_attachments
this.setState({ isGroup: result.data.min_num || result.data.max_num })
this.setState({ data:result.data})
this.newWorkFormRef.initValue(result.data);
}
}).catch((error)=>{
@ -69,7 +69,7 @@ class GtaskBanksEditEdit extends Component {
return this.state.isGroup;
}
render(){
let { bankId } = this.props.match.params
const common = {
onCancel:this.onCancel,
isGroup: this.isGroup,
@ -85,15 +85,15 @@ class GtaskBanksEditEdit extends Component {
}
`}
</style>
<NewWorkForm
<NewGtaskForm
{...this.props}
{...this.state}
{...common}
wrappedComponentRef={(ref) => this.newWorkFormRef = ref}
topicId={bankId}
></NewWorkForm>
topicId={this.props.match.params.workId}
></NewGtaskForm>
</div>
)
}
}
export default GtaskBanksEditEdit;
export default GtaskBanksEdit;

@ -0,0 +1,358 @@
import React,{ Component } from "react";
import { Input, InputNumber, Form, Button, Checkbox, Upload, Icon, message, Modal } from "antd";
import axios from 'axios'
import { WordsBtn, getUrl, ConditionToolTip, appendFileSizeToUploadFile, appendFileSizeToUploadFileAll } from 'educoder'
import TPMMDEditor from '../../../tpm/challengesnew/TPMMDEditor';
const MAX_TITLE_LENGTH = 60;
class NewGtaskForms extends Component{
constructor(props){
super(props);
this.contentMdRef = React.createRef();
this.state={
title_num:0,
description:"",
contentFileList: [],
}
}
initValue = (data) => {
if (data.isEdit) {
const contentFileList = data.attachments.map(item => {
return {
id: item.id,
uid: item.id,
name: appendFileSizeToUploadFile(item),
url: item.url,
filesize: item.filesize,
status: 'done'
}
})
this.setState({
...data,
base_on_project: data.group_info.base_on_project,
title_num: parseInt(data.name.length),
min_num: data.group_info.min_number,
max_num: data.group_info.max_number,
contentFileList,
}, () => {
setTimeout(() => {
this.contentMdRef.current.setValue(data.description || '')
}, 2000)
this.props.form.setFieldsValue({
title: data.name,
description: data.description || '',
});
})
} else { // new
}
}
// 输入title
changeTitle=(e)=>{
console.log(e.target.value.length);
this.setState({
title_num: parseInt(e.target.value.length)
})
}
handleContentUploadChange = (info) => {
let contentFileList = info.fileList;
this.setState({ contentFileList: appendFileSizeToUploadFileAll(contentFileList) });
}
deleteAttachment = (file, stateName) => {
// 初次上传不能直接取uid
const url = `/attachments/${file.response ? file.response.id : file.uid}.json`
axios.delete(url, {
})
.then((response) => {
if (response.data) {
const { status } = response.data;
if (status == 0) {
console.log('--- success')
this.setState((state) => {
const index = state[stateName].indexOf(file);
const newFileList = state[stateName].slice();
newFileList.splice(index, 1);
return {
[stateName]: newFileList,
};
});
}
}
})
.catch(function (error) {
console.log(error);
});
}
onAttachmentRemove = (file, stateName) => {
if(file.response!=undefined){
this.props.confirm({
content: '是否确认删除?',
onOk: () => {
this.deleteAttachment(file, stateName)
},
onCancel() {
console.log('Cancel');
},
});
return false;
}
}
handleSubmit = () => {
let {contentFileList,min_num,max_num,base_on_project}=this.state;
let {data}=this.props;
let task_type=data.task_type
let topicId=this.props.topicId
this.props.form.validateFieldsAndScroll((err, values) => {
const mdContnet = this.contentMdRef.current.getValue().trim();
values.description = mdContnet;
if (!err) {
if (this.state.isEdit) {
let url="/task_banks/"+topicId+".json";
axios.put(url, {
gtask_bank: {
name: values.title,
description: values.description,
min_num:task_type===1?undefined:min_num,
max_num:task_type===1?undefined:max_num,
base_on_project: task_type===1?undefined:base_on_project===true?1:0
},
attachment_ids:contentFileList
}
).then((response) => {
if(response.data.status===0){
this.props.showNotification(response.data.message)
}else{
this.props.showNotification(response.data.message)
}
}).catch((error) => {
console.log(error)
})
} else {
}
} else {
$("html").animate({ scrollTop: $('html').scrollTop() - 100 })
}
})
}
max_num_change = (val) => {
if (val < 2) {
this.setState({
max_num: 2,
})
return;
}
const { min_num } = this.state;
this.setState({
max_num: val,
min_num: val <= min_num ? val - 1 : min_num
})
}
min_num_change = (val) => {
this.setState({ min_num: val })
}
base_on_project_change = () => {
this.setState({ base_on_project: !this.state.base_on_project })
}
render(){
const { getFieldDecorator } = this.props.form;
let{
title_value, contentFileList, answerFileList, max_num, min_num, base_on_project,
init_max_num, init_min_num,
title_num, course_name, category, has_commit, has_project,
isEdit
}=this.state
const uploadProps = {
width: 600,
fileList: contentFileList,
multiple: true,
// https://github.com/ant-design/ant-design/issues/15505
// showUploadList={false},然后外部拿到 fileList 数组自行渲染列表。
// showUploadList: false,
action: `${getUrl()}/api/attachments.json`,
onChange: this.handleContentUploadChange,
onRemove: (file) => this.onAttachmentRemove(file, 'contentFileList'),
beforeUpload: (file) => {
console.log('beforeUpload', file.name);
const isLt150M = file.size / 1024 / 1024 < 150;
if (!isLt150M) {
message.error('文件大小必须小于150MB!');
}
return isLt150M;
},
};
return(
<div>
<style>
{
`
.newAboutInputForm.ant-form-item, .newAboutInputForm .ant-form-item{padding:20px 30px 20px 30px!important}
.margin0{margin: 0px!important}
.tasktypes{width:64px;
height:22px;
font-size:16px;
font-family:Microsoft YaHei;
font-weight:400;
line-height:25px;
color:rgba(51,51,51,1);
opacity:1;}
`
}
</style>
<Form className="courseForm">
<div className={"ant-row ant-form-item AboutInputForm newAboutInputForm "}>
<div className="ant-col ant-form-item-label margin0">
<label htmlFor="coursesNew_course" className="ant-form-item-required ">类型</label> <span className={"tasktypes"}>{this.props.data&&this.props.data.task_type===1?"":this.props.data&&this.props.data.task_type===2?"":""}</span>
</div>
</div>
<Form.Item
label="标题"
className="AboutInputForm"
>
{getFieldDecorator('title', {
rules: [{
required: true, message: '请输入标题'
}],
})(
<Input placeholder="请输入毕设任务标题最大限制60个字符"
onInput={this.changeTitle}
className="searchView yslnewworkinputaddonAfter searchViewAfter"
style={{"width":"100%"}}
maxLength={MAX_TITLE_LENGTH} addonAfter={`${String(title_num)}/${MAX_TITLE_LENGTH}`}
/>
)}
</Form.Item>
<style>{`
.uploadBtn.ant-btn {
border: none;
color: #4CACFF;
box-shadow: none;
background: transparent;
padding: 0 6px;
}
.ant-upload-list-item:hover .ant-upload-list-item-info{
background-color:#fff;
}
.upload_1 .ant-upload-list {
width: 350px;
}
.ant-input-number {
height: 40px;
line-height: 40px;
}
.workContent.AboutInputForm.ant-form-item {
border-bottom: none;
padding-bottom: 0px !important;
}
.newWorkUpload {
padding: 0px 30px 30px 30px!important;
background: #fff;
width: 100%;
display: inline-block;
border-bottom: 1px solid #EDEDED;
}
`}</style>
{ <Form.Item
label="内容"
className="AboutInputForm workContent mdInForm"
>
{getFieldDecorator('description', {
rules: [{
required: true, message: '请输入任务内容说明'
}],
})(
<TPMMDEditor ref={this.contentMdRef} placeholder="请输入任务内容说明最大限制5000个字符" mdID={'courseContentMD'} refreshTimeout={1500}
className="courseMessageMD" initValue={this.state.description}></TPMMDEditor>
)}
</Form.Item> }
<Upload {...uploadProps} className="upload_1 newWorkUpload">
<Button className="uploadBtn">
<Icon type="upload" /> 上传附件
</Button>
(单个文件150M以内)
</Upload>
{this.props.data&&this.props.data.task_type===2?
<Form.Item
label="分组设置"
className="AboutInputForm"
>
{getFieldDecorator('personNum', {
rules: [{
required: false
// required: true, message: '请输入最小人数和最大人数'
}],
})(
<div>
<p className="clearfix">
<ConditionToolTip condition={has_commit} title={'已有提交作品,人数范围只能扩大'}>
{/* max={has_commit ? init_min_num : null } */}
每组最小人数<InputNumber placeholder="请填写每组最小人数" min={1} className="winput-240-40 mr10" value={min_num}
onChange={this.min_num_change} style={{width:'180px'}} />
</ConditionToolTip>
<span className="ml15 mr15"></span>
{/* min={has_commit ? init_max_num : (min_num == undefined ? 2 : min_num + 1) } */}
<ConditionToolTip condition={has_commit} title={'已有提交作品,人数范围只能扩大'}>
每组最大人数<InputNumber className="winput-240-40 mr10" placeholder="请填写每组最大人数" value={max_num} max={10}
onChange={this.max_num_change} style={{width:'180px'}} />
</ConditionToolTip>
<div className="color-grey-9 mt20 font-14">学生提交作品时需要关联同组成员组内成员作品共享</div>
</p>
<p className="mt20">
<ConditionToolTip condition={has_commit || has_project} title={'已有关联项目或作品,不能修改'}>
<Checkbox checked={base_on_project} onChange={this.base_on_project_change}
disabled={has_project || has_commit}
className="color-grey-9 font-14"
>基于项目选中则必须在本平台创建项目项目管理员可以提交作品不选中无需在平台创建项目任意小组成员均可以提交作品</Checkbox>
</ConditionToolTip>
</p>
</div>
)}
</Form.Item>:""
}
<Form.Item>
<div className="clearfix mt30 mb30">
{/* htmlType="submit" */}
<Button type="primary" onClick={this.handleSubmit} className="defalutSubmitbtn fl mr20">提交</Button>
<a className="defalutCancelbtn fl" onClick={() => this.props.onCancel()}>取消</ a>
</div>
</Form.Item>
</Form>
</div>
)
}
}
const NewGtaskForm = Form.create({ name: 'NewGtaskForm' })(NewGtaskForms);
export default NewGtaskForm;
Loading…
Cancel
Save