dev_home
cxt 5 years ago
commit 4ff44c382e

@ -0,0 +1,126 @@
$(document).on('turbolinks:load', function() {
if ($('body.admins-laboratory-shixuns-index-page').length > 0) {
var $searchForm = $('.laboratory-shixun-list-form .search-form');
var laboratoryId = $('.laboratory-shixun-list-container').data('id');
$searchForm.find('select#tag_id').select2({
placeholder: "请选择",
allowClear: true
});
// 定义状态切换监听事件
var defineStatusChangeFunc = function (doElement, undoElement, url, callback) {
$('.laboratory-shixun-list-container').on('click', doElement, function () {
var $doAction = $(this);
var $undoAction = $doAction.siblings(undoElement);
var laboratoryShixunId = $doAction.data('id');
customConfirm({
content: '确认进行该操作吗?',
ok: function () {
$.ajax({
url: '/admins/laboratories/' + laboratoryId + '/laboratory_shixuns/' + laboratoryShixunId + url,
method: 'POST',
dataType: 'json',
success: function () {
show_success_flash();
$doAction.hide();
$undoAction.show();
if (callback && typeof callback === "function") {
callback(laboratoryShixunId, url);
}
}
});
}
});
});
}
// 首页展示与取消首页展示
var homepageShowCallback = function (laboratoryShixunId, url) {
var $laboratoryShixunItem = $('.laboratory-shixun-list-container').find('.laboratory-shixun-item-' + laboratoryShixunId);
if (url === '/homepage') {
$laboratoryShixunItem.find('.homepage-badge').show();
} else {
$laboratoryShixunItem.find('.homepage-badge').hide();
}
}
defineStatusChangeFunc('.homepage-show-action', '.homepage-hide-action', '/homepage', homepageShowCallback);
defineStatusChangeFunc('.homepage-hide-action', '.homepage-show-action', '/cancel_homepage', homepageShowCallback);
// 添加实训功能
var $addModal = $('.modal.admin-add-laboratory-shixun-modal');
var $addForm = $addModal.find('form.admin-add-laboratory-user-form');
var $shixunSelect = $addForm.find('select.shixun-select');
$addModal.on('show.bs.modal', function(){
$addModal.find('.error').html('');
$shixunSelect.select2('val', ' ');
});
$shixunSelect.select2({
theme: 'bootstrap4',
placeholder: '请输入实训名称/创建者检索',
multiple: true,
closeOnSelect: false,
ajax: {
delay: 500,
url: '/admins/laboratories/' + laboratoryId + '/shixuns_for_select',
dataType: 'json',
data: function(params){
return { keyword: params.term, page: params.page || 1, per_page: 20 };
},
processResults: function(data, params){
params.page = params.page || 1;
return {
results: data.shixuns,
pagination: {
more: (params.page * 20) < data.count
}
};
}
},
templateResult: function (item) {
if(!item.id || item.id === '') return item.text;
var ele = '<span>'
ele += '<span>' + item.name + '</span>';
ele += '<span class="font-12"> -- ' + item.creator_name + '</span>';
ele += '<span class="font-12"> -- ' + item.status_text+ '</span>';
ele += '</span>';
return $(ele);
},
templateSelection: function(item){
if (item.id) {
}
var ele = '<span>' + (item.name || item.text) + '<span class="font-12"> -- ' + item.creator_name + '</span></span>'
return $(ele);
}
});
$addModal.on('click', '.submit-btn', function(){
$addModal.find('.error').html('');
var shixunIds = $shixunSelect.val();
if (shixunIds && shixunIds.length > 0) {
$.ajax({
method: 'POST',
dataType: 'json',
url: '/admins/laboratories/' + laboratoryId + '/laboratory_shixuns',
data: { shixun_ids: shixunIds },
success: function(){
show_success_flash();
window.location.reload();
},
error: function(res){
$addModal.find('.error').html(res.responseJSON.message);
}
});
} else {
$addModal.find('.error').html('请选择实训');
}
});
}
})

@ -0,0 +1,149 @@
$(document).on('turbolinks:load', function() {
if ($('body.admins-laboratory-subjects-index-page').length > 0) {
var $searchForm = $('.laboratory-subject-list-form .search-form');
var laboratoryId = $('.laboratory-subject-list-container').data('id');
// ************** 学校选择 *************
$searchForm.find('.school-select').select2({
theme: 'bootstrap4',
placeholder: '请选择创建者单位',
allowClear: true,
minimumInputLength: 1,
ajax: {
delay: 500,
url: '/api/schools/search.json',
dataType: 'json',
data: function (params) {
return {keyword: params.term};
},
processResults: function (data) {
return {results: data.schools}
}
},
templateResult: function (item) {
if (!item.id || item.id === '') return item.text;
return item.name;
},
templateSelection: function (item) {
if (item.id) {
}
return item.name || item.text;
}
});
// 定义状态切换监听事件
var defineStatusChangeFunc = function (doElement, undoElement, url, callback) {
$('.laboratory-subject-list-container').on('click', doElement, function () {
var $doAction = $(this);
var $undoAction = $doAction.siblings(undoElement);
var laboratorySubjectId = $doAction.data('id');
customConfirm({
content: '确认进行该操作吗?',
ok: function () {
$.ajax({
url: '/admins/laboratories/' + laboratoryId + '/laboratory_subjects/' + laboratorySubjectId + url,
method: 'POST',
dataType: 'json',
success: function () {
show_success_flash();
$doAction.hide();
$undoAction.show();
if (callback && typeof callback === "function") {
callback(laboratorySubjectId, url);
}
}
});
}
});
});
}
// 首页展示与取消首页展示
var homepageShowCallback = function (laboratoryShixunId, url) {
var $laboratoryShixunItem = $('.laboratory-subject-list-container').find('.laboratory-subject-item-' + laboratoryShixunId);
if (url === '/homepage') {
$laboratoryShixunItem.find('.homepage-badge').show();
} else {
$laboratoryShixunItem.find('.homepage-badge').hide();
}
}
defineStatusChangeFunc('.homepage-show-action', '.homepage-hide-action', '/homepage', homepageShowCallback);
defineStatusChangeFunc('.homepage-hide-action', '.homepage-show-action', '/cancel_homepage', homepageShowCallback);
// 添加实践课程功能
var $addModal = $('.modal.admin-add-laboratory-subject-modal');
var $addForm = $addModal.find('form.admin-add-laboratory-user-form');
var $subjectSelect = $addForm.find('select.subject-select');
$addModal.on('show.bs.modal', function(){
$addModal.find('.error').html('');
$subjectSelect.select2('val', ' ');
});
$subjectSelect.select2({
theme: 'bootstrap4',
placeholder: '请输入课程名称/创建者检索',
multiple: true,
closeOnSelect: false,
ajax: {
delay: 500,
url: '/admins/laboratories/' + laboratoryId + '/subjects_for_select',
dataType: 'json',
data: function(params){
return { keyword: params.term, page: params.page || 1, per_page: 20 }
},
processResults: function(data, params){
params.page = params.page || 1;
return {
results: data.subjects,
pagination: {
more: (params.page * 20) < data.count
}
};
}
},
templateResult: function (item) {
if(!item.id || item.id === '') return item.text;
var ele = '<span>'
ele += '<span>' + item.name + '</span>';
ele += '<span class="font-12"> -- ' + item.creator_name + '</span>';
ele += '<span class="font-12"> -- ' + item.status_text+ '</span>';
ele += '</span>';
return $(ele);
},
templateSelection: function(item){
if (item.id) {
}
var ele = '<span>' + (item.name || item.text) + '<span class="font-12"> -- ' + item.creator_name + '</span></span>'
return $(ele);
}
});
$addModal.on('click', '.submit-btn', function(){
$addModal.find('.error').html('');
var subjectIds = $subjectSelect.val();
if (subjectIds && subjectIds.length > 0) {
$.ajax({
method: 'POST',
dataType: 'json',
url: '/admins/laboratories/' + laboratoryId + '/laboratory_subjects',
data: { subject_ids: subjectIds },
success: function(){
show_success_flash();
window.location.reload();
},
error: function(res){
$addModal.find('.error').html(res.responseJSON.message);
}
});
} else {
$addModal.find('.error').html('请选择课程');
}
});
}
})

@ -0,0 +1,60 @@
$(document).on('turbolinks:load', function() {
if ($('body.cooperative-laboratory-shixuns-index-page').length > 0) {
var $searchForm = $('.laboratory-shixun-list-form .search-form');
$searchForm.find('select#tag_id').select2({
placeholder: "请选择",
allowClear: true
});
// 上传图片
$('.modal.cooperative-upload-file-modal').on('upload:success', function (e, data) {
var $imageElement = $('.shixun-image-' + data.source_id);
if($imageElement.length === 0) return;
$imageElement.attr('src', data.url);
$imageElement.show();
$imageElement.next().html('重新上传');
});
// 定义状态切换监听事件
var defineStatusChangeFunc = function (doElement, undoElement, url, callback) {
$('.laboratory-shixun-list-container').on('click', doElement, function () {
var $doAction = $(this);
var $undoAction = $doAction.siblings(undoElement);
var laboratoryShixunId = $doAction.data('id');
customConfirm({
content: '确认进行该操作吗?',
ok: function () {
$.ajax({
url: '/cooperative/laboratory_shixuns/' + laboratoryShixunId + url,
method: 'POST',
dataType: 'json',
success: function () {
show_success_flash();
$doAction.hide();
$undoAction.show();
if (callback && typeof callback === "function") {
callback(laboratoryShixunId, url);
}
}
});
}
});
});
}
// 首页展示与取消首页展示
var homepageShowCallback = function (laboratoryShixunId, url) {
var $laboratoryShixunItem = $('.laboratory-shixun-list-container').find('.laboratory-shixun-item-' + laboratoryShixunId);
if (url === '/homepage') {
$laboratoryShixunItem.find('.homepage-badge').show();
} else {
$laboratoryShixunItem.find('.homepage-badge').hide();
}
}
defineStatusChangeFunc('.homepage-show-action', '.homepage-hide-action', '/homepage', homepageShowCallback);
defineStatusChangeFunc('.homepage-hide-action', '.homepage-show-action', '/cancel_homepage', homepageShowCallback);
}
})

@ -0,0 +1,83 @@
$(document).on('turbolinks:load', function() {
if ($('body.cooperative-laboratory-subjects-index-page').length > 0) {
var $searchForm = $('.laboratory-subject-list-form .search-form');
// ************** 学校选择 *************
$searchForm.find('.school-select').select2({
theme: 'bootstrap4',
placeholder: '请选择创建者单位',
allowClear: true,
minimumInputLength: 1,
ajax: {
delay: 500,
url: '/api/schools/search.json',
dataType: 'json',
data: function (params) {
return {keyword: params.term};
},
processResults: function (data) {
return {results: data.schools}
}
},
templateResult: function (item) {
if (!item.id || item.id === '') return item.text;
return item.name;
},
templateSelection: function (item) {
if (item.id) {
}
return item.name || item.text;
}
});
// 上传图片
$('.modal.cooperative-upload-file-modal').on('upload:success', function (e, data) {
var $imageElement = $('.subject-image-' + data.source_id);
if($imageElement.length === 0) return;
$imageElement.attr('src', data.url);
$imageElement.show();
$imageElement.next().html('重新上传');
});
// 定义状态切换监听事件
var defineStatusChangeFunc = function (doElement, undoElement, url, callback) {
$('.laboratory-subject-list-container').on('click', doElement, function () {
var $doAction = $(this);
var $undoAction = $doAction.siblings(undoElement);
var laboratorySubjectId = $doAction.data('id');
customConfirm({
content: '确认进行该操作吗?',
ok: function () {
$.ajax({
url: '/cooperative/laboratory_subjects/' + laboratorySubjectId + url,
method: 'POST',
dataType: 'json',
success: function () {
show_success_flash();
$doAction.hide();
$undoAction.show();
if (callback && typeof callback === "function") {
callback(laboratorySubjectId, url);
}
}
});
}
});
});
}
// 首页展示与取消首页展示
var homepageShowCallback = function (laboratoryShixunId, url) {
var $laboratoryShixunItem = $('.laboratory-subject-list-container').find('.laboratory-subject-item-' + laboratoryShixunId);
if (url === '/homepage') {
$laboratoryShixunItem.find('.homepage-badge').show();
} else {
$laboratoryShixunItem.find('.homepage-badge').hide();
}
}
defineStatusChangeFunc('.homepage-show-action', '.homepage-hide-action', '/homepage', homepageShowCallback);
defineStatusChangeFunc('.homepage-hide-action', '.homepage-show-action', '/cancel_homepage', homepageShowCallback);
}
})

@ -0,0 +1,18 @@
$(document).on('turbolinks:load', function () {
$('.cooperative-modal-container').on('show.bs.modal', '.modal.cooperative-edit-subject-modal', function () {
var $modal = $('.modal.cooperative-edit-subject-modal');
var $form = $modal.find('form.cooperative-edit-subject-form');
$modal.on('click', '.submit-btn', function () {
$form.find('.error').html('');
var url = $form.attr('action');
$.ajax({
method: 'PATCH',
dataType: 'script',
url: url,
data: $form.serialize()
});
});
})
});

@ -42,7 +42,7 @@ $(document).on('turbolinks:load', function() {
$.ajax({
method: 'POST',
dataType: 'json',
url: '/cooperatives/files?' + formDataString,
url: '/cooperative/files?' + formDataString,
data: new FormData($form[0]),
processData: false,
contentType: false,

@ -47,6 +47,12 @@
}
}
.image-preview-container {
display: flex;
flex-direction: column;
align-items: center;
}
.action-container {
& > .action {
padding: 0 3px;

@ -47,6 +47,12 @@
}
}
.image-preview-container {
display: flex;
flex-direction: column;
align-items: center;
}
.action-container {
& > .action {
padding: 0 3px;

@ -6,6 +6,7 @@ class Admins::BaseController < ApplicationController
layout 'admin'
skip_before_action :verify_authenticity_token
skip_before_action :setup_laboratory
before_action :require_login, :require_admin!

@ -6,6 +6,16 @@ class Admins::CompetitionPrizeUsersController < Admins::BaseController
include_class = [:competition_team, :competition_prize, :approver,
user: [:process_real_name_apply, :process_professional_apply, user_extension: :school]]
@prize_users = paginate(prize_users.preload(include_class))
respond_to do |format|
format.js
format.html
format.xlsx do
@all_prize_users = prize_users
filename = "#{@competition.name}竞赛获奖人信息列表_#{Time.current.strftime('%Y%m%d%H%M%S')}.xlsx"
render xlsx: 'index', filename: filename
end
end
end
def create

@ -12,10 +12,6 @@ class Admins::EnrollListsController < Admins::BaseController
respond_to do |format|
format.js
format.html
format.xls{
filename = "#{@competition.name}竞赛报名列表_#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}.xls"
send_data(shixun_list_xls(shixuns), :type => 'application/octet-stream', :filename => filename_for_content_disposition(filename))
}
end
end

@ -1,7 +1,6 @@
class Admins::LaboratoriesController < Admins::BaseController
def index
params[:sort_by] = params[:sort_by].presence || 'id'
params[:sort_direction] = params[:sort_direction].presence || 'desc'
default_sort('id', 'desc')
laboratories = Admins::LaboratoryQuery.call(params)
@laboratories = paginate laboratories.preload(:school, :laboratory_users)
@ -20,6 +19,37 @@ class Admins::LaboratoriesController < Admins::BaseController
render_delete_success
end
def shixuns_for_select
except_shixun_ids = current_laboratory.laboratory_shixuns.pluck(:shixun_id)
shixuns = Shixun.where.not(id: except_shixun_ids)
keyword = params[:keyword].to_s.strip
if keyword.present?
like_sql = 'shixuns.name LIKE :keyword OR CONCAT(users.lastname, users.firstname) LIKE :keyword '\
'OR mirror_repositories.name LIKE :keyword'
shixuns = shixuns.joins(:user, :mirror_repositories).where(like_sql, keyword: "%#{keyword}%")
end
@count = shixuns.count
@shixuns = paginate(shixuns.includes(:user))
end
def subjects_for_select
except_subject_ids = current_laboratory.laboratory_subjects.pluck(:subject_id)
subjects = Subject.where.not(id: except_subject_ids)
keyword = params[:keyword].to_s.strip
if keyword.present?
like_sql = 'subjects.name LIKE :keyword OR CONCAT(users.lastname, users.firstname) LIKE :keyword'
subjects = subjects.joins(:user).where(like_sql, keyword: "%#{keyword}%")
end
@count = subjects.count
@subjects = paginate(subjects.includes(:user))
end
private
def current_laboratory

@ -0,0 +1,41 @@
class Admins::LaboratoryShixunsController < Admins::BaseController
helper_method :current_laboratory, :current_laboratory_shixun
def index
laboratory_shixuns = Admins::LaboratoryShixunQuery.call(current_laboratory, params)
@laboratory_shixuns = paginate laboratory_shixuns.includes(shixun: %i[tag_repertoires user])
end
def create
shixun_ids = Array.wrap(params[:shixun_ids])
shixun_ids = Shixun.where(id: shixun_ids).pluck(:id)
exist_shixun_id = current_laboratory.laboratory_shixuns.where(shixun_id: shixun_ids).pluck(:shixun_id)
LaboratoryShixun.bulk_insert(*%i[shixun_id laboratory_id created_at updated_at]) do |worker|
(shixun_ids - exist_shixun_id).each do |shixun_id|
worker.add(shixun_id: shixun_id, laboratory_id: current_laboratory.id)
end
end
render_ok
end
def homepage
current_laboratory_shixun.update!(homepage: true)
render_ok
end
def cancel_homepage
current_laboratory_shixun.update!(homepage: false)
render_ok
end
private
def current_laboratory
@_current_laboratory ||= Laboratory.find(params[:laboratory_id])
end
def current_laboratory_shixun
@_current_laboratory_shixun ||= current_laboratory.laboratory_shixuns.find(params[:id])
end
end

@ -0,0 +1,43 @@
class Admins::LaboratorySubjectsController < Admins::BaseController
helper_method :current_laboratory, :current_laboratory_subject
def index
laboratory_subjects = Admins::LaboratorySubjectQuery.call(current_laboratory, params)
includes_tables = { subject: [:repertoire, :subject_level_system, user: {user_extension: :school}] }
@laboratory_subjects = paginate(laboratory_subjects.includes(includes_tables))
end
def create
subject_ids = Array.wrap(params[:subject_ids])
subject_ids = Subject.where(id: subject_ids).pluck(:id)
exist_subject_id = current_laboratory.laboratory_subjects.where(subject_id: subject_ids).pluck(:subject_id)
LaboratorySubject.bulk_insert(*%i[subject_id laboratory_id created_at updated_at]) do |worker|
(subject_ids - exist_subject_id).each do |subject_id|
worker.add(subject_id: subject_id, laboratory_id: current_laboratory.id)
end
end
render_ok
end
def homepage
current_laboratory_subject.update!(homepage: true)
render_ok
end
def cancel_homepage
current_laboratory_subject.update!(homepage: false)
render_ok
end
private
def current_laboratory
@_current_laboratory ||= Laboratory.find(params[:laboratory_id])
end
def current_laboratory_subject
@_current_laboratory_subject ||= current_laboratory.laboratory_subjects.find(params[:id])
end
end

@ -8,6 +8,7 @@ module Base::RenderHelper
def render_forbidden
render_by_format(html: -> { current_user&.business? ? render('shared/403') : redirect_to('/403') },
js: -> { render_js_error(I18n.t('error.forbidden'), type: :notify) },
json: -> { render status: 403, json: { messages: I18n.t('error.forbidden') } } )
end

@ -2,6 +2,8 @@ module LaboratoryHelper
extend ActiveSupport::Concern
included do
before_action :setup_laboratory
helper_method :current_laboratory
helper_method :default_setting
end
@ -17,4 +19,8 @@ module LaboratoryHelper
def default_setting
@_default_setting ||= LaboratorySetting.find_by(laboratory_id: 1)
end
def setup_laboratory
Laboratory.current = current_laboratory
end
end

@ -1,5 +1,5 @@
class Cooperative::FilesController < Cooperative::BaseController
before_action :convert_file!, only: [:create]
before_action :convert_file!, :check_permission!, only: [:create]
def create
File.delete(file_path) if File.exist?(file_path) # 删除之前的文件
@ -29,6 +29,22 @@ class Cooperative::FilesController < Cooperative::BaseController
render_error(ex.message)
end
def check_permission!
permission =
case params[:source_type].to_s
when '' then false
when 'Shixun' then
current_laboratory.laboratory_shixuns.exists?(ownership: true, shixun_id: params[:source_id])
when 'Subject' then
current_laboratory.laboratory_subjects.exists?(ownership: true, subject_id: params[:source_id])
else true
end
return if permission
render_forbidden
end
def file_path
@_file_path ||= begin
case params[:source_type].to_s

@ -0,0 +1,39 @@
class Cooperative::LaboratoryShixunsController < Cooperative::BaseController
before_action :check_shixun_ownership!, only: [:edit, :update]
helper_method :current_laboratory_shixun
def index
laboratory_shixuns = Admins::LaboratoryShixunQuery.call(current_laboratory, params)
@laboratory_shixuns = paginate laboratory_shixuns.includes(shixun: %i[tag_repertoires user])
end
def edit
end
def update
end
def homepage
current_laboratory_shixun.update!(homepage: true)
render_ok
end
def cancel_homepage
current_laboratory_shixun.update!(homepage: false)
render_ok
end
private
def current_laboratory_shixun
@_current_laboratory_shixun ||= current_laboratory.laboratory_shixuns.find(params[:id])
end
def check_shixun_ownership!
return if current_laboratory_shixun.ownership?
render_forbidden
end
end

@ -0,0 +1,46 @@
class Cooperative::LaboratorySubjectsController < Cooperative::BaseController
before_action :check_subject_ownership!, only: [:edit, :update]
helper_method :current_laboratory_subject
def index
laboratory_subjects = Admins::LaboratorySubjectQuery.call(current_laboratory, params)
includes_tables = { subject: [:repertoire, :subject_level_system, user: {user_extension: :school}] }
@laboratory_subjects = paginate(laboratory_subjects.includes(includes_tables))
end
def edit
@laboratory_subject = current_laboratory_subject
end
def update
current_laboratory_subject.subject.update!(update_params)
end
def homepage
current_laboratory_subject.update!(homepage: true)
render_ok
end
def cancel_homepage
current_laboratory_subject.update!(homepage: false)
render_ok
end
private
def current_laboratory_subject
@_current_laboratory_subject ||= current_laboratory.laboratory_subjects.find(params[:id])
end
def check_subject_ownership!
return if current_laboratory_subject.ownership?
render_forbidden
end
def update_params
params.require(:laboratory_subject).permit(:repertoire_id, :subject_level_system_id)
end
end

@ -18,7 +18,7 @@ class CoursesController < ApplicationController
:left_banner, :top_banner, :apply_to_join_course, :exit_course, :course_groups]
before_action :set_course, only: [:show, :update, :destroy, :settings, :set_invite_code_halt,
:set_public_or_private, :search_teacher_candidate, :teachers, :apply_teachers,
:top_banner, :left_banner, :add_teacher_popup, :add_teacher,
:top_banner, :left_banner, :add_teacher_popup, :add_teacher, :inform_up, :inform_down,
:graduation_group_list, :create_graduation_group, :join_graduation_group,
:course_group_list, :set_course_group, :change_course_admin, :change_course_teacher,
:delete_course_teacher, :teacher_application_review, :students, :all_course_groups,
@ -41,7 +41,7 @@ class CoursesController < ApplicationController
:set_course_group, :create_group_by_importing_file,
:update_task_position, :tasks_list]
before_action :teacher_or_admin_allowed, only: [:graduation_group_list, :create_graduation_group, :join_graduation_group,
:change_course_teacher, :course_group_list, :change_member_role,
:change_course_teacher, :course_group_list, :change_member_role,:inform_up, :inform_down,
:teacher_application_review, :apply_teachers, :delete_course_teacher]
before_action :validate_course_name, only: [:create, :update]
before_action :find_board, only: :board_list
@ -281,13 +281,43 @@ class CoursesController < ApplicationController
end
def informs
@informs = @course.informs
@informs = @course.informs.order("position desc")
end
def inform_up
inform = @course.informs.find_by(id: params[:inform_id])
next_inform = inform.next_inform
ActiveRecord::Base.transaction do
if next_inform.blank?
render_error('已经到达最顶部')
else
inform.update_attribute(:position, (inform.position + 1))
next_inform.update_attribute(:position, inform.position - 1)
render_ok
end
end
end
def inform_down
inform = @course.informs.find_by(id: params[:inform_id])
last_inform = inform.last_inform
ActiveRecord::Base.transaction do
if last_inform.blank?
render_error('已经到达最底部')
else
inform.update_attribute(:position, (inform.position - 1))
last_inform.update_attribute(:position, inform.position + 1)
render_ok
end
end
end
def new_informs
inform = Inform.new(container: @course)
inform.name = params[:name]
inform.description = params[:description]
inform.position = @course.informs.maximum(:position).to_i + 1
inform.save!
normal_status("创建成功")
end
@ -300,6 +330,7 @@ class CoursesController < ApplicationController
def delete_informs
inform = @course.informs.find_by(id: params[:inform_id])
@course.informs.where("position > ?", inform.position).update_all("position = position - 1")
inform.destroy!
normal_status("删除成功")
end
@ -1110,7 +1141,7 @@ class CoursesController < ApplicationController
# 如果在该课堂已经存在学生身份,且邀请码为分班邀请码,则将其直接加入分班
existing_student.update_attributes(course_group_id: course_group.id) if course_group.present?
else
correspond_teacher_exist = current_user.teacher_of_course? course
correspond_teacher_exist = current_user.none_admin_teacher_of_course? course
new_student = CourseMember.new(user_id: current_user.id, course_id: course.id, role: 4)
new_student.is_active = 0 if correspond_teacher_exist

@ -514,6 +514,9 @@ class ExercisesController < ApplicationController
if exercise_group.present? && (exercise_group.first.publish_time < Time.now) && (exercise_publish_time != exercise_group.first.publish_time)
error_count += 1
end
if exercise_group.present? && (exercise_group.first.publish_time < Time.now && exercise_group.first.end_time > Time.now) && (exercise_end_time < Time.now)
error_count += 1
end
if error_count == 0
common_group = exercise_groups_ids & course_id #传入的班级与问卷已存在的班级的交集,即表示已有分班的
new_group_ids = course_id - common_group #新传入的班级id
@ -529,12 +532,12 @@ class ExercisesController < ApplicationController
if the_group_setting_status == 2
ex_group_params = {
:publish_time => the_group_setting.publish_time,
:end_time => exercise_end_time
:end_time => exercise_end_time < Time.now ? the_group_setting.end_time : exercise_end_time
}
elsif the_group_setting_status == 3
ex_group_params = {
:publish_time => the_group_setting.publish_time,
:end_time => the_group_setting.end_time
:end_time => exercise_end_time
}
end
the_group_setting.update_attributes!(ex_group_params)
@ -558,7 +561,7 @@ class ExercisesController < ApplicationController
if error_count > 0
error_count == 0
normal_status(-1,"已发布/已截止的试卷不允许修改时间")
normal_status(-1,"试卷发布/截止时间不能小于当前时间")
else
# 未发布的分班设置才能删除
if old_exercise_groups.size > 0
@ -609,13 +612,27 @@ class ExercisesController < ApplicationController
def adjust_score
exercise_user = @exercise.exercise_users.find_by!(user_id: params[:user_id])
tip_exception("已提交的作品请去评阅页进行调分") if exercise_user.commit_status == 1
tip_exception("分数不能为空") if params[:score].blank?
tip_exception("分数不能超过0-#{@exercise.question_scores}") if params[:score].to_f < 0 || params[:score].to_f.round(1) > @exercise.question_scores.round(1)
if @exercise.subjective_score > 0
tip_exception("主观题成绩不能为空") if params[:subject_score].blank?
tip_exception("主观题成绩不能小于零") if params[:subject_score].to_f < 0
tip_exception("主观题成绩不能大于总分值:#{@exercise.subjective_score}") if params[:subject_score].to_f.round(1) > @exercise.subjective_score.round(1)
end
if @exercise.objective_score > 0
tip_exception("客观题成绩不能为空") if params[:objective_score].blank?
tip_exception("客观题成绩不能小于零") if params[:objective_score].to_f < 0
tip_exception("客观题成绩不能大于总分值:#{@exercise.objective_score}") if params[:objective_score].to_f.round(1) > @exercise.objective_score.round(1)
end
ActiveRecord::Base.transaction do
start_at_time = exercise_user.start_at || Time.now
exercise_user.update_attributes!(start_at: start_at_time, end_at: Time.now, status: 1, commit_status: 1, score: params[:score].to_f.round(2), commit_method: 5)
ExerciseUserScore.create!(exercise_id: @exercise.id, exercise_user_id: exercise_user.id, score: params[:score], comment: params[:comment])
subjective_score = @exercise.subjective_score > 0 ? params[:subject_score].to_f.round(2) : 0
objective_score = @exercise.objective_score > 0 ? params[:objective_score].to_f.round(2) : 0
score = subjective_score + objective_score
exercise_user.update_attributes!(start_at: start_at_time, end_at: Time.now, status: 1, commit_status: 1, score: score,
subjective_score: subjective_score, objective_score: objective_score, commit_method: 5)
ExerciseUserScore.create!(exercise_id: @exercise.id, exercise_user_id: exercise_user.id,
subjective_score: subjective_score, objective_score: objective_score)
normal_status("操作成功")
end
end

@ -149,6 +149,7 @@ class GraduationTasksController < ApplicationController
else
respond_to do |format|
format.xlsx{
set_export_cookies
graduation_work_to_xlsx(@work_excel,@task,current_user)
task_export_name_ = "#{current_user.real_name}_#{@course.name}_#{@task.name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}"
render xlsx: "#{task_export_name_.strip}",template: "graduation_tasks/tasks_list.xlsx.axlsx",locals: {table_columns:@head_cells_column, task_users:@task_cells_column}

@ -379,8 +379,9 @@ class GraduationWorksController < ApplicationController
end
def adjust_score
tip_exception("分数不能为空") if params[:score].blank?
tip_exception("分数不能超过0-100") if params[:score].to_f < 0 || params[:score].to_f > 100
tip_exception("成绩不能为空") if params[:score].blank?
tip_exception("成绩不能小于零") if params[:score].to_f < 0
tip_exception("成绩不能大于100") if params[:score].to_f.round(1) > 100
ActiveRecord::Base.transaction do
begin
# 分数不为空的历史评阅都置为失效

@ -26,12 +26,27 @@ class HomeController < ApplicationController
@rep_list << {rep_id: rep.id, rep_name: rep.name, sub_rep_list: sub_rep_list}
end
@shixuns = Shixun.where(homepage_show: 1).includes(:tag_repertoires, :challenges).limit(8)
shixuns = current_laboratory.shixuns
subjects = current_laboratory.subjects
if current_laboratory.main_site?
shixuns = shixuns.where(homepage_show: true)
subjects = subjects.where(homepage_show: true)
else
shixuns = shixuns.where(laboratory_shixuns: { homepage: true })
subjects = subjects.where(laboratory_subjects: { homepage: true })
end
@shixuns = shixuns.includes(:tag_repertoires, :challenges).limit(8)
@subjects = subjects.includes(:repertoire, :shixuns).limit(8)
@subjects = Subject.where(homepage_show: 1).includes(:shixuns, :repertoire).limit(8)
@main_shixuns = Shixun.where(homepage_show: true).includes(:tag_repertoires, :challenges).limit(8)
@main_subjects = Subject.where(homepage_show: true).includes(:shixuns, :repertoire).limit(8)
@tea_users = User.where(homepage_teacher: 1).includes(:user_extension).limit(10).order("experience desc")
@stu_users = User.where(is_test: 0).includes(:user_extension).where(user_extensions: {identity: 1}).limit(10).order("experience desc")
if current_laboratory.main_site?
@tea_users = User.where(homepage_teacher: 1).includes(:user_extension).limit(10).order("experience desc")
@stu_users = User.where(is_test: 0).includes(:user_extension).where(user_extensions: {identity: 1}).limit(10).order("experience desc")
end
end
def search

@ -160,7 +160,7 @@ class HomeworkCommonsController < ApplicationController
# 作品状态 0 未提交, 1 按时提交, 2 延迟提交
if params[:work_status].present?
params_work_status = request.get? ? params[:work_status].split(",") : params[:work_status]
params_work_status = params[:work_status]
work_status = params_work_status.map{|status| status.to_i}
all_student_works = @student_works.left_joins(:myshixun)
@student_works = all_student_works.where(work_status: work_status)
@ -171,7 +171,7 @@ class HomeworkCommonsController < ApplicationController
# 分班情况
unless params[:course_group].blank?
group_ids = request.get? ? params[:course_group].split(",") : params[:course_group]
group_ids = params[:course_group]
group_user_ids = @course.students.where(course_group_id: group_ids).pluck(:user_id)
# 有分组只可能是老师身份查看列表
@student_works = @student_works.where(user_id: group_user_ids)
@ -179,9 +179,9 @@ class HomeworkCommonsController < ApplicationController
if @homework.homework_type == "group" && !params[:member_work].blank?
if params[:member_work].to_i == 1
@student_works = @student_works.where("user_id = commit_user_id")
@student_works = @student_works.where("student_works.user_id = commit_user_id")
elsif params[:member_work].to_i == 0
@student_works = @student_works.where("user_id != commit_user_id")
@student_works = @student_works.where("student_works.user_id != commit_user_id")
end
end
@ -1512,7 +1512,7 @@ class HomeworkCommonsController < ApplicationController
end_time = game.end_time
# 用户关卡的得分
all_score = homework_challenge_settings.find_by(challenge_id: challenge.id).try(:score).to_f
final_score = @student_work.work_challenge_score game, all_score
final_score = @student_work.work_challenge_score game, all_score, challenge.id
# 抄袭用户
copy_user = User.find_by_id(game_codes[0].try(:target_user_id))
copy_end_time = copy_user.games.find_by(challenge_id: challenge.id).try(:end_time) if copy_user.present?

@ -103,14 +103,19 @@ class MessagesController < ApplicationController
return normal_status(403, "您没有权限进行该操作") if current_user != @message.author && !current_user.teacher_of_course?(@message.board.course)
begin
h = {is_md: true}
board = @message.board&.course&.boards.find_by!(id: params[:select_board_id])
email_notify = @message.email_notify ? 1 : @message.board&.course.email_notify && params[:email_notify]
send_email = !@message.email_notify && email_notify
h = {is_md: true, email_notify: email_notify, board_id: board&.id}
m_params = message_params.merge(h)
@message.update_attributes(m_params)
Attachment.associate_container(params[:attachment_ids], @message.id, @message.class.name)
@message.update_content(params[:content])
notify_course_students(@message, @message.board&.course) if send_email
rescue Exception => e
uid_logger_error(e.message)
tip_exception("修改失败")
tip_exception(e.message)
raise ActiveRecord::Rollback
end
end
@ -123,6 +128,7 @@ class MessagesController < ApplicationController
@message.author = current_user
@message.board_id = params[:select_board_id]
@message.message_detail_attributes = {content: params[:content]}
@message.email_notify = @board.course.email_notify && params[:email_notify] ? 1 : 0
@message.save!
Attachment.associate_container(params[:attachment_ids], @message.id, @message.class.name)
if @board.course.email_notify && params[:email_notify]
@ -189,7 +195,7 @@ class MessagesController < ApplicationController
private
def validate_sort_type
normal_status(2, "参数sort_tyope暂时只支持 'time', 'hot'两种") if params.has_key?(:sort_type) && !SORT_TYPE.include?(params[:sort_type].strip)
normal_status(2, "参数sort_type暂时只支持 'time', 'hot'两种") if params.has_key?(:sort_type) && !SORT_TYPE.include?(params[:sort_type].strip)
end
def find_message
@ -207,7 +213,7 @@ class MessagesController < ApplicationController
def notify_course_students message, course
course.students.includes(:user).each do |student|
UserMailer.course_message_email(student&.user&.mail, message.id).deliver_now if student&.user&.mail
UserMailer.course_message_email(student&.user&.mail, message.id).deliver_later if student&.user&.mail
end
end
end

@ -33,7 +33,12 @@ class ShixunsController < ApplicationController
current_user.my_shixuns
else
Shixun.unhidden
end
end
## 云上实验室过滤
unless current_laboratory.main_site?
@shixuns = @shixuns.joins(:laboratory_shixuns).where(laboratory_shixuns: { laboratory_id: current_laboratory.id })
end
## 方向
if params[:tag_level].present? && params[:tag_id].present?
@ -335,6 +340,9 @@ class ShixunsController < ApplicationController
end
end
end
# 将实训标志为该云上实验室建立
Laboratory.current.laboratory_shixuns.create!(shixun: @shixun, ownership: true)
rescue Exception => e
uid_logger_error("copy shixun failed ##{e.message}")
# 删除版本库
@ -430,6 +438,9 @@ class ShixunsController < ApplicationController
GitService.add_repository(repo_path: repo_path)
# todo: 为什么保存的时候要去除后面的.git呢??
@shixun.update_column(:repo_name, repo_path.split(".")[0])
# 将实训标志为该云上实验室建立
Laboratory.current.laboratory_shixuns.create!(shixun: @shixun, ownership: true)
rescue Exception => e
uid_logger_error(e.message)
tip_exception("实训创建失败")

@ -464,6 +464,7 @@ class StudentWorksController < ApplicationController
@shixun = @homework.shixuns.take
# 提示: 这里如果includes outputs表的话 sum(:evaluate_count)会出现错误
@games = @work.myshixun.games.joins(:challenge).reorder("challenges.position asc") if @work.myshixun
@challenges = @shixun.challenges if @shixun
@comment = @work.shixun_work_comments.find_by(challenge_id: 0)
# 用户最大评测次数
@ -475,7 +476,7 @@ class StudentWorksController < ApplicationController
end
# 图形效率图的数据
@echart_data = student_efficiency(@homework, @work)
@echart_data = student_efficiency(@homework, @work) if @work.myshixun
end
# 实训作品的评阅
@ -493,6 +494,9 @@ class StudentWorksController < ApplicationController
@comment.comment = params[:comment]
@comment.hidden_comment = params[:hidden_comment]
@comment.save!
if @work.work_status == 0
@work.update_attributes!(work_status: 1, commit_time: @homework.end_time, update_time: Time.now, work_score: 0, final_score: 0)
end
end
end
@ -517,6 +521,7 @@ class StudentWorksController < ApplicationController
@user = @work.user
@shixun = @homework.shixuns.take
@games = @work.myshixun.games.includes(:challenge, :game_codes, :outputs) if @work.myshixun
@challenges = @shixun.challenges if @shixun
# 用户最大评测次数
@user_evaluate_count = @games.pluck(:evaluate_count).sum if @games
@ -524,19 +529,23 @@ class StudentWorksController < ApplicationController
@echart_data = student_efficiency(@homework, @work)
@myself_eff = @echart_data[:efficiency_list].find { |item| item.last == @user.id }
@myself_consume = @echart_data[:consume_list].find { |item| item.last == @user.id }
filename_ = "#{@use&.student_id}_#{@use&.real_name}_#{@shixun&.name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}"
filename = Base64.urlsafe_encode64(filename_.strip)
stylesheets = %w(shixun_work/shixun_work.css shared/codemirror.css)
render pdf: 'shixun_work/shixun_work', filename: filename, stylesheets: stylesheets, disposition: 'inline', type:"pdf_attachment.content_type",stream:false
if params[:export].present? && params[:export]
normal_status(0,"正在下载中")
else
set_export_cookies
render pdf: 'shixun_work/shixun_work', filename: filename, stylesheets: stylesheets, disposition: 'inline', type:"pdf_attachment.content_type",stream:false
end
# render pdf: 'shixun_work/shixun_work', filename: filename, stylesheets: stylesheets, disposition: 'inline', type:"pdf_attachment.content_type",stream:false
end
# 作品调分
def adjust_score
tip_exception("分数不能为空") if params[:score].blank?
tip_exception("分数不能超过0-100") if @homework.homework_type != "practice" && (params[:score].to_f < 0 || params[:score].to_f.round(1) > 100.round(1))
tip_exception("已提交的作品请去评阅页进行调分") if @homework.homework_type == "practice" && @work.work_status > 0
tip_exception("分数不能超过总分值#{@homework.total_score}") if @homework.homework_type == "practice" && (params[:score].to_f < 0 || params[:score].to_f.round(1) > @homework.total_score.round(1))
tip_exception("成绩不能为空") if params[:score].blank?
tip_exception("成绩不能小于零") if params[:score].to_f < 0
tip_exception("成绩不能大于100") if params[:score].to_f.round(1) > 100
ActiveRecord::Base.transaction do
begin
# 分数不为空的历史评阅都置为失效
@ -713,27 +722,35 @@ class StudentWorksController < ApplicationController
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].to_i < 0
tip_exception("不能大于关卡分值:#{challenge_setting.score}") if challenge_setting.score < params[:score].to_i
if challenge_setting
challenge = challenge_setting&.challenge
tip_exception("不能小于零") if params[:score].to_i < 0
tip_exception("不能大于关卡分值:#{challenge_setting.score}") if challenge_setting && challenge_setting.score < params[:score].to_i
ActiveRecord::Base.transaction do
begin
if params[:type] == "review"
copy_user = User.find params[:copy_user_id]
comment = "代码查重结果显示与#{copy_user.try(:show_real_name)}的代码相似度#{params[:code_rate]}%"
else
comment = "根据实训报告中最终提交的代码调整第#{challenge.position}关分数"
ActiveRecord::Base.transaction do
begin
if params[:type] == "review"
copy_user = User.find params[:copy_user_id]
comment = "代码查重结果显示与#{copy_user.try(:show_real_name)}的代码相似度#{params[:code_rate]}%"
else
comment = "根据实训报告中最终提交的代码调整第#{challenge.position}关分数"
end
challenge_score = @work.challenge_work_scores.create(challenge_id: params[:challenge_id], user_id: current_user.id, score: params[:score],
comment: comment)
challenge_score.create_tiding current_user.id
if @work.work_status != 0 && @work.myshixun
HomeworksService.new.update_myshixun_work_score @work, @work.myshixun, @work.myshixun&.games, @homework, @homework.homework_challenge_settings
else
update_none_commit_work @work, @homework
end
rescue Exception => e
uid_logger(e.message)
tip_exception("调分失败")
raise ActiveRecord::Rollback
end
challenge_score = @work.challenge_work_scores.create(challenge_id: params[:challenge_id], user_id: current_user.id, score: params[:score],
comment: comment)
challenge_score.create_tiding current_user.id
HomeworksService.new.update_myshixun_work_score @work, @work&.myshixun, @work&.myshixun&.games, @homework, @homework.homework_challenge_settings
rescue Exception => e
uid_logger(e.message)
tip_exception(e.message)
raise ActiveRecord::Rollback
end
else
tip_exception("该关卡不记分")
end
end
@ -856,4 +873,20 @@ class StudentWorksController < ApplicationController
end
end
end
def update_none_commit_work work, homework
if work.work_status == 0
work.work_status = 1
work.commit_time = homework.end_time
work.update_time = Time.now
end
final_score = 0
homework.homework_challenge_settings.each do |cha_setting|
adjust_score = work.challenge_work_scores.select{|work_score| work_score.challenge_id == cha_setting.challenge_id}.last
final_score += adjust_score.score if adjust_score.present?
end
work.final_score = final_score
work.work_score = final_score
work.save!
end
end

@ -23,16 +23,17 @@ class SubjectsController < ApplicationController
# 最热排序
if reorder == "myshixun_count"
laboratory_join = current_laboratory.main_site? ? '' : " JOIN laboratory_subjects ls ON ls.subject_id = subjects.id AND ls.laboratory_id = #{current_laboratory.id} "
if select
@subjects = Subject.find_by_sql("SELECT subjects.id, subjects.user_id, subjects.name, subjects.stages_count, subjects.repertoire_id, subjects.status,
subjects.shixuns_count, subjects.excellent, sum(shixuns.myshixuns_count) AS myshixun_member_count FROM subjects join stage_shixuns
on stage_shixuns.subject_id = subjects.id join shixuns on shixuns.id = stage_shixuns.shixun_id where
on stage_shixuns.subject_id = subjects.id join shixuns on shixuns.id = stage_shixuns.shixun_id #{laboratory_join} where
subjects.hidden = 0 AND subjects.status = 2 AND subjects.name like '%#{search}%'
AND subjects.repertoire_id = #{select} GROUP BY subjects.id ORDER BY myshixun_member_count DESC")
else
@subjects = Subject.find_by_sql("SELECT subjects.id, subjects.user_id, subjects.name, subjects.stages_count, subjects.repertoire_id, subjects.status,
subjects.shixuns_count, subjects.excellent, sum(shixuns.myshixuns_count) AS myshixun_member_count FROM subjects join stage_shixuns
on stage_shixuns.subject_id = subjects.id join shixuns on shixuns.id = stage_shixuns.shixun_id where
on stage_shixuns.subject_id = subjects.id join shixuns on shixuns.id = stage_shixuns.shixun_id #{laboratory_join} where
subjects.hidden = 0 AND subjects.status = 2 AND subjects.name like '%#{search}%'
GROUP BY subjects.id ORDER BY myshixun_member_count DESC")
end
@ -52,6 +53,11 @@ class SubjectsController < ApplicationController
@subjects = Subject.visible.unhidden
end
# 云上实验室过滤
unless current_laboratory.main_site?
@subjects = @subjects.joins(:laboratory_subjects).where(laboratory_subjects: { laboratory_id: current_laboratory.id })
end
# 类型
if select
@subjects = @subjects.where(repertoire_id: select)
@ -117,6 +123,9 @@ class SubjectsController < ApplicationController
@subject.user_id = current_user.id
@subject.save!
@subject.subject_members.create!(role: 1, user_id: current_user.id)
# 将实践课程标记为该云上实验室建立
Laboratory.current.laboratory_subjects.create!(subject: @subject, ownership: true)
rescue Exception => e
uid_logger_error(e.message)
tip_exception("实训路径创建失败")

@ -1,5 +1,5 @@
class TrustieHacksController < ApplicationController
before_action :require_admin, :except => [:index]
before_action :require_admin, :except => [:index, :entry]
before_action :require_login, :except => [:index]
before_action :find_hackathon
before_action :find_hack, :except => [:create, :index, :edit_hackathon, :update_hackathon]
@ -15,7 +15,7 @@ class TrustieHacksController < ApplicationController
hacks = hacks.where("name like ?", "%#{search}%")
end
@hackathon_users_count = hacks ? 0 : hacks.sum(:hack_users_count)
@hackathon_users_count = hacks.blank? ? 0 : hacks.sum(:hack_users_count)
@hacks_count = hacks.count
@hacks = hacks.page(page).per(limit)
@ -49,10 +49,10 @@ class TrustieHacksController < ApplicationController
# 报名入口
def entry
if @hack.hack_users.exists?(user_id: current_user)
if @hack.hack_users.exists?(user_id: current_user.id)
render_error('已经报名,请勿重复操作')
else
@hack.hack_users.create(user_id: current_user)
@hack.hack_users.create(user_id: current_user.id)
render_ok
end
end

@ -414,6 +414,14 @@ module ApplicationHelper
m_t&.include?("src=\"") ? m_t&.gsub("src=\"","src=\"#{origin_url}") : m_t
end
def shixun_status_class(shixun)
case shixun.status
when 0 then 'text-info'
when 1 then 'text-warning'
when 2 then 'text-success'
when 3 then 'text-secondary'
end
end
end

@ -19,7 +19,7 @@ module StudentWorksHelper
# 作业的开启时间
def myshixun_open_time game
game.open_time ? (format_time game.open_time) : "--"
game&.open_time ? (format_time game.open_time) : "--"
end
# 作业完成时间
@ -29,7 +29,7 @@ module StudentWorksHelper
# 作业耗时
def time_consuming game
game.end_time.blank? ? "--" : (game_spend_time game.cost_time)
game&.end_time.blank? ? "--" : (game_spend_time game.cost_time)
end
# 用户个人实训总得分user_total_score

@ -12,6 +12,6 @@ class UserMailer < ApplicationMailer
def course_message_email(mail, message_id)
@message = Message.find_by(id: message_id)
@course = @message&.board&.course
mail(to: mail, subject: '课堂通知') if @message.present? && @course.present?
mail(to: mail, subject: '课堂发布了新的帖子') if @message.present? && @course.present?
end
end

@ -41,6 +41,14 @@ class Exercise < ApplicationRecord
exercise_questions.pluck(:question_score).sum
end
def subjective_score
exercise_questions.where(question_type: [4]).pluck(:question_score).sum
end
def objective_score
exercise_questions.where(question_type: [0, 1, 2, 3, 5]).pluck(:question_score).sum
end
def create_exercise_list
str = ""
# TODO: 一次性为所有学生创建数据是否存在问题?

@ -5,4 +5,13 @@ class Inform < ApplicationRecord
validates :description, length: { maximum: 5000 }
has_many :attachments, as: :container, dependent: :destroy
def next_inform
Inform.find_by(position: self.position+1, container_id: self.container_id, container_type: self.container_type)
end
def last_inform
Inform.find_by(position: self.position-1, container_id: self.container_id, container_type: self.container_type)
end
end

@ -8,6 +8,9 @@ class Laboratory < ApplicationRecord
has_many :portal_images, dependent: :destroy
has_many :laboratory_shixuns, dependent: :destroy
has_many :laboratory_subjects, dependent: :destroy
validates :identifier, uniqueness: { case_sensitive: false }, allow_nil: true
delegate :name, :navbar, :footer, :login_logo_url, :nav_logo_url, :tab_logo_url, :default_navbar, to: :laboratory_setting
@ -27,4 +30,25 @@ class Laboratory < ApplicationRecord
find_by_identifier(subdomain)
end
def self.current=(laboratory)
Thread.current[:current_laboratory] = laboratory
end
def self.current
Thread.current[:current_laboratory] ||= Laboratory.find(1)
end
def shixuns
main_site? ? Shixun.all : Shixun.joins(:laboratory_shixuns).where(laboratory_shixuns: { laboratory_id: id })
end
def subjects
main_site? ? Subject.all : Subject.joins(:laboratory_subjects).where(laboratory_subjects: { laboratory_id: id })
end
# 是否为主站
def main_site?
id == 1
end
end

@ -0,0 +1,4 @@
class LaboratoryShixun < ApplicationRecord
belongs_to :laboratory
belongs_to :shixun
end

@ -0,0 +1,6 @@
class LaboratorySubject < ApplicationRecord
belongs_to :laboratory
belongs_to :subject
delegate :repertoire_id, :subject_level_system_id, :student_count, to: :subject
end

@ -51,6 +51,8 @@ class Shixun < ApplicationRecord
# 实训审核记录
has_many :shixun_reviews, -> {order("shixun_reviews.created_at desc")}, :dependent => :destroy
has_many :laboratory_shixuns, dependent: :destroy
scope :search_by_name, ->(keyword) { where("name like ? or description like ? ",
"%#{keyword}%", "%#{keyword}%") }

@ -196,12 +196,12 @@ class StudentWork < ApplicationRecord
student_works_scores.where.not(reviewer_role: 3, score: nil).exists?
end
def work_challenge_score game, score
def work_challenge_score game, score, challenge_id
game_score = 0
adjust_score = challenge_work_scores.where(challenge_id: game.challenge_id).last
adjust_score = challenge_work_scores.where(challenge_id: challenge_id).last
if adjust_score.present?
game_score = adjust_score.score
else
elsif game.present?
setting = homework_common.homework_group_setting game.user_id
if game.status == 2 && ((game.end_time && game.end_time < setting.end_time) || (homework_common.allow_late && game.end_time && game.end_time < homework_common.late_time))
answer_open_evaluation = homework_common.homework_detail_manual.answer_open_evaluation

@ -24,6 +24,8 @@ class Subject < ApplicationRecord
# 开放课堂
has_many :courses, -> { where("is_delete = 0").order("courses.created_at ASC") }
has_many :laboratory_subjects, dependent: :destroy
validates :name, length: { maximum: 60 }
validates :description, length: { maximum: 8000 }
validates :learning_notes, length: { maximum: 2000 }

@ -1,4 +1,5 @@
class TrustieHack < ApplicationRecord
validates_length_of :description, maximum: 500
has_many :hack_users, :dependent => :destroy
belongs_to :trustie_hackathon, counter_cache: true

@ -1,5 +1,5 @@
class TrustieHackathon < ApplicationRecord
validates_length_of :description, maximum: 500
has_many :trustie_hacks, :dependent => :destroy
end

@ -235,6 +235,28 @@ class User < ApplicationRecord
end
end
# 实名认证状态
def auth_status
status = if authentication
"已认证"
elsif process_real_name_apply.present?
"待审核"
else
"未认证"
end
end
# 职业认证状态
def pro_status
status = if professional_certification
"已认证"
elsif process_professional_apply.present?
"待审核"
else
"未认证"
end
end
# 判断当前用户是否通过职业认证
def pro_certification?
professional_certification
@ -265,6 +287,11 @@ class User < ApplicationRecord
course.course_members.exists?(user_id: id, role: [1,2,3], is_active: 1) || admin? || business?
end
# 课堂的老师(创建者、老师、助教),不考虑超管和运营人员
def none_admin_teacher_of_course?(course)
course.course_members.exists?(user_id: id, role: [1,2,3], is_active: 1)
end
# 课堂的老师(创建者、老师、助教),不用考虑当前身份
def teacher_of_course_non_active?(course)
course.course_members.exists?(user_id: id, role: [1,2,3])

@ -0,0 +1,36 @@
class Admins::LaboratoryShixunQuery < ApplicationQuery
attr_reader :laboratory, :params
def initialize(laboratory, params)
@laboratory = laboratory
@params = params
end
def call
laboratory_shixuns = laboratory.laboratory_shixuns.joins(:shixun)
keyword = params[:keyword].to_s.strip
if keyword.present?
like_sql = 'shixuns.name LIKE :keyword OR CONCAT(users.lastname, users.firstname) LIKE :keyword'
laboratory_shixuns = laboratory_shixuns.joins(shixun: :user).where(like_sql, keyword: "%#{keyword}%")
end
# 实训状态
laboratory_shixuns = laboratory_shixuns.where(shixuns: { status: params[:status] }) if params[:status].present?
# 技术平台
if params[:tag_id].present?
laboratory_shixuns = laboratory_shixuns.joins(shixun: :shixun_mirror_repositories)
.where(shixun_mirror_repositories: { mirror_repository_id: params[:tag_id] })
end
# 首页展示、单位自建
%i[homepage ownership].each do |column|
if params[column].present? && params[column].to_s == 'true'
laboratory_shixuns = laboratory_shixuns.where(column => true)
end
end
laboratory_shixuns
end
end

@ -0,0 +1,36 @@
class Admins::LaboratorySubjectQuery < ApplicationQuery
attr_reader :laboratory, :params
def initialize(laboratory, params)
@laboratory = laboratory
@params = params
end
def call
laboratory_subjects = laboratory.laboratory_subjects.joins(:subject)
keyword = params[:keyword].to_s.strip
if keyword.present?
like_sql = 'subjects.name LIKE :keyword OR CONCAT(users.lastname, users.firstname) LIKE :keyword'
laboratory_subjects = laboratory_subjects.joins(subject: :user).where(like_sql, keyword: "%#{keyword}%")
end
# 状态
laboratory_subjects = laboratory_subjects.where(subjects: { status: params[:status] }) if params[:status].present?
# 创建者单位
if params[:school_id].present?
laboratory_subjects = laboratory_subjects.joins(subjects: { user: :user_extension })
.where(user_extensions: { school_id: params[:school_id] })
end
# 首页展示、单位自建
%i[homepage ownership].each do |column|
if params[column].present? && params[column].to_s == 'true'
laboratory_subjects = laboratory_subjects.where(column => true)
end
end
laboratory_subjects
end
end

@ -11,6 +11,9 @@ class Admins::ShixunSettingsQuery < ApplicationQuery
def call
all_shixuns = Shixun.all
all_shixuns = all_shixuns.where(id: params[:id]) if params[:id].present?
status =
case params[:status]
when "editing" then [0]

@ -12,6 +12,8 @@ class Admins::SubjectQuery < ApplicationQuery
def call
subjects = Subject.all
subjects = subjects.where(id: params[:id]) if params[:id].present?
# 状态过滤
status =
case params[:status].to_s.strip

@ -94,8 +94,8 @@ class DuplicateCourseService < ApplicationService
exercise = course.exercises.create!(attrs.merge(user_id: user.id))
origin_exercise.exercise_questions.find_each do |origin_question|
question_attrs = origin_question.as_json(only: %i[question_title question_type question_number question_score])
question_attrs[:question_type] ||= 1
question_attrs = origin_question.as_json(only: %i[question_title question_type question_number question_score shixun_name shixun_id is_ordered level])
# question_attrs[:question_type] ||= 1
question = exercise.exercise_questions.create!(question_attrs)
exercise_choice_map = {}
@ -103,15 +103,20 @@ class DuplicateCourseService < ApplicationService
choice_attrs = { choice_position: index + 1, choice_text: origin_choice.choice_text }
choice = question.exercise_choices.create!(choice_attrs)
exercise_choice_map[origin_choice.id] = choice.id
# exercise_choice_map[origin_choice.id] = choice.id 标准答案中存的是choice_position, 直接取原题的exercise_choice_id就行
end
origin_question.exercise_standard_answers.find_each do |origin_answer|
question.exercise_standard_answers.create!(
exercise_choice_id: exercise_choice_map[origin_answer.exercise_choice_id],
exercise_choice_id: origin_answer.exercise_choice_id,
answer_text: origin_answer.answer_text
)
end
origin_question.exercise_shixun_challenges.each_with_index do |sc, index|
question.exercise_shixun_challenges.create!({position: index+1, challenge_id: sc.challenge_id,
shixun_id: sc.shixun_id, question_score: sc.question_score})
end
end
origin_exercise.exercise_bank.increment!(:quotes) if exercise.exercise_bank

@ -76,22 +76,23 @@
<th>调分</th>
</thead>
<tbody>
<% @games.each_with_index do |game, index| %>
<% challenge_score = @homework.challenge_score game.challenge_id %>
<% game_score = @work.work_challenge_score game, challenge_score %>
<% @challenges.each_with_index do |challenge, index| %>
<% challenge_score = @homework.challenge_score challenge.id %>
<% game = @games.select{|game| game.challenge_id == challenge.id}.first if @games %>
<% game_score = @work.work_challenge_score game, challenge_score, challenge.id %>
<tr>
<td><%= index + 1 %></td>
<td style="text-align: left;">
<span class="task-hide edu-info-dark fl"><%= game.challenge.subject %></span>
<% if ((Time.now > @homework.end_time) && game.end_time.blank?) || (game.end_time.present? && game.end_time > @homework.end_time) %>
<span class="task-hide edu-info-dark fl"><%= challenge.subject %></span>
<% if game && (((Time.now > @homework.end_time) && game.end_time.blank?) || (game.end_time.present? && game.end_time > @homework.end_time)) %>
<span class="delay ml10">延时</span>
<% end %>
</td>
<td><%= myshixun_open_time(game) %></td>
<td><%= game.evaluate_count %></td>
<td><%= finished_time game.end_time %></td>
<td><%= game ? game&.evaluate_count : 0 %></td>
<td><%= game ? finished_time(game.end_time) : "--" %></td>
<td><%= ApplicationController.helpers.time_consuming game %></td>
<td><%= game.final_score %> / <%= game.challenge.all_score %></td>
<td><%= game ? game.final_score : 0 %> / <%= challenge.all_score %></td>
<td><span class="color-orange"><%= game_score %></span> / <%= challenge_score %></td>
<td><%= game_score %></td>
</tr>

@ -50,6 +50,12 @@
<%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %>
<%= link_to '清除', admins_competition_competition_prize_users_path(@competition), class: "btn btn-default",'data-disable-with': '清除中...' %>
<% end %>
<div class="mt-3 d-flex align-items-end">
<%= link_to '导出', admins_competition_competition_prize_users_path(competition_id: @competition.id, format: :xlsx), class: 'btn btn-primary' %>
<%#= javascript_void_link '导出', class: 'btn btn-primary', 'data-url': admins_competition_competition_prize_users_path(competition_id: @competition.id, format: :xlsx) %>
</div>
</div>
</div>

@ -0,0 +1,33 @@
wb = xlsx_package.workbook
wb.styles do |s|
blue_cell = s.add_style :bg_color => "FAEBDC", :sz => 10,:height => 25,:b => true, :border => { :style => :thin, :color =>"000000" },:alignment => {wrap_text: true,:horizontal => :center,:vertical => :center}
wb.add_worksheet(name: "#{@competition.name}证书审批列表") do |sheet|
sheet.add_row %w(序号 排名 奖项 战队ID 战队名称 姓名 职业 学号 学校名称 学院名称 地区 实名认证 职业认证 手机号码 队长 签领/开户行及银行卡号 审批时间 审批人), :height => 25,:style => blue_cell
@all_prize_users.each_with_index do |prize_user, index|
user = prize_user.user
data = [
index + 1,
prize_user.rank,
prize_user.competition_prize.name,
prize_user.competition_team_id,
prize_user.competition_team.name,
user.real_name,
user.identity,
user.student_id,
user.school_name,
user.department_name,
user.location,
user.auth_status,
user.pro_status,
user.phone,
prize_user.leader? ? "是" : "-",
[prize_user.extra&.[]('bank'), prize_user.extra&.[]('second_bank'), prize_user.extra&.[]('card_no')].compact.join('/'),
prize_user.approved_at&.strftime('%Y-%m-%d %H:%M'),
prize_user.approver&.real_name
]
sheet.add_row(data)
end
end
end

@ -41,6 +41,9 @@
<div class="dropdown-menu more-action-dropdown">
<%= link_to '轮播图', admins_laboratory_carousels_path(laboratory), class: 'dropdown-item' %>
<%= link_to '查看实训项目', admins_laboratory_laboratory_shixuns_path(laboratory), class: 'dropdown-item' %>
<%= link_to '查看实践课程', admins_laboratory_laboratory_subjects_path(laboratory), class: 'dropdown-item' %>
<% if school.present? && laboratory.id != 1 %>
<%= delete_link '删除', admins_laboratory_path(laboratory, element: ".laboratory-item-#{laboratory.id}"), class: 'dropdown-item delete-laboratory-action' %>
<% end %>

@ -0,0 +1,8 @@
json.count @count
json.shixuns do
json.array! @shixuns do |shixun|
json.extract! shixun, :id, :name, :status
json.status_text I18n.t("shixun.status.#{shixun.status}")
json.creator_name shixun.user.real_name
end
end

@ -0,0 +1,8 @@
json.count @count
json.subjects do
json.array! @subjects do |subject|
json.extract! subject, :id, :name, :status
json.status_text I18n.t("subject.status.#{subject.status}")
json.creator_name subject.user.real_name
end
end

@ -0,0 +1,45 @@
<% define_admin_breadcrumbs do %>
<% add_admin_breadcrumb('云上实验室', admins_laboratories_path) %>
<% add_admin_breadcrumb("#{current_laboratory.name} - 实训项目") %>
<% end %>
<div class="box search-form-container laboratory-shixun-list-form">
<%= form_tag(admins_laboratory_laboratory_shixuns_path(current_laboratory), method: :get, class: 'form-inline search-form', remote: true) do %>
<div class="form-group mr-1">
<label for="status">状态:</label>
<% status_options = [['全部', ''], ['编辑中', 0], ['审核中', 1], ['已发布', 2], ['已关闭', 3]] %>
<%= select_tag(:status, options_for_select(status_options), class: 'form-control') %>
</div>
<div class="form-group mr-4">
<label for="status">技术平台:</label>
<%= select_tag(:tag_id, options_for_select(MirrorRepository.pluck(:type_name,:id).unshift(['']), params[:tag_id]), class: 'form-control') %>
</div>
<%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-12 col-md-2 mr-3', placeholder: '创建者/实训名称检索') %>
<div class="form-check mr-2">
<%= hidden_field_tag(:homepage, false, id:'') %>
<%= check_box_tag(:homepage, true, params[:homepage].to_s == 'true', class: 'form-check-input') %>
<label class="form-check-label" for="homepage">只看首页展示</label>
</div>
<div class="form-check mr-2">
<%= hidden_field_tag(:ownership, false, id:'') %>
<%= check_box_tag(:ownership, true, params[:ownership].to_s == 'true', class: 'form-check-input') %>
<label class="form-check-label" for="ownership">只看自建</label>
</div>
<%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %>
<%= link_to '清空', admins_laboratory_laboratory_shixuns_path(current_laboratory), class: 'btn btn-default','data-disable-with': '清空中...' %>
<% end %>
<%= javascript_void_link('添加实训', class: 'btn btn-primary', data: { toggle: 'modal', target: '.admin-add-laboratory-shixun-modal' }) %>
</div>
<div class="box laboratory-shixun-list-container" data-id="<%= current_laboratory.id %>">
<%= render partial: 'admins/laboratory_shixuns/shared/list', locals: { laboratory_shixuns: @laboratory_shixuns } %>
</div>
<%= render partial: 'admins/laboratory_shixuns/shared/add_laboratory_shixun_modal' %>

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

@ -0,0 +1,28 @@
<div class="modal fade admin-add-laboratory-shixun-modal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">添加实训</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<form class="admin-add-laboratory-user-form">
<div class="form-group d-flex">
<label class="col-form-label">选择实训:</label>
<div class="d-flex flex-column-reverse w-75">
<select id="shixun_ids" name="shixun_ids" class="form-control shixun-select" multiple></select>
</div>
</div>
<div class="error text-danger"></div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary submit-btn">确认</button>
</div>
</div>
</div>
</div>

@ -0,0 +1,27 @@
<table class="table text-center laboratory-shixun-list-table">
<thead class="thead-light">
<tr>
<th width="28%" class="text-left">实训名称</th>
<th width="12%">技术平台</th>
<th width="14%" class="text-left">技术体系</th>
<th width="10%">封面</th>
<th width="8%">创建者</th>
<th width="8%">状态</th>
<th width="8%">执行时间</th>
<th width="16%">操作</th>
</tr>
</thead>
<tbody>
<% if laboratory_shixuns.present? %>
<% laboratory_shixuns.each do |laboratory_shixun| %>
<tr class="laboratory-shixun-item-<%= laboratory_shixun.id %>">
<%= render partial: 'admins/laboratory_shixuns/shared/td', locals: { laboratory_shixun: laboratory_shixun } %>
</tr>
<% end %>
<% else %>
<%= render 'admins/shared/no_data_for_table' %>
<% end %>
</tbody>
</table>
<%= render partial: 'admins/shared/paginate', locals: { objects: laboratory_shixuns } %>

@ -0,0 +1,28 @@
<%- shixun = laboratory_shixun.shixun -%>
<td class="text-left">
<%= link_to "/shixuns/#{shixun.identifier}", target: '_blank' do %>
<%= shixun.name %>
<span class="badge badge-pill badge-success homepage-badge" style="<%= laboratory_shixun.homepage? ? '' : 'display:none' %>">首页</span>
<span class="badge badge-pill badge-info ownership-badge" style="<%= laboratory_shixun.ownership ? '' : 'display:none' %>">自建</span>
<% end %>
</td>
<td><%= shixun.shixun_main_name %></td>
<td class="text-left">
<% shixun.tag_repertoires.each do |tag| %>
<span class="badge badge-secondary"><%= tag.name %></span>
<% end %>
</td>
<td>
<% imageExists = Util::FileManage.exists?(shixun) %>
<% imageUrl = imageExists ? '/' + url_to_avatar(shixun) : '' %>
<%= image_tag(imageUrl, width: 60, height: 40, class: "preview-image shixun-image-#{shixun.id}", data: { toggle: 'tooltip', title: '点击预览' }, style: imageExists ? '' : 'display:none') %>
</td>
<td><%= link_to shixun.user&.real_name, "/users/#{shixun.user&.login}", target:'_blank' %></td>
<td><span class="<%= shixun_status_class(shixun) %>"><%= t("shixun.status.#{shixun.status}") %></span></td>
<td><%= shixun.excute_time %></td>
<td class="action-container">
<%= link_to('去修改', admins_shixun_settings_path(id: laboratory_shixun.shixun_id)) %>
<%= javascript_void_link('首页展示', class: 'action homepage-show-action', data: { id: laboratory_shixun.id }, style: laboratory_shixun.homepage? ? 'display:none' : '') %>
<%= javascript_void_link('取消首页展示', class: 'action homepage-hide-action', data: { id: laboratory_shixun.id }, style: laboratory_shixun.homepage? ? '' : 'display:none') %>
</td>

@ -0,0 +1,45 @@
<% define_admin_breadcrumbs do %>
<% add_admin_breadcrumb('云上实验室', admins_laboratories_path) %>
<% add_admin_breadcrumb("#{current_laboratory.name} - 实践课程") %>
<% end %>
<div class="box search-form-container laboratory-subject-list-form">
<%= form_tag(admins_laboratory_laboratory_subjects_path(current_laboratory), method: :get, class: 'form-inline search-form', remote: true) do %>
<div class="form-group mr-1">
<label for="status">状态:</label>
<% status_options = [['全部', ''], ['编辑中', 0], ['审核中', 1], ['已发布', 2]] %>
<%= select_tag(:status, options_for_select(status_options), class: 'form-control') %>
</div>
<div class="form-group col-12 col-md-3">
<label for="school_name">单位:</label>
<%= select_tag :school_id, options_for_select([''], params[:school_id]), class: 'form-control school-select flex-1' %>
</div>
<%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-12 col-md-2 mr-3', placeholder: '创建者/课程名称检索') %>
<div class="form-check mr-2">
<%= hidden_field_tag(:homepage, false, id:'') %>
<%= check_box_tag(:homepage, true, params[:homepage].to_s == 'true', class: 'form-check-input') %>
<label class="form-check-label" for="homepage">只看首页展示</label>
</div>
<div class="form-check mr-2">
<%= hidden_field_tag(:ownership, false, id:'') %>
<%= check_box_tag(:ownership, true, params[:ownership].to_s == 'true', class: 'form-check-input') %>
<label class="form-check-label" for="ownership">只看自建</label>
</div>
<%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %>
<%= link_to '清空', admins_laboratory_laboratory_subjects_path(current_laboratory), class: 'btn btn-default','data-disable-with': '清空中...' %>
<% end %>
<%= javascript_void_link('添加课程', class: 'btn btn-primary', data: { toggle: 'modal', target: '.admin-add-laboratory-subject-modal' }) %>
</div>
<div class="box laboratory-subject-list-container" data-id="<%= current_laboratory.id %>">
<%= render partial: 'admins/laboratory_subjects/shared/list', locals: { laboratory_subjects: @laboratory_subjects } %>
</div>
<%= render partial: 'admins/laboratory_subjects/shared/add_laboratory_subject_modal' %>

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

@ -0,0 +1,28 @@
<div class="modal fade admin-add-laboratory-subject-modal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">添加实践课程</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<form class="admin-add-laboratory-user-form">
<div class="form-group d-flex">
<label class="col-form-label">选择实践课程:</label>
<div class="d-flex flex-column-reverse w-75">
<select id="subject_ids" name="subject_ids" class="form-control subject-select" multiple></select>
</div>
</div>
<div class="error text-danger"></div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary submit-btn">确认</button>
</div>
</div>
</div>
</div>

@ -0,0 +1,48 @@
<table class="table text-center laboratory-subject-list-table">
<thead class="thead-light">
<tr>
<th width="28%" class="text-left">课程名称</th>
<th width="12%">技术体系</th>
<th width="10%">等级体系</th>
<th width="10%">封面</th>
<th width="8%">创建者</th>
<th width="10%">单位</th>
<th width="8%">状态</th>
<th width="14%">操作</th>
</tr>
</thead>
<tbody>
<% if laboratory_subjects.present? %>
<% laboratory_subjects.each do |laboratory_subject| %>
<tr class="laboratory-subject-item-<%= laboratory_subject.id %>">
<%- subject = laboratory_subject.subject -%>
<td class="text-left">
<%= link_to(subject.name, "/paths/#{subject.id}", target: '_blank') %>
<span class="badge badge-pill badge-success homepage-badge" style="<%= laboratory_subject.homepage? ? '' : 'display:none' %>">首页</span>
<span class="badge badge-pill badge-success ownership-badge" style="<%= laboratory_subject.ownership? ? '' : 'display:none' %>">自建</span>
</td>
<td><%= display_text subject.repertoire&.name %></td>
<td><%= display_text subject.subject_level_system&.name %></td>
<td>
<% image_exists = Util::FileManage.exists?(subject) %>
<%= image_tag(image_exists ? Util::FileManage.source_disk_file_url(subject) : '', height: 40, class: "w-100 preview-image subject-image-#{subject.id}", style: image_exists ? '' : 'display:none') %>
</td>
<td><%= subject.user.real_name %></td>
<td><%= subject.user.school_name %></td>
<td><%= display_subject_status(subject) %></td>
<td class="action-container">
<%= link_to('去修改', admins_subjects_path(id: laboratory_subject.subject_id)) %>
<%= javascript_void_link('首页展示', class: 'action homepage-show-action', data: { id: laboratory_subject.id }, style: laboratory_subject.homepage? ? 'display:none' : '') %>
<%= javascript_void_link('取消首页展示', class: 'action homepage-hide-action', data: { id: laboratory_subject.id }, style: laboratory_subject.homepage? ? '' : 'display:none') %>
</td>
</tr>
<% end %>
<% else %>
<%= render 'admins/shared/no_data_for_table' %>
<% end %>
</tbody>
</table>
<%= render partial: 'admins/shared/paginate', locals: { objects: laboratory_subjects } %>

@ -1,10 +1,10 @@
<% sidebar_collapse = request.cookies['admin_sidebar_collapse'].to_s == 'true' %>
<nav id="sidebar" class="<%= sidebar_collapse ? 'active' : '' %>" data-current-controller="<%= admin_sidebar_controller %>">
<div class="sidebar-header">
<div class="sidebar-header-logo">
<a href="/" class="sidebar-header-logo" data-toggle="tooltip" data-title="返回主站" >
<img class="rounded-circle" src="/images/<%= url_to_avatar(current_user) %>" />
<span class="logo-label">后台管理</span>
</div>
</a>
<div id="sidebarCollapse" class="navbar-btn <%= sidebar_collapse ? 'active' : '' %>">
<i class="fa fa-chevron-left fold" data-toggle="tooltip" data-placement="right" data-boundary="window" title="收起"></i>
<i class="fa fa-bars unfold" data-toggle="tooltip" data-placement="right" data-boundary="window" title="展开"></i>

@ -0,0 +1,42 @@
<% define_breadcrumbs do %>
<% add_breadcrumb('实训项目') %>
<% end %>
<div class="box search-form-container laboratory-shixun-list-form">
<%= form_tag(cooperative_laboratory_shixuns_path, method: :get, class: 'form-inline search-form', remote: true) do %>
<div class="form-group mr-1">
<label for="status">状态:</label>
<% status_options = [['全部', ''], ['编辑中', 0], ['审核中', 1], ['已发布', 2], ['已关闭', 3]] %>
<%= select_tag(:status, options_for_select(status_options), class: 'form-control') %>
</div>
<div class="form-group mr-4">
<label for="status">技术平台:</label>
<%= select_tag(:tag_id, options_for_select(MirrorRepository.pluck(:type_name,:id).unshift(['']), params[:tag_id]), class: 'form-control') %>
</div>
<%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-12 col-md-2 mr-3', placeholder: '创建者/实训名称检索') %>
<div class="form-check mr-2">
<%= hidden_field_tag(:homepage, false, id:'') %>
<%= check_box_tag(:homepage, true, params[:homepage].to_s == 'true', class: 'form-check-input') %>
<label class="form-check-label" for="homepage">只看首页展示</label>
</div>
<div class="form-check mr-2">
<%= hidden_field_tag(:ownership, false, id:'') %>
<%= check_box_tag(:ownership, true, params[:ownership].to_s == 'true', class: 'form-check-input') %>
<label class="form-check-label" for="ownership">只看自建</label>
</div>
<%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %>
<%= link_to '清空', cooperative_laboratory_shixuns_path, class: 'btn btn-default','data-disable-with': '清空中...' %>
<% end %>
</div>
<div class="box laboratory-shixun-list-container">
<%= render partial: 'cooperative/laboratory_shixuns/shared/list', locals: { laboratory_shixuns: @laboratory_shixuns } %>
</div>
<%= render(partial: 'cooperative/shared/modal/upload_file_modal', locals: { title: '上传封面', accept: 'image/*' }) %>

@ -0,0 +1 @@
$('.laboratory-shixun-list-container').html("<%= j(render partial: 'cooperative/laboratory_shixuns/shared/list', locals: { laboratory_shixuns: @laboratory_shixuns }) %>");

@ -0,0 +1,27 @@
<table class="table text-center laboratory-shixun-list-table">
<thead class="thead-light">
<tr>
<th width="28%" class="text-left">实训名称</th>
<th width="12%">技术平台</th>
<th width="14%" class="text-left">技术体系</th>
<th width="10%">封面</th>
<th width="8%">创建者</th>
<th width="8%">状态</th>
<th width="8%">执行时间</th>
<th width="16%">操作</th>
</tr>
</thead>
<tbody>
<% if laboratory_shixuns.present? %>
<% laboratory_shixuns.each do |laboratory_shixun| %>
<tr class="laboratory-shixun-item-<%= laboratory_shixun.id %>">
<%= render partial: 'cooperative/laboratory_shixuns/shared/td', locals: { laboratory_shixun: laboratory_shixun } %>
</tr>
<% end %>
<% else %>
<%= render 'cooperative/shared/no_data_for_table' %>
<% end %>
</tbody>
</table>
<%= render partial: 'cooperative/shared/paginate', locals: { objects: laboratory_shixuns } %>

@ -0,0 +1,32 @@
<%- shixun = laboratory_shixun.shixun -%>
<td class="text-left">
<%= link_to "/shixuns/#{shixun.identifier}", target: '_blank' do %>
<%= shixun.name %>
<span class="badge badge-pill badge-success homepage-badge" style="<%= laboratory_shixun.homepage? ? '' : 'display:none' %>">首页</span>
<span class="badge badge-pill badge-info ownership-badge" style="<%= laboratory_shixun.ownership ? '' : 'display:none' %>">自建</span>
<% end %>
</td>
<td><%= shixun.shixun_main_name %></td>
<td class="text-left">
<% shixun.tag_repertoires.each do |tag| %>
<span class="badge badge-secondary"><%= tag.name %></span>
<% end %>
</td>
<td class="image-preview-container">
<% imageExists = Util::FileManage.exists?(shixun) %>
<%= image_tag(imageExists ? Util::FileManage.source_disk_file_url(shixun) : '', height: 40, class: "preview-image shixun-image-#{shixun.id}", data: { toggle: 'tooltip', title: '点击预览' }, style: imageExists ? '' : 'display:none') %>
<% if laboratory_shixun.ownership? %>
<%= javascript_void_link imageExists ? '重新上传' : '上传图片', class: 'action upload-shixun-image-action', data: { source_id: shixun.id, source_type: 'Shixun', toggle: 'modal', target: '.cooperative-upload-file-modal' } %>
<% end %>
</td>
<td><%= link_to shixun.user&.real_name, "/users/#{shixun.user&.login}", target:'_blank' %></td>
<td><span class="<%= shixun_status_class(shixun) %>"><%= t("shixun.status.#{shixun.status}") %></span></td>
<td><%= shixun.excute_time %></td>
<td class="action-container">
<% if laboratory_shixun.ownership? %>
<%#= link_to('修改', cooperative_laboratory_subjects_path(laboratory_shixun)) %>
<% end %>
<%= javascript_void_link('首页展示', class: 'action homepage-show-action', data: { id: laboratory_shixun.id }, style: laboratory_shixun.homepage? ? 'display:none' : '') %>
<%= javascript_void_link('取消首页展示', class: 'action homepage-hide-action', data: { id: laboratory_shixun.id }, style: laboratory_shixun.homepage? ? '' : 'display:none') %>
</td>

@ -0,0 +1,2 @@
$('.cooperative-modal-container').html("<%= j( render partial: 'cooperative/laboratory_subjects/shared/edit_subject_modal', locals: { laboratory_subject: @laboratory_subject } ) %>");
$('.modal.cooperative-edit-subject-modal').modal('show');

@ -0,0 +1,42 @@
<% define_breadcrumbs do %>
<% add_breadcrumb('实践课程') %>
<% end %>
<div class="box search-form-container laboratory-subject-list-form">
<%= form_tag(cooperative_laboratory_subjects_path, method: :get, class: 'form-inline search-form', remote: true) do %>
<div class="form-group mr-1">
<label for="status">状态:</label>
<% status_options = [['全部', ''], ['编辑中', 0], ['审核中', 1], ['已发布', 2]] %>
<%= select_tag(:status, options_for_select(status_options), class: 'form-control') %>
</div>
<div class="form-group col-12 col-md-3">
<label for="school_name">单位:</label>
<%= select_tag :school_id, options_for_select([''], params[:school_id]), class: 'form-control school-select flex-1' %>
</div>
<%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-12 col-md-2 mr-3', placeholder: '创建者/课程名称检索') %>
<div class="form-check mr-2">
<%= hidden_field_tag(:homepage, false, id:'') %>
<%= check_box_tag(:homepage, true, params[:homepage].to_s == 'true', class: 'form-check-input') %>
<label class="form-check-label" for="homepage">只看首页展示</label>
</div>
<div class="form-check mr-2">
<%= hidden_field_tag(:ownership, false, id:'') %>
<%= check_box_tag(:ownership, true, params[:ownership].to_s == 'true', class: 'form-check-input') %>
<label class="form-check-label" for="ownership">只看自建</label>
</div>
<%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %>
<%= link_to '清空', cooperative_laboratory_subjects_path(current_laboratory), class: 'btn btn-default','data-disable-with': '清空中...' %>
<% end %>
</div>
<div class="box laboratory-subject-list-container">
<%= render partial: 'cooperative/laboratory_subjects/shared/list', locals: { laboratory_subjects: @laboratory_subjects } %>
</div>
<%= render(partial: 'cooperative/shared/modal/upload_file_modal', locals: { title: '上传封面', accept: 'image/*' }) %>

@ -0,0 +1 @@
$('.laboratory-subject-list-container').html("<%= j(render partial: 'cooperative/laboratory_subjects/shared/list', locals: { laboratory_subjects: @laboratory_subjects }) %>");

@ -0,0 +1,31 @@
<div class="modal fade cooperative-edit-subject-modal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">编辑课程信息</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<%= simple_form_for([:cooperative, laboratory_subject], html: { class: 'cooperative-edit-subject-form' }, defaults: { wrapper_html: { class: 'offset-md-1 col-md-10' } }) do |f| %>
<%= f.input :repertoire_id, label: '技术体系:' do %>
<% repertoire_options = Repertoire.order('CONVERT(name USING gbk) COLLATE gbk_chinese_ci ASC').map{|r| [r.name, r.id]} %>
<%= f.select :repertoire_id, [['请选择', '']] + repertoire_options, {}, class: 'form-control' %>
<% end %>
<%= f.input :subject_level_system_id, label: '等级体系:' do %>
<% level_options = SubjectLevelSystem.all.map{|r| [r.name, r.id]} %>
<%= f.select :subject_level_system_id, [['请选择', '']] + level_options, {}, class: 'form-control' %>
<% end %>
<div class="error text-danger"></div>
<% end %>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary submit-btn">确认</button>
</div>
</div>
</div>
</div>

@ -0,0 +1,27 @@
<table class="table text-center laboratory-subject-list-table">
<thead class="thead-light">
<tr>
<th width="28%" class="text-left">课程名称</th>
<th width="12%">技术体系</th>
<th width="10%">等级体系</th>
<th width="10%">封面</th>
<th width="8%">创建者</th>
<th width="10%">单位</th>
<th width="8%">状态</th>
<th width="14%">操作</th>
</tr>
</thead>
<tbody>
<% if laboratory_subjects.present? %>
<% laboratory_subjects.each do |laboratory_subject| %>
<tr class="laboratory-subject-item-<%= laboratory_subject.id %>">
<%= render partial: 'cooperative/laboratory_subjects/shared/td', locals: { laboratory_subject: laboratory_subject } %>
</tr>
<% end %>
<% else %>
<%= render 'cooperative/shared/no_data_for_table' %>
<% end %>
</tbody>
</table>
<%= render partial: 'cooperative/shared/paginate', locals: { objects: laboratory_subjects } %>

@ -0,0 +1,28 @@
<%- subject = laboratory_subject.subject -%>
<td class="text-left">
<%= link_to(subject.name, "/paths/#{subject.id}", target: '_blank') %>
<span class="badge badge-pill badge-success homepage-badge" style="<%= laboratory_subject.homepage? ? '' : 'display:none' %>">首页</span>
<span class="badge badge-pill badge-success ownership-badge" style="<%= laboratory_subject.ownership? ? '' : 'display:none' %>">自建</span>
</td>
<td><%= display_text subject.repertoire&.name %></td>
<td><%= display_text subject.subject_level_system&.name %></td>
<td class="image-preview-container">
<% image_exists = Util::FileManage.exists?(subject) %>
<%= image_tag(image_exists ? Util::FileManage.source_disk_file_url(subject) : '', height: 40, class: "w-100 preview-image subject-image-#{subject.id}", style: image_exists ? '' : 'display:none') %>
<% if laboratory_subject.ownership? %>
<%= javascript_void_link image_exists ? '重新上传' : '上传图片', class: 'action upload-subject-image-action', data: { source_id: subject.id, source_type: 'Subject', toggle: 'modal', target: '.cooperative-upload-file-modal' } %>
<% end %>
</td>
<td><%= link_to subject.user&.real_name, "/users/#{subject.user&.login}", target:'_blank' %></td>
<td><%= subject.user.school_name %></td>
<td><%= display_subject_status(subject) %></td>
<td class="action-container">
<% if laboratory_subject.ownership? %>
<%= link_to('修改', edit_cooperative_laboratory_subject_path(laboratory_subject), remote: true) %>
<% end %>
<%= javascript_void_link('首页展示', class: 'action homepage-show-action', data: { id: laboratory_subject.id }, style: laboratory_subject.homepage? ? 'display:none' : '') %>
<%= javascript_void_link('取消首页展示', class: 'action homepage-hide-action', data: { id: laboratory_subject.id }, style: laboratory_subject.homepage? ? '' : 'display:none') %>
</td>

@ -0,0 +1,3 @@
$('.laboratory-subject-list-container .laboratory-subject-item-<%= current_laboratory_subject.id %>').html("<%= j(render partial: 'cooperative/laboratory_subjects/shared/td', locals: { laboratory_subject: current_laboratory_subject }) %>");
$('.cooperative-modal-container .modal.cooperative-edit-subject-modal').modal('hide');
show_success_flash();

@ -17,6 +17,8 @@
<li><%= sidebar_item(edit_cooperative_laboratory_setting_path, '网站设置', icon: 'cogs', controller: 'cooperative-laboratory_settings') %></li>
<li><%= sidebar_item(cooperative_carousels_path, '轮播图设置', icon: 'image', controller: 'cooperative-carousels') %></li>
<li><%= sidebar_item(cooperative_laboratory_users_path, '管理员列表', icon: 'user', controller: 'cooperative-laboratory_users') %></li>
<li><%= sidebar_item(cooperative_laboratory_shixuns_path, '实训项目', icon: 'window-restore', controller: 'cooperative-laboratory_shixuns') %></li>
<li><%= sidebar_item(cooperative_laboratory_subjects_path, '实践课程', icon: 'th-list', controller: 'cooperative-laboratory_subjects') %></li>
<li><%= sidebar_item('/', '返回主页', icon: 'sign-out', controller: 'root') %></li>
</ul>
</nav>

@ -11,12 +11,13 @@
<form class="cooperative-upload-file-form" enctype="multipart/form-data">
<%= hidden_field_tag(:source_type, nil) %>
<%= hidden_field_tag(:source_id, nil) %>
<%= hidden_field_tag(:suffix, nil) %>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text">文件</span>
</div>
<div class="custom-file">
<input type="file" name="file" class="upload-file-input" id="upload-file-input">
<input type="file" name="file" class="upload-file-input" accept="<%= accept ||= '*' %>" id="upload-file-input">
<label class="custom-file-label file-names" for="upload-file-input">选择文件</label>
</div>
</div>

@ -16,6 +16,8 @@ json.exercise_types do
json.subjective @subjective_type #是否包含主观题1为包括0为不包括
json.exercise_end_time ((@ex_user_end_time.nil? || @ex_user_end_time < Time.now) ? "--" : how_much_time(@ex_user_end_time))
json.groups_count @c_group_counts
json.subjective_score @exercise.subjective_score
json.objective_score @exercise.objective_score
end
if @exercise_current_user_status == 0 #当为老师的时候

@ -4,6 +4,7 @@ end
json.id message.id
json.content content_safe(message.contents_show(identity))
# json.content message.contents_show(identity)
json.time time_from_now(message.created_at)
json.hidden message.hidden
# 主贴与子贴不一致

@ -3,17 +3,19 @@ json.images_url @images_url
json.reps @rep_list
json.shixuns do
json.partial! 'shixuns/shixun', locals: {shixuns: @shixuns}
json.partial! 'shixuns/shixun', locals: {shixuns: @shixuns.present? ? @shixuns : @main_shixuns}
end
json.subjects do
json.partial! 'subjects/subject', locals: {subjects: @subjects}
json.partial! 'subjects/subject', locals: {subjects: @subjects.present? ? @subjects : @main_subjects}
end
json.teachers do
json.partial! 'users/user_small', users: @tea_users
end
if current_laboratory.main_site?
json.teachers do
json.partial! 'users/user_small', users: @tea_users
end
json.students do
json.partial! 'users/user_small', users: @stu_users
json.students do
json.partial! 'users/user_small', users: @stu_users
end
end

@ -1,2 +1,2 @@
json.extract! message, :id, :parent_id, :subject, :created_on, :total_replies_count, :total_praises_count,
:is_md, :praises_count, :visits, :sticky, :is_hidden, :is_public
:is_md, :praises_count, :visits, :sticky, :is_hidden, :is_public, :email_notify

@ -3,44 +3,46 @@ json.category @homework.category_info
json.course_name @course.name
json.work_id @work.id
json.work_efficiency @homework.work_efficiency
json.has_commit @work.myshixun.present?
if @shixun
json.shixun_name @shixun.name
# 总体评价
json.overall_appraisal @work.overall_appraisal
json.myself_experience @work.myshixun.try(:total_score)
json.myself_experience @work.myshixun.try(:total_score).to_i
json.total_experience @shixun.all_score
json.work_score number_with_precision @work.work_score, precision: 1
json.work_score number_with_precision @work.work_score.to_f.round(2), precision: 1
json.all_work_score number_with_precision 100, precision: 1
json.time_consuming @work.myshixun_consume
json.evaluate_count @user_evaluate_count.to_i
if @homework.work_efficiency
json.eff_score_full number_with_precision @homework.eff_score, precision: 1
json.eff_score number_with_precision @work.eff_score, precision: 1
json.eff_score number_with_precision @work.eff_score.to_f.round(2), precision: 1
json.challenge_score_full number_with_precision (100 - @homework.eff_score), precision: 1
json.challenge_score number_with_precision @work.final_score, precision: 1
json.challenge_score number_with_precision @work.final_score.to_f.round(2), precision: 1
end
# 阶段成绩
json.stage_list do
json.array! @games do |game|
json.name game.challenge.subject
json.is_delay student_work_is_delay?(@homework, game)
json.array! @challenges do |challenge|
json.name challenge.subject
game = @games.select{|game| game.challenge_id == challenge.id}.first if @games
json.is_delay game ? student_work_is_delay?(@homework, game) : false
json.open_time myshixun_open_time game
json.evaluate_count game.evaluate_count
json.finished_time finished_time game.end_time
json.evaluate_count game ? game&.evaluate_count : 0
json.finished_time game ? finished_time(game.end_time) : "--"
json.time_consuming time_consuming game
json.myself_experience game.final_score
json.experience game.challenge.all_score
json.complete_status game_status(game, @homework)
json.challenge_id game.challenge_id
challenge_score = @homework.challenge_score game.challenge_id
json.myself_experience game ? game&.final_score : 0
json.experience challenge.all_score
json.complete_status game ? game_status(game, @homework) : 0
json.challenge_id challenge.id
challenge_score = @homework.challenge_score challenge.id
json.game_score_full challenge_score
json.game_score @work.work_challenge_score game, challenge_score
challenge_comment = @work.shixun_work_comments.find_by(challenge_id: game.challenge_id)
json.game_score @work.work_challenge_score game, challenge_score, challenge.id
challenge_comment = @work.shixun_work_comments.find_by(challenge_id: challenge.id)
json.challenge_comment challenge_comment&.comment
json.challenge_comment_hidden @user_course_identity < Course::STUDENT ? challenge_comment&.hidden_comment : nil
json.comment_id challenge_comment&.id
json.view_answer game.answer_open != 0
json.view_answer game ? game.answer_open != 0 : 0
end
end
@ -52,7 +54,7 @@ if @shixun
json.username @user.real_name
json.student_id @user.student_id
json.image_url url_to_avatar(@user)
json.complete_count @work.myshixun&.passed_count
json.complete_count @work.myshixun&.passed_count.to_i
json.challenges_count @shixun.challenges_count
json.efficiency @homework.work_efficiency ? number_with_precision(@work.efficiency, precision: 2) : nil
json.max_efficiency @homework.work_efficiency ? number_with_precision(@homework.max_efficiency, precision: 2) : nil

@ -1,7 +1,7 @@
<html>
<head>
<meta charset="utf-8">
<title><%= @course.name %>通知</title>
<title><%= @course.name %> 发布了新的帖子</title>
<style type="text/css">
/* 验证链接页面 */
body,h1,h2,h3,h4,h5,h6,hr,p,blockquote,dl,dt,dd,ul,ol,li,pre,form,fieldset,legend,button,input,textarea,th,td{ margin:0; padding:0;}
@ -36,22 +36,16 @@
<p style="color:#333; font-size:16px; margin-bottom:15px;font-weight: bold">
您好!
</p>
<p style="color:#333;">
正在注册Educoder请在10分钟内在注册页输入此验证码并进行下一步操作。
如非你本人操作,请忽略此邮件。
<p style="color:#333; ">
参与的课堂:<%= @course.name %>,有新的帖子发布了:
<a href="https://www.educoder.net/courses/<%= @course.id %>/boards/<%= @message.board_id %>/messages/<%= @message.id %>" style="font-weight: normal; color:#ff7500;"><%= @message.subject %></a>
</p>
<div style="text-align: center;">
<div style="display:block; height: 45px; line-height:45px;padding:0 30px; width:100px; font-size: 20px; font-weight: bold; background:#ffd9d9; color:#e72c37; margin:30px auto;">
<p><%= @code %></p>
</div>
<div style="text-align: center; margin-top:40px;">
<span style="font-weight: normal;color:#666;">
此邮件为系统所发,请勿直接回复。<br/>
要解决问题或了解您的帐户详情,您可以访问 <a href="https://www.educoder.net/help?index=5" style="font-weight: normal; color:#ff7500;">帮助中心</a>。
</span>
</div>
<p style="color:#666; margin-top:30px;">
如果您并未发过此请求,则可能是因为其他用户在注册时误输了您的邮件地址,而使您收到了这封邮件,那么您可以放心的忽略此邮件,无需进一步采取任何操作。
</p>
</div>
<div style="padding:20px; color:#333; line-height: 1.9;background:#46484c;border:1px solid #ddd; border-top:none; width: 558px;">
<a href="https:///www.educoder.net/" style="font-weight: normal; color:#fff;">www.educoder.net</a>

@ -1,6 +1,8 @@
admins-mirror_scripts: 'admins-mirror_repositories'
admins-laboratory_settings: 'admins-laboratories'
admins-carousels: 'admins-laboratories'
admins-laboratory_shixuns: 'admins-laboratories'
admins-laboratory_subjects: 'admins-laboratories'
admins-competition_settings: 'admins-competitions'
admins-enroll_lists: 'admins-competitions'
admins-competition_prize_users: 'admins-competitions'

@ -381,6 +381,8 @@ Rails.application.routes.draw do
get 'work_score'
get 'act_score'
get 'statistics'
post :inform_up
post :inform_down
end
collection do
@ -1032,12 +1034,30 @@ Rails.application.routes.draw do
post :replace_image_url, on: :member
end
resources :laboratories, only: [:index, :create, :destroy] do
member do
get :shixuns_for_select
get :subjects_for_select
end
resource :laboratory_setting, only: [:show, :update]
resource :laboratory_user, only: [:create, :destroy]
resources :carousels, only: [:index, :create, :update, :destroy] do
post :drag, on: :collection
end
resources :laboratory_shixuns, only: [:index, :create] do
member do
post :homepage
post :cancel_homepage
end
end
resources :laboratory_subjects, only: [:index, :create] do
member do
post :homepage
post :cancel_homepage
end
end
end
resources :competitions, only: [:index, :destroy, :create] do
@ -1101,12 +1121,25 @@ Rails.application.routes.draw do
namespace :cooperative do
# get '/', to: 'dashboards#show'
get '/', to: 'laboratory_settings#edit'
resources :files, only: [:create]
resources :users, only: [:index]
resources :laboratory_users, only: [:index, :create, :destroy]
resource :laboratory_setting, only: [:edit, :update]
resources :carousels, only: [:index, :create, :update, :destroy] do
post :drag, on: :collection
end
resources :laboratory_shixuns, only: [:index, :edit, :update] do
member do
post :homepage
post :cancel_homepage
end
end
resources :laboratory_subjects, only: [:index, :edit, :update] do
member do
post :homepage
post :cancel_homepage
end
end
end
resources :colleges, only: [] do

@ -4,4 +4,5 @@
:queues:
- [default, 3]
- [searchkick, 10]
- [notify, 100]
- [notify, 100]
- [mailers, 101]

@ -0,0 +1,13 @@
class CreateLaboratoryShixuns < ActiveRecord::Migration[5.2]
def change
create_table :laboratory_shixuns do |t|
t.references :laboratory
t.references :shixun
t.boolean :ownership, default: false
t.boolean :homepage, default: false
t.timestamps
end
end
end

@ -0,0 +1,17 @@
class AddPositionForInforms < ActiveRecord::Migration[5.2]
def change
add_column :informs, :position, :integer, :default => 1
course_ids = Inform.where(container_type: 'Course').pluck(:container_id).uniq
courses = Course.where(id: course_ids)
courses.find_each do |course|
next if course.informs.count == 1
informs = course.informs.order("created_at asc")
informs.each_with_index do |inform, index|
inform.update_attribute(:position, index+1)
end
end
end
end

@ -0,0 +1,13 @@
class CreateLaboratorySubjects < ActiveRecord::Migration[5.2]
def change
create_table :laboratory_subjects do |t|
t.references :laboratory
t.references :subject
t.boolean :ownership, default: false
t.boolean :homepage, default: false
t.timestamps
end
end
end

@ -0,0 +1,5 @@
class AddEmailNotifyToMessages < ActiveRecord::Migration[5.2]
def change
add_column :messages, :email_notify, :boolean, default: 0
end
end

@ -0,0 +1,6 @@
class AddColumnToExerciseUserScore < ActiveRecord::Migration[5.2]
def change
add_column :exercise_user_scores, :subjective_score, :float, default: 0
add_column :exercise_user_scores, :objective_score, :float, default: 0
end
end

@ -0,0 +1,6 @@
class ModifyDescriotionLimitForHacks < ActiveRecord::Migration[5.2]
def change
change_column :trustie_hackathons, :description, :text
change_column :trustie_hacks, :description, :text
end
end

File diff suppressed because one or more lines are too long

@ -137693,6 +137693,283 @@ $(document).on('turbolinks:load', function() {
});
}
});
$(document).on('turbolinks:load', function() {
if ($('body.admins-laboratory-shixuns-index-page').length > 0) {
var $searchForm = $('.laboratory-shixun-list-form .search-form');
var laboratoryId = $('.laboratory-shixun-list-container').data('id');
$searchForm.find('select#tag_id').select2({
placeholder: "请选择",
allowClear: true
});
// 定义状态切换监听事件
var defineStatusChangeFunc = function (doElement, undoElement, url, callback) {
$('.laboratory-shixun-list-container').on('click', doElement, function () {
var $doAction = $(this);
var $undoAction = $doAction.siblings(undoElement);
var laboratoryShixunId = $doAction.data('id');
customConfirm({
content: '确认进行该操作吗?',
ok: function () {
$.ajax({
url: '/admins/laboratories/' + laboratoryId + '/laboratory_shixuns/' + laboratoryShixunId + url,
method: 'POST',
dataType: 'json',
success: function () {
show_success_flash();
$doAction.hide();
$undoAction.show();
if (callback && typeof callback === "function") {
callback(laboratoryShixunId, url);
}
}
});
}
});
});
}
// 首页展示与取消首页展示
var homepageShowCallback = function (laboratoryShixunId, url) {
var $laboratoryShixunItem = $('.laboratory-shixun-list-container').find('.laboratory-shixun-item-' + laboratoryShixunId);
if (url === '/homepage') {
$laboratoryShixunItem.find('.homepage-badge').show();
} else {
$laboratoryShixunItem.find('.homepage-badge').hide();
}
}
defineStatusChangeFunc('.homepage-show-action', '.homepage-hide-action', '/homepage', homepageShowCallback);
defineStatusChangeFunc('.homepage-hide-action', '.homepage-show-action', '/cancel_homepage', homepageShowCallback);
// 添加实训功能
var $addModal = $('.modal.admin-add-laboratory-shixun-modal');
var $addForm = $addModal.find('form.admin-add-laboratory-user-form');
var $shixunSelect = $addForm.find('select.shixun-select');
$addModal.on('show.bs.modal', function(){
$addModal.find('.error').html('');
$shixunSelect.select2('val', ' ');
});
$shixunSelect.select2({
theme: 'bootstrap4',
placeholder: '请输入实训名称/创建者检索',
multiple: true,
closeOnSelect: false,
ajax: {
delay: 500,
url: '/admins/laboratories/' + laboratoryId + '/shixuns_for_select',
dataType: 'json',
data: function(params){
return { keyword: params.term, page: params.page || 1, per_page: 20 };
},
processResults: function(data, params){
params.page = params.page || 1;
return {
results: data.shixuns,
pagination: {
more: (params.page * 20) < data.count
}
};
}
},
templateResult: function (item) {
if(!item.id || item.id === '') return item.text;
var ele = '<span>'
ele += '<span>' + item.name + '</span>';
ele += '<span class="font-12"> -- ' + item.creator_name + '</span>';
ele += '<span class="font-12"> -- ' + item.status_text+ '</span>';
ele += '</span>';
return $(ele);
},
templateSelection: function(item){
if (item.id) {
}
var ele = '<span>' + (item.name || item.text) + '<span class="font-12"> -- ' + item.creator_name + '</span></span>'
return $(ele);
}
});
$addModal.on('click', '.submit-btn', function(){
$addModal.find('.error').html('');
var shixunIds = $shixunSelect.val();
if (shixunIds && shixunIds.length > 0) {
$.ajax({
method: 'POST',
dataType: 'json',
url: '/admins/laboratories/' + laboratoryId + '/laboratory_shixuns',
data: { shixun_ids: shixunIds },
success: function(){
show_success_flash();
window.location.reload();
},
error: function(res){
$addModal.find('.error').html(res.responseJSON.message);
}
});
} else {
$addModal.find('.error').html('请选择实训');
}
});
}
})
;
$(document).on('turbolinks:load', function() {
if ($('body.admins-laboratory-subjects-index-page').length > 0) {
var $searchForm = $('.laboratory-subject-list-form .search-form');
var laboratoryId = $('.laboratory-subject-list-container').data('id');
// ************** 学校选择 *************
$searchForm.find('.school-select').select2({
theme: 'bootstrap4',
placeholder: '请选择创建者单位',
allowClear: true,
minimumInputLength: 1,
ajax: {
delay: 500,
url: '/api/schools/search.json',
dataType: 'json',
data: function (params) {
return {keyword: params.term};
},
processResults: function (data) {
return {results: data.schools}
}
},
templateResult: function (item) {
if (!item.id || item.id === '') return item.text;
return item.name;
},
templateSelection: function (item) {
if (item.id) {
}
return item.name || item.text;
}
});
// 定义状态切换监听事件
var defineStatusChangeFunc = function (doElement, undoElement, url, callback) {
$('.laboratory-subject-list-container').on('click', doElement, function () {
var $doAction = $(this);
var $undoAction = $doAction.siblings(undoElement);
var laboratorySubjectId = $doAction.data('id');
customConfirm({
content: '确认进行该操作吗?',
ok: function () {
$.ajax({
url: '/admins/laboratories/' + laboratoryId + '/laboratory_subjects/' + laboratorySubjectId + url,
method: 'POST',
dataType: 'json',
success: function () {
show_success_flash();
$doAction.hide();
$undoAction.show();
if (callback && typeof callback === "function") {
callback(laboratorySubjectId, url);
}
}
});
}
});
});
}
// 首页展示与取消首页展示
var homepageShowCallback = function (laboratoryShixunId, url) {
var $laboratoryShixunItem = $('.laboratory-subject-list-container').find('.laboratory-subject-item-' + laboratoryShixunId);
if (url === '/homepage') {
$laboratoryShixunItem.find('.homepage-badge').show();
} else {
$laboratoryShixunItem.find('.homepage-badge').hide();
}
}
defineStatusChangeFunc('.homepage-show-action', '.homepage-hide-action', '/homepage', homepageShowCallback);
defineStatusChangeFunc('.homepage-hide-action', '.homepage-show-action', '/cancel_homepage', homepageShowCallback);
// 添加实践课程功能
var $addModal = $('.modal.admin-add-laboratory-subject-modal');
var $addForm = $addModal.find('form.admin-add-laboratory-user-form');
var $subjectSelect = $addForm.find('select.subject-select');
$addModal.on('show.bs.modal', function(){
$addModal.find('.error').html('');
$subjectSelect.select2('val', ' ');
});
$subjectSelect.select2({
theme: 'bootstrap4',
placeholder: '请输入课程名称/创建者检索',
multiple: true,
closeOnSelect: false,
ajax: {
delay: 500,
url: '/admins/laboratories/' + laboratoryId + '/subjects_for_select',
dataType: 'json',
data: function(params){
return { keyword: params.term, page: params.page || 1, per_page: 20 }
},
processResults: function(data, params){
params.page = params.page || 1;
return {
results: data.subjects,
pagination: {
more: (params.page * 20) < data.count
}
};
}
},
templateResult: function (item) {
if(!item.id || item.id === '') return item.text;
var ele = '<span>'
ele += '<span>' + item.name + '</span>';
ele += '<span class="font-12"> -- ' + item.creator_name + '</span>';
ele += '<span class="font-12"> -- ' + item.status_text+ '</span>';
ele += '</span>';
return $(ele);
},
templateSelection: function(item){
if (item.id) {
}
var ele = '<span>' + (item.name || item.text) + '<span class="font-12"> -- ' + item.creator_name + '</span></span>'
return $(ele);
}
});
$addModal.on('click', '.submit-btn', function(){
$addModal.find('.error').html('');
var subjectIds = $subjectSelect.val();
if (subjectIds && subjectIds.length > 0) {
$.ajax({
method: 'POST',
dataType: 'json',
url: '/admins/laboratories/' + laboratoryId + '/laboratory_subjects',
data: { subject_ids: subjectIds },
success: function(){
show_success_flash();
window.location.reload();
},
error: function(res){
$addModal.find('.error').html(res.responseJSON.message);
}
});
} else {
$addModal.find('.error').html('请选择课程');
}
});
}
})
;
$(document).on('turbolinks:load', function() {
if ($('body.admins-library-applies-index-page').length > 0) {
var $searchFrom = $('.library-applies-list-form');

@ -25487,17 +25487,28 @@ input.form-control {
height: 300px;
}
/* line 51, app/assets/stylesheets/admins/common.scss */
/* line 50, app/assets/stylesheets/admins/common.scss */
.admin-body-container .image-preview-container {
display: -webkit-box;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
flex-direction: column;
-webkit-box-align: center;
align-items: center;
}
/* line 57, app/assets/stylesheets/admins/common.scss */
.admin-body-container .action-container > .action {
padding: 0 3px;
}
/* line 56, app/assets/stylesheets/admins/common.scss */
/* line 62, app/assets/stylesheets/admins/common.scss */
.admin-body-container .action-container .more-action-dropdown .dropdown-item {
font-size: 14px;
}
/* line 63, app/assets/stylesheets/admins/common.scss */
/* line 69, app/assets/stylesheets/admins/common.scss */
.admin-body-container .paginate-container {
margin-top: 20px;
display: -webkit-box;
@ -25511,68 +25522,68 @@ input.form-control {
align-items: center;
}
/* line 70, app/assets/stylesheets/admins/common.scss */
/* line 76, app/assets/stylesheets/admins/common.scss */
.admin-body-container .paginate-container .paginate-total {
margin-bottom: 10px;
color: darkgrey;
}
/* line 75, app/assets/stylesheets/admins/common.scss */
/* line 81, app/assets/stylesheets/admins/common.scss */
.admin-body-container .paginate-container .pagination {
margin-bottom: 0px;
}
/* line 81, app/assets/stylesheets/admins/common.scss */
/* line 87, app/assets/stylesheets/admins/common.scss */
.admin-body-container .search-form-container {
display: -webkit-box;
display: flex;
margin-bottom: 20px;
}
/* line 85, app/assets/stylesheets/admins/common.scss */
/* line 91, app/assets/stylesheets/admins/common.scss */
.admin-body-container .search-form-container .search-form {
-webkit-box-flex: 1;
flex: 1;
}
/* line 88, app/assets/stylesheets/admins/common.scss */
/* line 94, app/assets/stylesheets/admins/common.scss */
.admin-body-container .search-form-container .search-form * {
font-size: 14px;
}
/* line 90, app/assets/stylesheets/admins/common.scss */
/* line 96, app/assets/stylesheets/admins/common.scss */
.admin-body-container .search-form-container .search-form select, .admin-body-container .search-form-container .search-form input {
margin-right: 10px;
font-size: 14px;
}
/* line 97, app/assets/stylesheets/admins/common.scss */
/* line 103, app/assets/stylesheets/admins/common.scss */
.admin-body-container .global-error {
color: grey;
min-height: 300px;
}
/* line 101, app/assets/stylesheets/admins/common.scss */
/* line 107, app/assets/stylesheets/admins/common.scss */
.admin-body-container .global-error-code {
font-size: 80px;
}
/* line 105, app/assets/stylesheets/admins/common.scss */
/* line 111, app/assets/stylesheets/admins/common.scss */
.admin-body-container .global-error-text {
font-size: 24px;
}
/* line 111, app/assets/stylesheets/admins/common.scss */
/* line 117, app/assets/stylesheets/admins/common.scss */
.admin-body-container .nav-tabs .nav-link {
padding: 0.5rem 2rem;
}
/* line 116, app/assets/stylesheets/admins/common.scss */
/* line 122, app/assets/stylesheets/admins/common.scss */
.admin-body-container .CodeMirror {
border: 1px solid #ced4da;
}
/* line 120, app/assets/stylesheets/admins/common.scss */
/* line 126, app/assets/stylesheets/admins/common.scss */
.admin-body-container .batch-action-container {
margin-bottom: -15px;
padding: 10px 20px 0;

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save