合并阿里云

mast_item_banktwo
杨树林 5 years ago
commit 6cafefe3bc

2
.gitignore vendored

@ -43,7 +43,7 @@
/public/react/config/stats.json /public/react/config/stats.json
/public/react/stats.json /public/react/stats.json
/public/react/.idea/* /public/react/.idea/*
/public/h5build
/public/npm-debug.log /public/npm-debug.log
# avatars # avatars

@ -1,31 +1,42 @@
$(document).on('turbolinks:load', function() { $(document).on('turbolinks:load', function () {
$('.admin-modal-container').on('show.bs.modal', '.modal.admin-edit-discipline-modal', function(){ $('.admin-modal-container').on('show.bs.modal', '.modal.admin-edit-discipline-modal', function () {
var $modal = $('.modal.admin-edit-discipline-modal'); var $modal = $('.modal.admin-edit-discipline-modal');
var $form = $modal.find('form.admin-edit-discipline-form'); var $form = $modal.find('form.admin-edit-discipline-form');
$form.validate({ $form.validate({
errorElement: 'span', errorElement: 'span',
errorClass: 'danger text-danger', errorClass: 'danger text-danger',
rules: { rules: {
'discipline[name]': { 'discipline[name]': {
required: true, required: true,
maxlength: 20 maxlength: 20
} }
} }
}); });
$modal.on('click', '.submit-btn', function(){ $modal.on('click', '.submit-btn', submit_edit_form);
$form.find('.error').html('');
var url = $form.attr('action');
if ($form.valid()) { $form.find("#discipline_name").keydown(function (e) {
$.ajax({ var ev = e || event;
method: 'PATCH', var keycode = ev.which || ev.keyCode;
dataType: 'script', if (keycode == 13) {
url: url, submit_edit_form();
data: $form.serialize() return false;
}
}); });
}
function submit_edit_form() {
$form.find('.error').html('');
var url = $form.attr('action');
if ($form.valid()) {
$.ajax({
method: 'PATCH',
dataType: 'script',
url: url,
data: $form.serialize()
});
}
}
}); });
});
}); });

@ -0,0 +1,31 @@
$(document).on('turbolinks:load', function() {
$('.admin-modal-container').on('show.bs.modal', '.modal.admin-edit-repertoire-modal', function(){
var $modal = $('.modal.admin-edit-repertoire-modal');
var $form = $modal.find('form.admin-edit-repertoire-form');
$form.validate({
errorElement: 'span',
errorClass: 'danger text-danger',
rules: {
'repertoire[name]': {
required: true,
maxlength: 20
}
}
});
$modal.on('click', '.submit-btn', function(){
$form.find('.error').html('');
var url = $form.attr('action');
if ($form.valid()) {
$.ajax({
method: 'PATCH',
dataType: 'script',
url: url,
data: $form.serialize()
});
}
});
});
});

@ -1,31 +1,43 @@
$(document).on('turbolinks:load', function() { $(document).on('turbolinks:load', function () {
$('.admin-modal-container').on('show.bs.modal', '.modal.admin-edit-sub-discipline-modal', function(){ $('.admin-modal-container').on('show.bs.modal', '.modal.admin-edit-sub-discipline-modal', function () {
var $modal = $('.modal.admin-edit-sub-discipline-modal'); var $modal = $('.modal.admin-edit-sub-discipline-modal');
var $form = $modal.find('form.admin-edit-sub-discipline-form'); var $form = $modal.find('form.admin-edit-sub-discipline-form');
$form.validate({ $form.validate({
errorElement: 'span', errorElement: 'span',
errorClass: 'danger text-danger', errorClass: 'danger text-danger',
rules: { rules: {
'sub_discipline[name]': { 'sub_discipline[name]': {
required: true, required: true,
maxlength: 20 maxlength: 20
} }
} }
}); });
$modal.on('click', '.submit-btn', function(){ $modal.on('click', '.submit-btn', submit_edit_form);
$form.find('.error').html('');
var url = $form.attr('action');
if ($form.valid()) { $form.find("#sub_discipline_name").keydown(function (e) {
$.ajax({ var ev = e || event;
method: 'PATCH', var keycode = ev.which || ev.keyCode;
dataType: 'script', if (keycode == 13) {
url: url, submit_edit_form();
data: $form.serialize() return false;
}
}); });
}
function submit_edit_form() {
$form.find('.error').html('');
var url = $form.attr('action');
if ($form.valid()) {
$.ajax({
method: 'PATCH',
dataType: 'script',
url: url,
data: $form.serialize()
});
}
}
}); });
});
}); });

@ -0,0 +1,31 @@
$(document).on('turbolinks:load', function() {
$('.admin-modal-container').on('show.bs.modal', '.modal.admin-edit-sub-repertoire-modal', function(){
var $modal = $('.modal.admin-edit-sub-repertoire-modal');
var $form = $modal.find('form.admin-edit-sub-repertoire-form');
$form.validate({
errorElement: 'span',
errorClass: 'danger text-danger',
rules: {
'sub_repertoire[name]': {
required: true,
maxlength: 20
}
}
});
$modal.on('click', '.submit-btn', function(){
$form.find('.error').html('');
var url = $form.attr('action');
if ($form.valid()) {
$.ajax({
method: 'PATCH',
dataType: 'script',
url: url,
data: $form.serialize()
});
}
});
});
});

@ -1,31 +1,42 @@
$(document).on('turbolinks:load', function() { $(document).on('turbolinks:load', function () {
$('.admin-modal-container').on('show.bs.modal', '.modal.admin-edit-tag-discipline-modal', function(){ $('.admin-modal-container').on('show.bs.modal', '.modal.admin-edit-tag-discipline-modal', function () {
var $modal = $('.modal.admin-edit-tag-discipline-modal'); var $modal = $('.modal.admin-edit-tag-discipline-modal');
var $form = $modal.find('form.admin-edit-tag-discipline-form'); var $form = $modal.find('form.admin-edit-tag-discipline-form');
$form.validate({ $form.validate({
errorElement: 'span', errorElement: 'span',
errorClass: 'danger text-danger', errorClass: 'danger text-danger',
rules: { rules: {
'tag_discipline[name]': { 'tag_discipline[name]': {
required: true, required: true,
maxlength: 20 maxlength: 20
} }
} }
}); });
$modal.on('click', '.submit-btn', function(){ $modal.on('click', '.submit-btn', submit_edit_form);
$form.find('.error').html('');
var url = $form.attr('action');
if ($form.valid()) { $form.find("#tag_discipline_name").keydown(function (e) {
$.ajax({ var ev = e || event;
method: 'PATCH', var keycode = ev.which || ev.keyCode;
dataType: 'script', if (keycode == 13) {
url: url, submit_edit_form();
data: $form.serialize() return false;
}
}); });
}
function submit_edit_form() {
$form.find('.error').html('');
var url = $form.attr('action');
if ($form.valid()) {
$.ajax({
method: 'PATCH',
dataType: 'script',
url: url,
data: $form.serialize()
});
}
}
}); });
});
}); });

@ -0,0 +1,31 @@
$(document).on('turbolinks:load', function() {
$('.admin-modal-container').on('show.bs.modal', '.modal.admin-edit-tag-repertoire-modal', function(){
var $modal = $('.modal.admin-edit-tag-repertoire-modal');
var $form = $modal.find('form.admin-edit-tag-repertoire-form');
$form.validate({
errorElement: 'span',
errorClass: 'danger text-danger',
rules: {
'tag_repertoire[name]': {
required: true,
maxlength: 20
}
}
});
$modal.on('click', '.submit-btn', function(){
$form.find('.error').html('');
var url = $form.attr('action');
if ($form.valid()) {
$.ajax({
method: 'PATCH',
dataType: 'script',
url: url,
data: $form.serialize()
});
}
});
});
});

@ -0,0 +1,65 @@
$(document).on('turbolinks:load', function() {
if ($('body.admins-repertoires-index-page').length > 0) {
// ============== 新建 ===============
var $modal = $('.modal.admin-create-repertoire-modal');
var $form = $modal.find('form.admin-create-repertoire-form');
var $nameInput = $form.find('input[name="name"]');
$form.validate({
errorElement: 'span',
errorClass: 'danger text-danger',
rules: {
name: {
required: true
}
}
});
// modal ready fire
$modal.on('show.bs.modal', function () {
$nameInput.val('');
});
$modal.on('click', '.submit-btn', function(){
$form.find('.error').html('');
if ($form.valid()) {
var url = $form.data('url');
$.ajax({
method: 'POST',
dataType: 'json',
url: url,
data: $form.serialize(),
success: function(){
$.notify({ message: '创建成功' });
$modal.modal('hide');
setTimeout(function(){
window.location.reload();
}, 500);
},
error: function(res){
var data = res.responseJSON;
$form.find('.error').html(data.message);
}
});
}
});
$(".repertoire-list-container").on("change", '.repertoire-source-form', function () {
var s_id = $(this).attr("data-id");
var s_value = $(this).val();
var s_name = $(this).attr("name");
var json = {};
json[s_name] = s_value;
$.ajax({
url: "/admins/repertoires/" + s_id,
type: "PUT",
dataType:'script',
data: json
});
});
}
});

@ -30,9 +30,23 @@ $(document).on('turbolinks:load', function() {
type: "PUT", type: "PUT",
dataType:'script', dataType:'script',
data: json data: json
}) });
}); });
$(".shixun-settings-list-container").on("change", '.repertoire-setting-form', function () {
var s_id = $(this).attr("data-id");
var s_value = $(this).val();
var s_name = $(this).attr("name");
var json = {};
json[s_name] = s_value;
$.ajax({
url: "/admins/shixun_settings/" + s_id + "/update_tag_repertoires",
type: "POST",
dataType:'script',
data: json
});
});
$("select#settings-tag-choosed").select2({ $("select#settings-tag-choosed").select2({
placeholder: "请选择分类", placeholder: "请选择分类",
allowClear: true allowClear: true

@ -1,65 +1,76 @@
$(document).on('turbolinks:load', function() { $(document).on('turbolinks:load', function () {
if ($('body.admins-sub-disciplines-index-page').length > 0) { if ($('body.admins-sub-disciplines-index-page').length > 0) {
// ============== 新建 =============== // ============== 新建 ===============
var $modal = $('.modal.admin-create-sub-discipline-modal'); var $modal = $('.modal.admin-create-sub-discipline-modal');
var $form = $modal.find('form.admin-create-sub-discipline-form'); var $form = $modal.find('form.admin-create-sub-discipline-form');
var $nameInput = $form.find('input[name="name"]'); var $nameInput = $form.find('input[name="name"]');
$form.validate({ $form.validate({
errorElement: 'span', errorElement: 'span',
errorClass: 'danger text-danger', errorClass: 'danger text-danger',
rules: { rules: {
name: { name: {
required: true required: true
} }
} }
}); });
// modal ready fire // modal ready fire
$modal.on('show.bs.modal', function () { $modal.on('show.bs.modal', function () {
$nameInput.val(''); $nameInput.val('');
}); });
$modal.on('click', '.submit-btn', function(){ $modal.on('click', '.submit-btn', submit_create_form);
$form.find('.error').html('');
if ($form.valid()) { $nameInput.keydown(function (e) {
var url = $form.data('url'); var ev = e || event;
var keycode = ev.which || ev.keyCode;
if (keycode == 13) {
submit_create_form();
return false;
}
});
$.ajax({ function submit_create_form() {
method: 'POST', $form.find('.error').html('');
dataType: 'json',
url: url,
data: $form.serialize(),
success: function(){
$.notify({ message: '创建成功' });
$modal.modal('hide');
setTimeout(function(){ if ($form.valid()) {
window.location.reload(); var url = $form.data('url');
}, 500);
},
error: function(res){
var data = res.responseJSON;
$form.find('.error').html(data.message);
}
});
}
});
$(".sub-discipline-list-container").on("change", '.sub-discipline-source-form', function () { $.ajax({
var s_id = $(this).attr("data-id"); method: 'POST',
var s_value = $(this).val(); dataType: 'json',
var s_name = $(this).attr("name"); url: url,
var json = {}; data: $form.serialize(),
json[s_name] = s_value; success: function () {
$.ajax({ $.notify({message: '创建成功'});
url: "/admins/sub_disciplines/" + s_id, $modal.modal('hide');
type: "PUT",
dataType:'script', setTimeout(function () {
data: json window.location.reload();
}); }, 500);
}); },
} error: function (res) {
var data = res.responseJSON;
$form.find('.error').html(data.message);
}
});
}
}
$(".sub-discipline-list-container").on("change", '.sub-discipline-source-form', function () {
var s_id = $(this).attr("data-id");
var s_value = $(this).val();
var s_name = $(this).attr("name");
var json = {};
json[s_name] = s_value;
$.ajax({
url: "/admins/sub_disciplines/" + s_id,
type: "PUT",
dataType: 'script',
data: json
});
});
}
}); });

@ -0,0 +1,65 @@
$(document).on('turbolinks:load', function() {
if ($('body.admins-sub-repertoires-index-page').length > 0) {
// ============== 新建 ===============
var $modal = $('.modal.admin-create-sub-repertoire-modal');
var $form = $modal.find('form.admin-create-sub-repertoire-form');
var $nameInput = $form.find('input[name="name"]');
$form.validate({
errorElement: 'span',
errorClass: 'danger text-danger',
rules: {
name: {
required: true
}
}
});
// modal ready fire
$modal.on('show.bs.modal', function () {
$nameInput.val('');
});
$modal.on('click', '.submit-btn', function(){
$form.find('.error').html('');
if ($form.valid()) {
var url = $form.data('url');
$.ajax({
method: 'POST',
dataType: 'json',
url: url,
data: $form.serialize(),
success: function(){
$.notify({ message: '创建成功' });
$modal.modal('hide');
setTimeout(function(){
window.location.reload();
}, 500);
},
error: function(res){
var data = res.responseJSON;
$form.find('.error').html(data.message);
}
});
}
});
$(".sub-repertoire-list-container").on("change", '.sub-repertoire-source-form', function () {
var s_id = $(this).attr("data-id");
var s_value = $(this).val();
var s_name = $(this).attr("name");
var json = {};
json[s_name] = s_value;
$.ajax({
url: "/admins/sub_repertoires/" + s_id,
type: "PUT",
dataType:'script',
data: json
});
});
}
});

@ -0,0 +1,71 @@
$(document).on('turbolinks:load', function () {
if ($('body.admins-subject-settings-index-page').length > 0) {
var $form = $('.subject-setting-list-form');
// ************** 学校选择 *************
$form.find('.school-select').select2({
theme: 'bootstrap4',
placeholder: '请选择创建者单位',
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;
}
});
$(".subject-setting-list-container").on("change", '.subject-setting-form', function () {
var s_id = $(this).attr("data-id");
var s_value = $(this).val();
var s_name = $(this).attr("name");
var json = {};
json[s_name] = s_value;
$.ajax({
url: "/admins/subject_settings/" + s_id,
type: "PUT",
dataType:'script',
data: json
})
});
// 清空
$form.on('click', '.clear-btn', function () {
$form.find('select[name="status"]').val('');
$form.find('.school-select').val('').trigger('change');
$form.find('input[name="keyword"]').val('');
$form.find('#homepage_show').attr('checked', false);
$form.find('#excellent').attr('checked', false);
$form.find('input[type="submit"]').trigger('click');
});
// 上传图片
$('.modal.admin-upload-file-modal').on('upload:success', function (e, data) {
if(data.suffix == '_qrcode'){
var $imageElement = $('.subject-weapp-image-' + data.source_id);
$imageElement.attr('src', data.url);
$imageElement.show();
$imageElement.next().html('重新上传');
} else {
var $imageElement = $('.subject-image-' + data.source_id);
$imageElement.attr('src', data.url);
$imageElement.show();
$imageElement.next().html('重新上传');
}
});
}
});

@ -37,22 +37,8 @@ $(document).on('turbolinks:load', function () {
$form.find('#homepage_show').attr('checked', false); $form.find('#homepage_show').attr('checked', false);
$form.find('#excellent').attr('checked', false); $form.find('#excellent').attr('checked', false);
$form.find('input[type="submit"]').trigger('click'); $form.find('input[type="submit"]').trigger('click');
})
// 上传图片
$('.modal.admin-upload-file-modal').on('upload:success', function (e, data) {
if(data.suffix == '_qrcode'){
var $imageElement = $('.subject-weapp-image-' + data.source_id);
$imageElement.attr('src', data.url);
$imageElement.show();
$imageElement.next().html('重新上传');
} else {
var $imageElement = $('.subject-image-' + data.source_id);
$imageElement.attr('src', data.url);
$imageElement.show();
$imageElement.next().html('重新上传');
}
}); });
// 定义状态切换监听事件 // 定义状态切换监听事件
var defineStatusChangeFunc = function (doElement, undoElement, url, callback) { var defineStatusChangeFunc = function (doElement, undoElement, url, callback) {
$('.subject-list-container').on('click', doElement, function () { $('.subject-list-container').on('click', doElement, function () {

@ -1,65 +1,76 @@
$(document).on('turbolinks:load', function() { $(document).on('turbolinks:load', function () {
if ($('body.admins-tag-disciplines-index-page').length > 0) { if ($('body.admins-tag-disciplines-index-page').length > 0) {
// ============== 新建 =============== // ============== 新建 ===============
var $modal = $('.modal.admin-create-tag-discipline-modal'); var $modal = $('.modal.admin-create-tag-discipline-modal');
var $form = $modal.find('form.admin-create-tag-discipline-form'); var $form = $modal.find('form.admin-create-tag-discipline-form');
var $nameInput = $form.find('input[name="name"]'); var $nameInput = $form.find('input[name="name"]');
$form.validate({ $form.validate({
errorElement: 'span', errorElement: 'span',
errorClass: 'danger text-danger', errorClass: 'danger text-danger',
rules: { rules: {
name: { name: {
required: true required: true
} }
} }
}); });
// modal ready fire // modal ready fire
$modal.on('show.bs.modal', function () { $modal.on('show.bs.modal', function () {
$nameInput.val(''); $nameInput.val('');
}); });
$modal.on('click', '.submit-btn', function(){ $modal.on('click', '.submit-btn', submit_create_form);
$form.find('.error').html('');
if ($form.valid()) { $nameInput.keydown(function (e) {
var url = $form.data('url'); var ev = e || event;
var keycode = ev.which || ev.keyCode;
if (keycode == 13) {
submit_create_form();
return false;
}
});
$.ajax({ function submit_create_form() {
method: 'POST', $form.find('.error').html('');
dataType: 'json',
url: url,
data: $form.serialize(),
success: function(){
$.notify({ message: '创建成功' });
$modal.modal('hide');
setTimeout(function(){ if ($form.valid()) {
window.location.reload(); var url = $form.data('url');
}, 500);
},
error: function(res){
var data = res.responseJSON;
$form.find('.error').html(data.message);
}
});
}
});
$(".tag-discipline-list-container").on("change", '.tag-discipline-source-form', function () { $.ajax({
var s_id = $(this).attr("data-id"); method: 'POST',
var s_value = $(this).val(); dataType: 'json',
var s_name = $(this).attr("name"); url: url,
var json = {}; data: $form.serialize(),
json[s_name] = s_value; success: function () {
$.ajax({ $.notify({message: '创建成功'});
url: "/admins/tag_disciplines/" + s_id, $modal.modal('hide');
type: "PUT",
dataType:'script', setTimeout(function () {
data: json window.location.reload();
}); }, 500);
}); },
} error: function (res) {
var data = res.responseJSON;
$form.find('.error').html(data.message);
}
});
}
}
$(".tag-discipline-list-container").on("change", '.tag-discipline-source-form', function () {
var s_id = $(this).attr("data-id");
var s_value = $(this).val();
var s_name = $(this).attr("name");
var json = {};
json[s_name] = s_value;
$.ajax({
url: "/admins/tag_disciplines/" + s_id,
type: "PUT",
dataType: 'script',
data: json
});
});
}
}); });

@ -0,0 +1,65 @@
$(document).on('turbolinks:load', function() {
if ($('body.admins-tag-repertoires-index-page').length > 0) {
// ============== 新建 ===============
var $modal = $('.modal.admin-create-tag-repertoire-modal');
var $form = $modal.find('form.admin-create-tag-repertoire-form');
var $nameInput = $form.find('input[name="name"]');
$form.validate({
errorElement: 'span',
errorClass: 'danger text-danger',
rules: {
name: {
required: true
}
}
});
// modal ready fire
$modal.on('show.bs.modal', function () {
$nameInput.val('');
});
$modal.on('click', '.submit-btn', function(){
$form.find('.error').html('');
if ($form.valid()) {
var url = $form.data('url');
$.ajax({
method: 'POST',
dataType: 'json',
url: url,
data: $form.serialize(),
success: function(){
$.notify({ message: '创建成功' });
$modal.modal('hide');
setTimeout(function(){
window.location.reload();
}, 500);
},
error: function(res){
var data = res.responseJSON;
$form.find('.error').html(data.message);
}
});
}
});
$(".tag-repertoire-list-container").on("change", '.tag-repertoire-source-form', function () {
var s_id = $(this).attr("data-id");
var s_value = $(this).val();
var s_name = $(this).attr("name");
var json = {};
json[s_name] = s_value;
$.ajax({
url: "/admins/tag_repertoires/" + s_id,
type: "PUT",
dataType:'script',
data: json
});
});
}
});

@ -167,7 +167,7 @@ class AccountsController < ApplicationController
end end
# 检验邮箱是否已被注册及邮箱或者手机号是否合法 # 检验邮箱是否已被注册及邮箱或者手机号是否合法
# 参数type为事件类型 1注册2忘记密码 # 参数type为事件类型 1注册2忘记密码3绑定
def valid_email_and_phone def valid_email_and_phone
check_mail_and_phone_valid(params[:login], params[:type]) check_mail_and_phone_valid(params[:login], params[:type])
end end

@ -16,19 +16,23 @@ class Admins::DisciplinesController < Admins::BaseController
end end
def update def update
if params[:discipline] && params[:discipline][:name].present? begin
name = params[:discipline][:name].to_s.strip if params[:discipline] && params[:discipline][:name]
current_discipline.update_attributes!(name: name) name = params[:discipline][:name].to_s.strip
else current_discipline.update_attributes!(name: name)
ActiveRecord::Base.transaction do else
current_discipline.update_attributes!(setting_params) ActiveRecord::Base.transaction do
current_discipline.sub_disciplines.each do |sub| current_discipline.update_attributes!(setting_params)
sub.tag_disciplines.each do |tag| current_discipline.sub_disciplines.each do |sub|
tag.update_attributes!(setting_params) sub.tag_disciplines.each do |tag|
tag.update_attributes!(setting_params)
end
sub.update_attributes!(setting_params)
end end
sub.update_attributes!(setting_params)
end end
end end
rescue Exception => e
@message = e.message
end end
@disciplines = Discipline.all @disciplines = Discipline.all
end end

@ -0,0 +1,36 @@
class Admins::RepertoiresController < Admins::BaseController
def index
@repertoires = Repertoire.all
end
def edit
@repertoire = current_repertoire
end
def update
Rails.logger.info("#################--------")
if params[:repertoire] && params[:repertoire][:name].present?
name = params[:repertoire][:name].to_s.strip
current_repertoire.update_attributes!(name: name)
end
@repertoires = Repertoire.all
end
def create
name = params[:name].to_s.strip
return render_error('名称重复') if Repertoire.where(name: name).exists?
Repertoire.create!(name: name)
render_ok
end
def destroy
@repertoire_id = params[:id]
current_repertoire.destroy!
end
private
def current_repertoire
@_current_repertoire = Repertoire.find params[:id]
end
end

@ -47,21 +47,23 @@ class Admins::ShixunSettingsController < Admins::BaseController
@shixun = Shixun.find_by(id:params[:id]) @shixun = Shixun.find_by(id:params[:id])
@page_no = params[:page_no] || "1" @page_no = params[:page_no] || "1"
@shixun_tags = TagRepertoire.order("name asc").pluck(:name,:id) @shixun_tags = TagRepertoire.order("name asc").pluck(:name,:id)
tag_ids = params[:tag_repertoires] unless @shixun.update_attributes(setting_params)
if tag_ids.present? redirect_to admins_shixun_settings_path
@shixun&.shixun_tag_repertoires.delete_all flash[:danger] = "更新失败"
tag_repertoire_ids = @shixun&.tag_repertoires&.pluck(:id) end
tag_ids.each do |id| end
unless tag_repertoire_ids.include?(id)
tag_repertoire = @shixun.shixun_tag_repertoires.new(shixun_id:@shixun.id,tag_repertoire_id:id) def update_tag_repertoires
tag_repertoire.save! shixun = Shixun.find_by(id:params[:id])
end tag_repertoire_ids = params[:tag_repertoires] || []
end tag_ids = tag_repertoire_ids.reject(&:blank?).map(&:to_i)
else old_tag_ids = shixun.shixun_tag_repertoires.pluck(:tag_repertoire_id)
unless @shixun.update_attributes(setting_params) new_ids = tag_ids - old_tag_ids
redirect_to admins_shixun_settings_path delete_ids = old_tag_ids - tag_ids
flash[:danger] = "更新失败" tag_params = new_ids.map{|sub| {tag_repertoire_id: sub}}
end ActiveRecord::Base.transaction do
shixun.shixun_tag_repertoires.where(tag_repertoire_id: delete_ids).destroy_all
shixun.shixun_tag_repertoires.create!(tag_params)
end end
end end
@ -133,6 +135,6 @@ class Admins::ShixunSettingsController < Admins::BaseController
def setting_params def setting_params
params.permit(:use_scope,:excute_time,:close,:status,:can_copy,:webssh,:hidden,:homepage_show,:task_pass, params.permit(:use_scope,:excute_time,:close,:status,:can_copy,:webssh,:hidden,:homepage_show,:task_pass,
:code_hidden,:vip,:page_no,:id, :is_wechat_support, tag_repertoires:[]) :code_hidden,:vip,:page_no,:id, :is_wechat_support)
end end
end end

@ -7,6 +7,7 @@ class Admins::SubDisciplinesController < Admins::BaseController
def create def create
name = params[:name].to_s.strip name = params[:name].to_s.strip
return render_error('名称不能为空') if name.blank?
return render_error('名称重复') if current_discipline.sub_disciplines.where(name: name).exists? return render_error('名称重复') if current_discipline.sub_disciplines.where(name: name).exists?
SubDiscipline.create!(name: name, discipline_id: current_discipline.id) SubDiscipline.create!(name: name, discipline_id: current_discipline.id)
render_ok render_ok
@ -17,16 +18,20 @@ class Admins::SubDisciplinesController < Admins::BaseController
end end
def update def update
if params[:sub_discipline] && params[:sub_discipline][:name].present? begin
name = params[:sub_discipline][:name].to_s.strip if params[:sub_discipline] && params[:sub_discipline][:name]
current_sub_discipline.update_attributes!(name: name) name = params[:sub_discipline][:name].to_s.strip
else current_sub_discipline.update_attributes!(name: name)
ActiveRecord::Base.transaction do else
current_sub_discipline.update_attributes!(setting_params) ActiveRecord::Base.transaction do
current_sub_discipline.tag_disciplines.each do |tag| current_sub_discipline.update_attributes!(setting_params)
tag.update_attributes!(setting_params) current_sub_discipline.tag_disciplines.each do |tag|
tag.update_attributes!(setting_params)
end
end end
end end
rescue Exception => e
@message = e.message
end end
@sub_disciplines = current_sub_discipline.discipline&.sub_disciplines @sub_disciplines = current_sub_discipline.discipline&.sub_disciplines
end end

@ -0,0 +1,45 @@
class Admins::SubRepertoiresController < Admins::BaseController
def index
@repertoire = current_repertoire
@sub_repertoires = current_repertoire.sub_repertoires
end
def create
name = params[:name].to_s.strip
return render_error('名称重复') if current_repertoire.sub_repertoires.where(name: name).exists?
SubRepertoire.create!(name: name, repertoire_id: current_repertoire.id)
render_ok
end
def edit
@sub_repertoire = current_sub_repertoire
end
def update
if params[:sub_repertoire] && params[:sub_repertoire][:name].present?
name = params[:sub_repertoire][:name].to_s.strip
current_sub_repertoire.update_attributes!(name: name)
end
@sub_repertoires = current_sub_repertoire.repertoire&.sub_repertoires
end
def destroy
@sub_repertoire_id = params[:id]
current_sub_repertoire.destroy!
end
private
def current_sub_repertoire
@_current_sub_repertoire = SubRepertoire.find params[:id]
end
def current_repertoire
@_current_repertoire = Repertoire.find params[:repertoire_id]
end
def setting_params
params.permit(:shixun, :subject, :question)
end
end

@ -0,0 +1,29 @@
class Admins::SubjectSettingsController < Admins::BaseController
def index
default_sort('created_at', 'desc')
subjects = Admins::SubjectQuery.call(params)
@sub_disciplines = SubDiscipline.where(subject: 1).pluck(:name,:id)
@subjects = paginate subjects.includes(:repertoire, :subject_level_system, :sub_disciplines)
end
def update
sub_discipline_ids = params[:sub_disciplines] || []
sub_ids = sub_discipline_ids.reject(&:blank?).map(&:to_i)
old_sub_ids = current_subject.sub_discipline_containers.pluck(:sub_discipline_id)
new_ids = sub_ids - old_sub_ids
delete_ids = old_sub_ids - sub_ids
sub_params = new_ids.map{|sub| {sub_discipline_id: sub}}
ActiveRecord::Base.transaction do
current_subject.sub_discipline_containers.where(sub_discipline_id: delete_ids).destroy_all
current_subject.sub_discipline_containers.create!(sub_params)
end
end
private
def current_subject
@_current_subject ||= Subject.find(params[:id])
end
end

@ -3,7 +3,7 @@ class Admins::SubjectsController < Admins::BaseController
default_sort('created_at', 'desc') default_sort('created_at', 'desc')
subjects = Admins::SubjectQuery.call(params) subjects = Admins::SubjectQuery.call(params)
@subjects = paginate subjects.includes(:repertoire, :subject_level_system, user: { user_extension: :school }) @subjects = paginate subjects.includes(user: { user_extension: :school })
end end
def edit def edit
@ -14,7 +14,7 @@ class Admins::SubjectsController < Admins::BaseController
current_subject.update!(update_params) current_subject.update!(update_params)
flash[:success] = '保存成功' flash[:success] = '保存成功'
redirect_to admins_subjects_path redirect_to admins_subject_settings_path
end end
def destroy def destroy

@ -17,11 +17,15 @@ class Admins::TagDisciplinesController < Admins::BaseController
end end
def update def update
if params[:tag_discipline] && params[:tag_discipline][:name].present? begin
name = params[:tag_discipline][:name].to_s.strip if params[:tag_discipline] && params[:tag_discipline][:name]
current_tag_discipline.update_attributes!(name: name) name = params[:tag_discipline][:name].to_s.strip
else current_tag_discipline.update_attributes!(name: name)
current_tag_discipline.update_attributes!(setting_params) else
current_tag_discipline.update_attributes!(setting_params)
end
rescue Exception => e
@message = e.message
end end
@tag_disciplines = current_tag_discipline.sub_discipline&.tag_disciplines @tag_disciplines = current_tag_discipline.sub_discipline&.tag_disciplines
end end

@ -0,0 +1,43 @@
class Admins::TagRepertoiresController < Admins::BaseController
def index
@sub_repertoire = current_sub_repertoire
@tag_repertoires = current_sub_repertoire.tag_repertoires
end
def create
name = params[:name].to_s.strip
return render_error('名称重复') if current_sub_repertoire.tag_repertoires.where(name: name).exists?
TagRepertoire.create!(name: name, sub_repertoire_id: current_sub_repertoire.id)
render_ok
end
def edit
@tag_repertoire = current_tag_repertoire
end
def update
if params[:tag_repertoire] && params[:tag_repertoire][:name].present?
name = params[:tag_repertoire][:name].to_s.strip
current_tag_repertoire.update_attributes!(name: name)
end
@tag_repertoires = current_tag_repertoire.sub_repertoire&.tag_repertoires
end
def destroy
@tag_repertoire_id = params[:id]
current_tag_repertoire.destroy!
end
private
def current_sub_repertoire
@_current_sub_repertoire = SubRepertoire.find params[:sub_repertoire_id]
end
def current_tag_repertoire
@_current_tag_repertoire = TagRepertoire.find params[:id]
end
end

@ -92,7 +92,7 @@ class ApplicationController < ActionController::Base
# 判断用户的邮箱或者手机是否可用 # 判断用户的邮箱或者手机是否可用
# params[:type] 1: 注册2忘记密码 # params[:type] 1: 注册2忘记密码3绑定
def check_mail_and_phone_valid login, type def check_mail_and_phone_valid login, type
unless login =~ /^[a-zA-Z0-9]+([._\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/ || login =~ /^1\d{10}$/ || unless login =~ /^[a-zA-Z0-9]+([._\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/ || login =~ /^1\d{10}$/ ||
login =~ /^[a-zA-Z0-9]+([._\\]*[a-zA-Z0-9])$/ login =~ /^[a-zA-Z0-9]+([._\\]*[a-zA-Z0-9])$/
@ -104,6 +104,8 @@ class ApplicationController < ActionController::Base
tip_exception(-2, "该手机号码或邮箱已被注册") tip_exception(-2, "该手机号码或邮箱已被注册")
elsif type.to_i == 2 && user.nil? elsif type.to_i == 2 && user.nil?
tip_exception(-2, "该手机号码或邮箱未注册") tip_exception(-2, "该手机号码或邮箱未注册")
elsif type.to_i == 3 && user.present?
tip_exception(-2, "该手机号码或邮箱已绑定")
end end
sucess_status sucess_status
end end
@ -218,7 +220,7 @@ class ApplicationController < ActionController::Base
# 未授权的捕捉407弹试用申请弹框 # 未授权的捕捉407弹试用申请弹框
def require_login def require_login
#6.13 -hs #6.13 -hs
tip_exception(401, "..") unless User.current.logged? tip_exception(401, "请登录后再操作") unless User.current.logged?
end end
# 异常提醒 # 异常提醒
@ -632,7 +634,8 @@ class ApplicationController < ActionController::Base
end end
def paginate(relation) def paginate(relation)
limit = (params[:limit].to_i.zero? || params[:limit].to_i > 20) ? 20 : params[:limit].to_i limit = params[:limit] || params[:per_page]
limit = (limit.to_i.zero? || limit.to_i > 20) ? 20 : limit.to_i
page = params[:page].to_i.zero? ? 1 : params[:page].to_i page = params[:page].to_i.zero? ? 1 : params[:page].to_i
offset = (page - 1) * limit offset = (page - 1) * limit
@ -643,6 +646,8 @@ class ApplicationController < ActionController::Base
end end
end end
def strf_time(time) def strf_time(time)
time.blank? ? '' : time.strftime("%Y-%m-%d %H:%M:%S") time.blank? ? '' : time.strftime("%Y-%m-%d %H:%M:%S")
end end

@ -17,9 +17,11 @@ class AttachmentsController < ApplicationController
redirect_to @file.cloud_url and return redirect_to @file.cloud_url and return
end end
pdf_attachment = params[:disposition] || "attachment" type_attachment = params[:disposition] || "attachment"
if pdf_attachment == "inline" if type_attachment == "inline"
send_file absolute_path(local_path(@file)),filename: @file.title, disposition: 'inline',type: 'application/pdf' send_file absolute_path(local_path(@file)),filename: @file.title, disposition: 'inline',type: 'application/pdf'
elsif type_attachment == "MP4"
send_file_with_range absolute_path(local_path(@file)), disposition: 'inline', type: "video/mp4", range: true
else else
send_file(absolute_path(local_path(@file)), filename: @file.title,stream:false, type: @file.content_type.presence || 'application/octet-stream') send_file(absolute_path(local_path(@file)), filename: @file.title,stream:false, type: @file.content_type.presence || 'application/octet-stream')
end end
@ -202,4 +204,31 @@ class AttachmentsController < ApplicationController
end end
end end
def send_file_with_range(path, options = {})
logger.info("########request.headers: #{request.headers}")
logger.info("########request.headers: #{File.exist?(path)}")
if File.exist?(path)
size = File.size(path)
logger.info("########request.headers: #{request.headers}")
if !request.headers["Range"]
status_code = 200 # 200 OK
offset = 0
length = File.size(path)
else
status_code = 206 # 206 Partial Content
bytes = Rack::Utils.byte_ranges(request.headers, size)[0]
offset = bytes.begin
length = bytes.end - bytes.begin
end
response.header["Accept-Ranges"] = "bytes"
response.header["Content-Range"] = "bytes #{bytes.begin}-#{bytes.end}/#{size}" if bytes
response.header["status"] = status_code
send_data IO.binread(path, length, offset), options
else
raise ActionController::MissingFile, "Cannot read file #{path}."
end
end
end end

@ -181,7 +181,7 @@ class ChallengesController < ApplicationController
begin begin
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
tab = params[:tab].to_i tab = params[:tab].to_i
@challenge.update_attributes(challenge_params) @challenge.update_attributes!(challenge_params)
if tab == 0 && @challenge.st == 0 if tab == 0 && @challenge.st == 0
@challenge.challenge_tags.delete_all @challenge.challenge_tags.delete_all
if params[:challenge_tag].present? if params[:challenge_tag].present?
@ -211,7 +211,7 @@ class ChallengesController < ApplicationController
# last 末尾匹配, full: 全完匹配 # last 末尾匹配, full: 全完匹配
logger.info("set: #{set}; match_rule : #{set[:match_rule]}") logger.info("set: #{set}; match_rule : #{set[:match_rule]}")
match_rule = set[:match_rule] == 'last' ? 'last' : 'full' match_rule = set[:match_rule] == 'last' ? 'last' : 'full'
TestSet.create(:challenge_id => @challenge.id, TestSet.create!(:challenge_id => @challenge.id,
:input => "#{set[:input]}", :input => "#{set[:input]}",
:output => "#{set[:output]}", :output => "#{set[:output]}",
:is_public => params_hidden[index], :is_public => params_hidden[index],
@ -227,8 +227,11 @@ class ChallengesController < ApplicationController
@challenge.update_attributes(picture_path: nil, web_route: nil, expect_picture_path: nil, original_picture_path: nil) @challenge.update_attributes(picture_path: nil, web_route: nil, expect_picture_path: nil, original_picture_path: nil)
end end
# 关卡评测执行文件如果被修改,需要修改脚本内容 # 关卡评测执行文件如果被修改,需要修改脚本内容
script = modify_shixun_script @shixun, @shixun.evaluate_script logger.info("############shixun_publiced:#{@shixun.public == 0}")
@shixun.shixun_info.update_column(:evaluate_script, script) if @shixun.public == 0
script = modify_shixun_script @shixun, @shixun.evaluate_script
@shixun.shixun_info.update_column(:evaluate_script, script)
end
# TODO: # TODO:
# if path != params[:challenge][:path] # if path != params[:challenge][:path]
# shixun_modify_status_without_publish(@shixun, 1) # shixun_modify_status_without_publish(@shixun, 1)
@ -237,9 +240,9 @@ class ChallengesController < ApplicationController
end end
end end
rescue => e rescue Exception => e
logger_error("##update_challenges: ##{e.message}") logger.error("##update_challenges: ##{e.message}")
tip_exception("更新失败!") tip_exception("#{e.message}")
end end
end end
@ -262,7 +265,7 @@ class ChallengesController < ApplicationController
params[:challenge_answer].each_with_index do |answer, index| params[:challenge_answer].each_with_index do |answer, index|
# 内容为空不保存 # 内容为空不保存
next if answer[:contents].blank? next if answer[:contents].blank?
ChallengeAnswer.create(name: answer[:name], contents: answer[:contents], ChallengeAnswer.create!(name: answer[:name], contents: answer[:contents],
level: index+1, score: answer[:score], challenge_id: @challenge.id) level: index+1, score: answer[:score], challenge_id: @challenge.id)
end end
end end

@ -136,22 +136,22 @@ class CollegesController < ApplicationController
private private
def require_login # def require_login
return if User.current.logged? # return if User.current.logged?
#
redirect_to "/login?back_url=#{CGI::escape(request.fullpath)}" # redirect_to "/login?back_url=#{CGI::escape(request.fullpath)}"
end # end
def check_college_present! def check_college_present!
return if current_college.present? return if current_college.present?
redirect_to '/404' tip_exception(404, "")
end end
def check_manage_permission! def check_manage_permission!
return if can_manage_college? return if can_manage_college?
redirect_to '/403' tip_exception(403, "")
end end
def can_manage_college? def can_manage_college?
@ -160,7 +160,7 @@ class CollegesController < ApplicationController
return true if current_user.is_teacher? && current_user.school_id == current_school.id # 学校老师 return true if current_user.is_teacher? && current_user.school_id == current_school.id # 学校老师
# return true if current_school.customers.exists? && current_user.partner&.partner_customers&.exists?(customer_id: current_school.customer_id) # return true if current_school.customers.exists? && current_user.partner&.partner_customers&.exists?(customer_id: current_school.customer_id)
false tip_exception(403, "")
end end
def current_school def current_school

@ -6,12 +6,17 @@ module ControllerRescueHandler
Util.logger_error e Util.logger_error e
render json: {status: -1, message: e.message} render json: {status: -1, message: e.message}
end end
rescue_from ActiveRecord::StatementInvalid do |e|
Util.logger_error e
render json: {status: -1, message: "接口数据异常"}
end
# rescue_from ActionView::MissingTemplate, with: :object_not_found # rescue_from ActionView::MissingTemplate, with: :object_not_found
# rescue_from ActiveRecord::RecordNotFound, with: :object_not_found # rescue_from ActiveRecord::RecordNotFound, with: :object_not_found
rescue_from Educoder::TipException, with: :tip_show rescue_from Educoder::TipException, with: :tip_show
rescue_from ::ActionView::MissingTemplate, with: :missing_template rescue_from ::ActionView::MissingTemplate, with: :missing_template
rescue_from ActiveRecord::RecordNotFound, with: :object_not_found rescue_from ActiveRecord::RecordNotFound, with: :object_not_found
rescue_from ActionController::ParameterMissing, with: :render_parameter_missing rescue_from ActionController::ParameterMissing, with: :render_parameter_missing
# form validation error # form validation error
rescue_from ActiveModel::ValidationError do |ex| rescue_from ActiveModel::ValidationError do |ex|
render_error(ex.model.errors.full_messages.join(',')) render_error(ex.model.errors.full_messages.join(','))
@ -19,5 +24,9 @@ module ControllerRescueHandler
rescue_from ActiveRecord::RecordInvalid do |ex| rescue_from ActiveRecord::RecordInvalid do |ex|
render_error(ex.record.errors.full_messages.join(',')) render_error(ex.record.errors.full_messages.join(','))
end end
# rescue_from RuntimeError do |ex|
# Util.logger_error "#######ex:#{ex}"
# render_error(ex.message)
# end
end end
end end

@ -16,7 +16,7 @@ module LoginHelper
:expires => 1.month.from_now, :expires => 1.month.from_now,
:path => '/', :path => '/',
:secure => false, :secure => false,
:httponly => true :httponly => false
} }
if edu_setting('cookie_domain').present? if edu_setting('cookie_domain').present?
cookie_options = cookie_options.merge(domain: edu_setting('cookie_domain')) cookie_options = cookie_options.merge(domain: edu_setting('cookie_domain'))

@ -1,6 +1,7 @@
class CoursesController < ApplicationController class CoursesController < ApplicationController
include MessagesHelper include MessagesHelper
include ExportHelper include ExportHelper
include CustomSortable
# model validation error # model validation error
rescue_from ActiveRecord::RecordInvalid do |ex| rescue_from ActiveRecord::RecordInvalid do |ex|
@ -23,8 +24,8 @@ class CoursesController < ApplicationController
:course_group_list, :set_course_group, :change_course_admin, :change_course_teacher, :course_group_list, :set_course_group, :change_course_admin, :change_course_teacher,
:delete_course_teacher, :teacher_application_review, :students, :all_course_groups, :delete_course_teacher, :teacher_application_review, :students, :all_course_groups,
:transfer_to_course_group, :delete_from_course, :search_users, :add_students_by_search, :transfer_to_course_group, :delete_from_course, :search_users, :add_students_by_search,
:base_info, :get_historical_courses, :create_group_by_importing_file, :base_info, :get_historical_courses, :create_group_by_importing_file, :course_videos,
:attahcment_category_list,:export_member_scores_excel, :duplicate_course, :attahcment_category_list,:export_member_scores_excel, :duplicate_course, :delete_course_video,
:switch_to_teacher, :switch_to_assistant, :switch_to_student, :exit_course, :switch_to_teacher, :switch_to_assistant, :switch_to_student, :exit_course,
:informs, :update_informs, :online_learning, :update_task_position, :tasks_list, :informs, :update_informs, :online_learning, :update_task_position, :tasks_list,
:join_excellent_course, :export_couser_info, :export_member_act_score, :new_informs, :join_excellent_course, :export_couser_info, :export_member_act_score, :new_informs,
@ -100,6 +101,23 @@ class CoursesController < ApplicationController
@courses = @courses.preload(:school, :none_hidden_course_modules, teacher: :user_extension) @courses = @courses.preload(:school, :none_hidden_course_modules, teacher: :user_extension)
end end
def course_videos
logger.info("########[#{@course}")
videos = @course.videos
videos = custom_sort(videos, params[:sort_by], params[:sort_direction])
@count = videos.count
@videos = paginate videos
end
def delete_course_video
video = Video.find_by(id: params[:video_id])
tip_exception(404, "找不到资源") if video.blank?
tip_exception(403, "...") unless (video.user_id == current_user.id || current_user.admin_or_business?)
video.destroy!
AliyunVod::Service.delete_video([video.uuid]) rescue nil
render_ok
end
def visits_plus_one def visits_plus_one
new_visits = @course.visits + 1 new_visits = @course.visits + 1
@course.update_visits(new_visits) @course.update_visits(new_visits)
@ -377,6 +395,7 @@ class CoursesController < ApplicationController
def destroy def destroy
if @course.is_delete == 0 if @course.is_delete == 0
@course.delete! @course.delete!
Tiding.where(belong_container: @course).update_all(is_delete: 1)
Tiding.create!(user_id: current_user.id, trigger_user_id: current_user.id, container_id: @course.id, Tiding.create!(user_id: current_user.id, trigger_user_id: current_user.id, container_id: @course.id,
container_type: 'DeleteCourse', tiding_type: 'System', belong_container: @course, extra: @course.name) container_type: 'DeleteCourse', tiding_type: 'System', belong_container: @course, extra: @course.name)
normal_status(0, "成功") normal_status(0, "成功")
@ -1146,6 +1165,7 @@ class CoursesController < ApplicationController
if existing_student.present? if existing_student.present?
# 如果在该课堂已经存在学生身份,且邀请码为分班邀请码,则将其直接加入分班 # 如果在该课堂已经存在学生身份,且邀请码为分班邀请码,则将其直接加入分班
existing_student.update!(course_group_id: course_group.id) if course_group.present? existing_student.update!(course_group_id: course_group.id) if course_group.present?
message = "您已是课堂成员"
else else
correspond_teacher_exist = current_user.none_admin_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 = CourseMember.new(user_id: current_user.id, course_id: course.id, role: 4)
@ -1156,8 +1176,8 @@ class CoursesController < ApplicationController
CourseAddStudentCreateWorksJob.perform_later(course.id, [current_user.id]) CourseAddStudentCreateWorksJob.perform_later(course.id, [current_user.id])
StudentJoinCourseNotifyJob.perform_later(current_user.id, course.id) StudentJoinCourseNotifyJob.perform_later(current_user.id, course.id)
student_role = 1
end end
student_role = 1
end end
# 创建教师身份 # 创建教师身份
@ -1194,9 +1214,9 @@ class CoursesController < ApplicationController
teacher_role = 1 teacher_role = 1
end end
if teacher_role && student_role if (teacher_role && student_role) || message.to_s == "您已是课堂成员"
render json: { status: 0, message: message, course_id: course.id} render json: { status: 0, message: message, course_id: course.id}
elsif student_role elsif student_role.to_i == 1
render json: { status: 0, message: "加入成功", course_id: course.id} render json: { status: 0, message: "加入成功", course_id: course.id}
else else
normal_status(message) normal_status(message)

File diff suppressed because it is too large Load Diff

@ -1168,7 +1168,7 @@ class ExercisesController < ApplicationController
#班级的选择 #班级的选择
if params[:exercise_group_id].present? if params[:exercise_group_id].present?
group_id = params[:exercise_group_id] group_id = params[:exercise_group_id]
exercise_students = @course_all_members.course_find_by_ids("course_group_id", group_id) #试卷所分班的全部人数 exercise_students = @course_all_members.course_find("course_group_id", group_id) #试卷所分班的全部人数
user_ids = exercise_students.pluck(:user_id).reject(&:blank?) user_ids = exercise_students.pluck(:user_id).reject(&:blank?)
@exercise_users_list = @exercise_users_list.exercise_commit_users(user_ids) @exercise_users_list = @exercise_users_list.exercise_commit_users(user_ids)
end end

@ -368,6 +368,7 @@ class HomeworkCommonsController < ApplicationController
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
begin begin
@homework = HomeworkCommon.new(homework_params) @homework = HomeworkCommon.new(homework_params)
@homework.reference_answer = params[:reference_answer].to_s.strip
@homework.homework_type = @homework_type @homework.homework_type = @homework_type
@homework.user_id = current_user.id @homework.user_id = current_user.id
@homework.course_id = @course.id @homework.course_id = @course.id
@ -417,6 +418,7 @@ class HomeworkCommonsController < ApplicationController
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
begin begin
@homework.update_attributes!(homework_params) @homework.update_attributes!(homework_params)
@homework.reference_answer = params[:reference_answer].to_s.strip
if @homework.homework_type == "group" if @homework.homework_type == "group"
homework_detail_group = @homework.homework_detail_group homework_detail_group = @homework.homework_detail_group
@ -497,7 +499,7 @@ class HomeworkCommonsController < ApplicationController
# tip_exception("challenge_id参数的长度与challenge_score参数的长度不匹配") if # tip_exception("challenge_id参数的长度与challenge_score参数的长度不匹配") if
# params[:challenge_settings][:challenge_score].length != params[:challenge_settings][:challenge_id].length # params[:challenge_settings][:challenge_score].length != params[:challenge_settings][:challenge_id].length
sum_challenge_score = params[:challenge_settings].pluck(:challenge_score).reject(&:blank?).map{|score| score.to_f}.sum sum_challenge_score = params[:challenge_settings].pluck(:challenge_score).reject(&:blank?)&.map{|score| score.to_f}.sum
total_score = params[:work_efficiency] ? (params[:eff_score].to_f + sum_challenge_score) : sum_challenge_score total_score = params[:work_efficiency] ? (params[:eff_score].to_f + sum_challenge_score) : sum_challenge_score
tip_exception("分值之和必须等于总分值:#{params[:total_score]}") if params[:total_score].to_f.round(2) != total_score.to_f.round(2) tip_exception("分值之和必须等于总分值:#{params[:total_score]}") if params[:total_score].to_f.round(2) != total_score.to_f.round(2)
@ -910,7 +912,7 @@ class HomeworkCommonsController < ApplicationController
def publish_homework def publish_homework
tip_exception("请至少选择一个分班") if params[:group_ids].blank? && @course.course_groups.size != 0 tip_exception("请至少选择一个分班") if params[:group_ids].blank? && @course.course_groups.size != 0
group_ids = params[:group_ids]&.reject(&:blank?).map(&:to_i) group_ids = params[:group_ids]&.reject(&:blank?)&.map(&:to_i)
if params[:detail].blank? if params[:detail].blank?
tip_exception("缺少截止时间参数") if params[:end_time].blank? tip_exception("缺少截止时间参数") if params[:end_time].blank?
tip_exception("截止时间不能早于当前时间") if params[:end_time] <= strf_time(Time.now) tip_exception("截止时间不能早于当前时间") if params[:end_time] <= strf_time(Time.now)
@ -918,7 +920,7 @@ class HomeworkCommonsController < ApplicationController
@course.end_date.present? && params[:end_time] > strf_time(@course.end_date.end_of_day) @course.end_date.present? && params[:end_time] > strf_time(@course.end_date.end_of_day)
else else
tip_exception("缺少分班截止时间参数") if params[:group_end_times].blank? tip_exception("缺少分班截止时间参数") if params[:group_end_times].blank?
group_end_times = params[:group_end_times].reject(&:blank?).map{|time| time.to_time} group_end_times = params[:group_end_times].reject(&:blank?)&.map{|time| time.to_time}
tip_exception("截止时间和分班参数的个数不一致") if group_end_times.length != group_ids.length tip_exception("截止时间和分班参数的个数不一致") if group_end_times.length != group_ids.length
group_end_times.each do |time| group_end_times.each do |time|
tip_exception("分班截止时间不能早于当前时间") if time <= Time.now tip_exception("分班截止时间不能早于当前时间") if time <= Time.now
@ -1049,7 +1051,7 @@ class HomeworkCommonsController < ApplicationController
homeworks = homeworks.published_no_end.includes(:homework_group_settings, :homework_detail_manual, :homework_challenge_settings) homeworks = homeworks.published_no_end.includes(:homework_group_settings, :homework_detail_manual, :homework_challenge_settings)
course_students = @course.students course_students = @course.students
charge_group_ids = @course.charge_group_ids(current_user) charge_group_ids = @course.charge_group_ids(current_user)
group_ids = params[:group_ids]&.reject(&:blank?).map(&:to_i) group_ids = params[:group_ids]&.reject(&:blank?)&.map(&:to_i)
end_groups = charge_group_ids & group_ids if group_ids end_groups = charge_group_ids & group_ids if group_ids
begin begin
@ -1404,8 +1406,8 @@ class HomeworkCommonsController < ApplicationController
end end
def homework_params def homework_params
tip_exception("name参数不能为空") if params[:name].blank? tip_exception("标题不能为空") if params[:name].blank?
tip_exception("description参数不能为空") if params[:description].blank? tip_exception("内容不能为空") if params[:description].blank?
params.require(:homework_common).permit(:name, :description, :reference_answer) params.require(:homework_common).permit(:name, :description, :reference_answer)
end end

@ -0,0 +1,69 @@
class LiveLinksController < ApplicationController
before_action :require_login
before_action :find_course, only: [:index, :create]
before_action :user_course_identity, :teacher_allowed, only: [:create]
before_action :edit_auth, only: [:edit, :update]
before_action :delete_auth, only: [:destroy]
def index
lives = @course.live_links
order_str = "on_status desc, live_time desc"
@total_count = lives.size
@my_live_id = @course.live_links.find_by(user_id: current_user.id)&.id
# order_str = "live_links.id = #{@my_live_id} desc, #{order_str}" if @my_live_id.present?
lives = lives.order("#{order_str}")
@lives = paginate lives.includes(user: :user_extension)
end
def create
on_status = params[:live_time].present? && params[:live_time].to_time <= Time.now ? 1 : 0
@course.live_links.create!(create_params.merge(user_id: current_user.id, on_status: on_status))
render_ok
end
def edit
@live = current_live
end
def update
if params[:on_status]
tip_exception("请勿重复开启") if current_live.on_status && params[:on_status].to_i == 1
ActiveRecord::Base.transaction do
current_live.update!(on_status: params[:on_status])
# 开启时发送消息,关闭直播时删除对应的消息
if params[:on_status].to_i == 1
LivePublishJob.perform_later(current_live.id)
end
end
else
on_status = params[:live_time].present? && params[:live_time].to_time <= Time.now ? 1 : 0
current_live.update!(create_params.merge(on_status: on_status))
end
render_ok
end
def destroy
current_live.destroy!
render_ok
end
private
def create_params
params.permit(:url, :description, :course_name, :platform, :live_time, :duration)
end
def current_live
@_current_live = LiveLink.find params[:id]
end
def edit_auth
tip_exception(403, "无权限操作") unless current_user.id == current_live.user_id || current_user.admin_or_business?
end
def delete_auth
tip_exception(403, "无权限操作") unless current_user.id == current_live.user_id || current_user.admin?
end
end

@ -8,6 +8,24 @@ class MainController < ApplicationController
end end
def index def index
render file: 'public/react/build/index.html', :layout => false domain_session = params[:_educoder_session]
if domain_session
uid_logger("main start domain_session is #{domain_session}")
if cookies[:_educoder_session] != domain_session
cookies[:_educoder_session] = nil
cookies[:_educoder_session] = domain_session
end
uid_logger("main start is #{cookies[:_educoder_session]}")
end
if params[:path] && params[:path]&.include?("educoderh5") && params[:path].split("/").first == "educoderh5"
render file: 'public/h5build/index.html', :layout => false
else
render file: 'public/react/build/index.html', :layout => false
end
end end
end end

@ -265,7 +265,9 @@ class MyshixunsController < ApplicationController
uid_logger_dubug("-- game build: file update #{@sec_key}, record id is #{record.id}, time is **** #{Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")}") uid_logger_dubug("-- game build: file update #{@sec_key}, record id is #{record.id}, time is **** #{Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")}")
end end
# 隐藏代码文件 和 VNC的都不需要走版本库 # 隐藏代码文件 和 VNC的都不需要走版本库
unless @hide_code || (@myshixun.shixun&.vnc_evaluate && params[:evaluate].present?) vnc = @myshixun.shixun&.vnc
unless @hide_code || (vnc && params[:evaluate].present?)
# 远程版本库文件内容 # 远程版本库文件内容
last_content = GitService.file_content(repo_path: @repo_path, path: path)["content"] last_content = GitService.file_content(repo_path: @repo_path, path: path)["content"]
@ -275,8 +277,8 @@ class MyshixunsController < ApplicationController
else else
params[:content] params[:content]
end end
uid_logger_dubug("###11222333####{content}") uid_logger_dubug("content_#{@myshixun.identifier}: #{content}")
uid_logger_dubug("###222333####{last_content}") uid_logger_dubug("###last_content_#{@myshixun.identifier}####{last_content}")
if content != last_content if content != last_content
@content_modified = 1 @content_modified = 1
@ -286,6 +288,7 @@ class MyshixunsController < ApplicationController
message = params[:evaluate] == 0 ? "System automatically submitted" : "User submitted" message = params[:evaluate] == 0 ? "System automatically submitted" : "User submitted"
uid_logger_dubug("112233#{author_name}") uid_logger_dubug("112233#{author_name}")
uid_logger_dubug("112233#{author_email}") uid_logger_dubug("112233#{author_email}")
uid_logger_dubug("daiao_debug_#{@myshixun.identifier}: #{@repo_path}: #{path}; #{message}; #{content}; ")
@content = GitService.update_file(repo_path: @repo_path, @content = GitService.update_file(repo_path: @repo_path,
file_path: path, file_path: path,
message: message, message: message,

@ -1,13 +1,13 @@
class PollQuestionsController < ApplicationController class PollQuestionsController < ApplicationController
before_action :require_login, :check_auth before_action :require_login, :check_auth
before_action :get_poll,only:[:new,:create] before_action :get_poll, only: [:new, :create]
before_action :get_poll_question,except: [:new,:create] before_action :get_poll_question, except: [:new, :create]
before_action :is_course_teacher before_action :is_course_teacher
before_action :get_poll_questions_count,only:[:create] before_action :get_poll_questions_count, only: [:create]
before_action :get_poll_question_answers,only:[:edit,:update] before_action :get_poll_question_answers, only: [:edit, :update]
before_action :check_poll_status,only: [:new,:create,:delete_answer,:destroy] before_action :check_poll_status, only: [:new, :create, :delete_answer, :destroy]
before_action :validates_params,only:[:create,:update] before_action :validates_params, only: [:create, :update]
before_action :validates_update_params,only: [:update] before_action :validates_update_params, only: [:update]
def new def new
@ -25,54 +25,48 @@ class PollQuestionsController < ApplicationController
# 创建题目和选择的答案 # 创建题目和选择的答案
def create def create
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
begin poll_options = {
poll_options = { :question_title => params[:question_title],
:question_title => params[:question_title], :question_type => params[:question_type],
:question_type => params[:question_type], :is_necessary => params[:is_necessary].to_i,
:is_necessary => params[:is_necessary].to_i, :question_number => @poll_ques_count + 1,
:question_number => @poll_ques_count + 1, :max_choices => params[:max_choices] || nil,
:max_choices => params[:max_choices] || nil, :min_choices => params[:min_choices] || nil
:min_choices => params[:min_choices] || nil }
} @poll_question = @poll.poll_questions.new(poll_options)
@poll_question = @poll.poll_questions.new(poll_options)
if params[:insert_id].present? #插入问题时那么从插入的这个id以后的question_num都将要+1 if params[:insert_id].present? #插入问题时那么从插入的这个id以后的question_num都将要+1
insert_poll = @poll.poll_questions.find_by(id: params[:insert_id]) insert_poll = @poll.poll_questions.find_by(id: params[:insert_id])
if insert_poll.present? #如果该问题存在的话,意思是如果是第一题,那么就不存在插入 if insert_poll.present? #如果该问题存在的话,意思是如果是第一题,那么就不存在插入
ques_num = insert_poll.question_number.to_i ques_num = insert_poll.question_number.to_i
@poll_question.question_number = ques_num + 1 #更新了问题的位置 @poll_question.question_number = ques_num + 1 #更新了问题的位置
@poll.poll_questions.insert_question(ques_num).update_all("question_number = question_number + 1") @poll.poll_questions.insert_question(ques_num).update_all("question_number = question_number + 1")
end
end end
if @poll_question.save! end
if params[:question_type] != 3 if @poll_question.save!
p_answer = params[:question_answers] if params[:question_type] != 3
p_other_answer = params[:question_other_answer] p_answer = params[:question_answers]
# 新增选择题答案选择的选项 p_other_answer = params[:question_other_answer]
(1..p_answer.count).each do |i| # 新增选择题答案选择的选项
answer = p_answer[i-1] # 传入的答案的内容 (1..p_answer.count).each do |i|
question_option = { answer = p_answer[i - 1] # 传入的答案的内容
:answer_position => i, question_option = {
:answer_text => answer :answer_position => i,
} :answer_text => answer
poll_answers = @poll_question.poll_answers.new question_option }
poll_answers.save! poll_answers = @poll_question.poll_answers.new question_option
end poll_answers.save!
# 新增答案的其他选项 end
if p_other_answer # 新增答案的其他选项
question_option = { if p_other_answer
:answer_position => p_answer.count + 1, question_option = {
:answer_text => '' :answer_position => p_answer.count + 1,
} :answer_text => ''
poll_answers = @poll_question.poll_answers.new question_option }
poll_answers.save! poll_answers = @poll_question.poll_answers.new question_option
end poll_answers.save!
end end
end end
rescue Exception => e
uid_logger_error(e.message)
tip_exception("问卷的问题创建失败!")
raise ActiveRecord::Rollback
end end
end end
end end
@ -103,61 +97,55 @@ class PollQuestionsController < ApplicationController
def update def update
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
begin if @poll_question.question_type < 3 #当为单选题或多选题时
if @poll_question.question_type < 3 #当为单选题或多选题时 p_answer = params[:question_answers]
p_answer = params[:question_answers] p_other_answer = params[:question_other_answer]
p_other_answer = params[:question_other_answer] p_answer_count = p_answer.count
p_answer_count = p_answer.count @poll_question.poll_answers.each do |an|
@poll_question.poll_answers.each do |an| if (p_answer_count < @poll_current_answers) && (p_answer_count..@poll_current_answers).to_a.include?(an.answer_position)
if (p_answer_count < @poll_current_answers) && (p_answer_count..@poll_current_answers).to_a.include?(an.answer_position) an.destroy
an.destroy
end
end end
(1..p_answer_count).each do |i| end
answer = @poll_question.poll_answers.find_answer_by_custom("answer_position",i).first (1..p_answer_count).each do |i|
if answer # 判断该位置的answer是否存在存在则更新.不存在则跳到下一步 answer = @poll_question.poll_answers.find_answer_by_custom("answer_position", i).first
answer.answer_text = p_answer[i-1] if answer # 判断该位置的answer是否存在存在则更新.不存在则跳到下一步
answer.answer_position = i answer.answer_text = p_answer[i - 1]
answer.save! answer.answer_position = i
else answer.save!
answer_options = { else
:answer_position => i, answer_options = {
:answer_text => p_answer[i-1] :answer_position => i,
} :answer_text => p_answer[i - 1]
@poll_question.poll_answers.new answer_options }
end @poll_question.poll_answers.new answer_options
end end
if p_other_answer #判断答案的其他选项是否存在 end
other_answer = @poll_question.poll_answers.find_answer_by_custom("answer_text","").first if p_other_answer #判断答案的其他选项是否存在
if other_answer.blank? other_answer = @poll_question.poll_answers.find_answer_by_custom("answer_text", "").first
question_option = { if other_answer.blank?
:answer_position => p_answer_count + 1, question_option = {
:answer_text => '' :answer_position => p_answer_count + 1,
} :answer_text => ''
@poll_question.poll_answers.new question_option }
else @poll_question.poll_answers.new question_option
other_answer.answer_position = p_answer_count + 1 else
other_answer.save! other_answer.answer_position = p_answer_count + 1
end other_answer.save!
end end
end end
@poll_question.update!(poll_questions_params)
rescue Exception => e
uid_logger_error(e.message)
tip_exception("更新失败")
raise ActiveRecord::Rollback
end end
@poll_question.update!(poll_questions_params)
end end
end end
def delete_answer def delete_answer
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
begin begin
answer_d_id = params[:answer_no].to_i # 答案的当前位置 answer_d_id = params[:answer_no].to_i # 答案的当前位置
poll_answers = @poll_question.poll_answers poll_answers = @poll_question.poll_answers
delete_answer = poll_answers.find_by(answer_position: answer_d_id) delete_answer = poll_answers.find_by(answer_position: answer_d_id)
left_answers = poll_answers.where("answer_position > ?",answer_d_id) left_answers = poll_answers.where("answer_position > ?", answer_d_id)
left_answers.update_all("answer_position = answer_position - 1") if left_answers left_answers.update_all("answer_position = answer_position - 1") if left_answers
if delete_answer.destroy if delete_answer.destroy
@ -175,7 +163,7 @@ class PollQuestionsController < ApplicationController
def destroy def destroy
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
begin begin
question_d_id = @poll_question.question_number.to_i #问题的当前位置 question_d_id = @poll_question.question_number.to_i #问题的当前位置
poll_questions = @poll.poll_questions poll_questions = @poll.poll_questions
left_questions = poll_questions.insert_question(question_d_id) left_questions = poll_questions.insert_question(question_d_id)
left_questions.update_all("question_number = question_number - 1") if left_questions left_questions.update_all("question_number = question_number - 1") if left_questions
@ -192,11 +180,11 @@ class PollQuestionsController < ApplicationController
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
begin begin
opr = params[:opr] opr = params[:opr]
current_q_p = @poll_question.question_number.to_i #问题的当前位置 current_q_p = @poll_question.question_number.to_i #问题的当前位置
if @poll.polls_status.to_i == 1 if @poll.polls_status.to_i == 1
if opr.present? if opr.present?
if opr.to_s == "up" if opr.to_s == "up"
last_q_p = @poll.poll_questions.find_by(question_number: (current_q_p-1)) #当前问题的前一个问题 last_q_p = @poll.poll_questions.find_by(question_number: (current_q_p - 1)) #当前问题的前一个问题
if last_q_p.present? if last_q_p.present?
@poll_question.update!(question_number: (current_q_p - 1)) @poll_question.update!(question_number: (current_q_p - 1))
last_q_p.update!(question_number: current_q_p) # 重新获取当前问题的位置 last_q_p.update!(question_number: current_q_p) # 重新获取当前问题的位置
@ -205,7 +193,7 @@ class PollQuestionsController < ApplicationController
normal_status(-1, "移动失败,已经是第一个问题了!") normal_status(-1, "移动失败,已经是第一个问题了!")
end end
elsif opr.to_s == "down" elsif opr.to_s == "down"
next_q_p = @poll.poll_questions.find_by(question_number: (current_q_p+1)) #当前问题的后一个问题 next_q_p = @poll.poll_questions.find_by(question_number: (current_q_p + 1)) #当前问题的后一个问题
if next_q_p.present? if next_q_p.present?
@poll_question.update!(question_number: (current_q_p + 1)) @poll_question.update!(question_number: (current_q_p + 1))
next_q_p.update!(question_number: current_q_p) next_q_p.update!(question_number: current_q_p)
@ -219,7 +207,7 @@ class PollQuestionsController < ApplicationController
normal_status(-1, "移动失败,请输入参数") normal_status(-1, "移动失败,请输入参数")
end end
else else
normal_status(-1,"已发布的不能移动问题") normal_status(-1, "已发布的不能移动问题")
end end
rescue Exception => e rescue Exception => e
uid_logger_error(e.message) uid_logger_error(e.message)
@ -231,7 +219,7 @@ class PollQuestionsController < ApplicationController
private private
def poll_questions_params def poll_questions_params
params.require(:poll_question).permit(:question_title,:question_type,:is_necessary,:question_number,:max_choices,:min_choices) params.require(:poll_question).permit(:question_title, :question_type, :is_necessary, :question_number, :max_choices, :min_choices)
end end
def validates_params def validates_params
@ -242,12 +230,12 @@ class PollQuestionsController < ApplicationController
normal_status(-1, "最小可选不能大于最大可选!") normal_status(-1, "最小可选不能大于最大可选!")
elsif params[:question_answers].present? && (params[:max_choices].to_i > params[:question_answers].count) elsif params[:question_answers].present? && (params[:max_choices].to_i > params[:question_answers].count)
normal_status(-1, "选择题的最大可选项不能大于答案数!") normal_status(-1, "选择题的最大可选项不能大于答案数!")
elsif [1,3].include?(params[:question_type]) && (params[:max_choices].to_i > 0 || params[:min_choices].to_i > 0) elsif [1, 3].include?(params[:question_type]) && (params[:max_choices].to_i > 0 || params[:min_choices].to_i > 0)
normal_status(-1, "单选题或主观题不能有最大或最小选择数!") normal_status(-1, "单选题或主观题不能有最大或最小选择数!")
elsif params[:question_type] == 3 && (params[:question_answers] || params[:question_other_answer]) elsif params[:question_type] == 3 && (params[:question_answers] || params[:question_other_answer])
normal_status(-1, "主观问题不需要可选答案!") normal_status(-1, "主观问题不需要可选答案!")
elsif params[:question_type] != 3 elsif params[:question_type] != 3
if params[:question_answers].present? && params[:question_answers].select{|answer| answer.blank?}.count > 0 if params[:question_answers].present? && params[:question_answers].select {|answer| answer.blank?}.count > 0
normal_status(-1, "选项不能有空值!") normal_status(-1, "选项不能有空值!")
elsif params[:question_other_answer].present? && !params[:question_other_answer].blank? elsif params[:question_other_answer].present? && !params[:question_other_answer].blank?
normal_status(-1, "其他选项不能有值!") normal_status(-1, "其他选项不能有值!")
@ -262,11 +250,11 @@ class PollQuestionsController < ApplicationController
def validates_update_params def validates_update_params
question_a_count = params[:question_answers].present? ? params[:question_answers].count : 0 question_a_count = params[:question_answers].present? ? params[:question_answers].count : 0
question_o_count = params[:question_other_answer].present? ? params[:question_other_answer].count : 0 question_o_count = params[:question_other_answer].present? ? params[:question_other_answer].count : 0
normal_status(-1, "已发布的问卷不允许增删答案!") if (((question_a_count+question_o_count) != @poll_current_answers) && (@poll.polls_status.to_i != 1)) normal_status(-1, "已发布的问卷不允许增删答案!") if (((question_a_count + question_o_count) != @poll_current_answers) && (@poll.polls_status.to_i != 1))
end end
def get_poll def get_poll
@poll = Poll.find_by(id:params[:poll_id]) @poll = Poll.find_by(id: params[:poll_id])
if @poll.blank? if @poll.blank?
tip_exception(404) tip_exception(404)
end end
@ -283,7 +271,7 @@ class PollQuestionsController < ApplicationController
def get_poll_question def get_poll_question
@poll_question = PollQuestion.find_by(id: params[:id]) @poll_question = PollQuestion.find_by(id: params[:id])
if @poll_question.present? if @poll_question.present?
@poll = Poll.find_by(id:@poll_question.poll_id) @poll = Poll.find_by(id: @poll_question.poll_id)
else else
tip_exception(404) tip_exception(404)
end end
@ -305,7 +293,7 @@ class PollQuestionsController < ApplicationController
tip_exception(404) tip_exception(404)
else else
@identity = current_user.course_identity(@course) @identity = current_user.course_identity(@course)
normal_status(-1, "权限不够") unless(@course.present? && @identity < Course::STUDENT) #课堂存在,且当前用户为教师/管理员 normal_status(-1, "权限不够") unless (@course.present? && @identity < Course::STUDENT) #课堂存在,且当前用户为教师/管理员
end end
end end
end end

@ -5,120 +5,114 @@ class PollVotesController < ApplicationController
before_action :check_answer_in_question before_action :check_answer_in_question
def create #每一次答案的点击,请求一次 def create #每一次答案的点击,请求一次
begin question_votes = @poll_question.poll_votes
question_votes = @poll_question.poll_votes question_type = @poll_question.question_type
question_type = @poll_question.question_type question_answer_id = params[:poll_answer_id] ? params[:poll_answer_id] : -1 #该答案的id
question_answer_id = params[:poll_answer_id] ? params[:poll_answer_id] : -1 #该答案的id question_answer_text = params[:vote_text].present? ? params[:vote_text] : nil #其他选项的内容
question_answer_text = params[:vote_text].present? ? params[:vote_text] : nil #其他选项的内容 user_votes = question_votes.find_current_vote("user_id", current_user.id) #当前用户的答案,可能有多个
user_votes = question_votes.find_current_vote("user_id",current_user.id) #当前用户的答案,可能有多个 # 当前用户的当前答案,如果已存在,当再次点击的时候,取消答案,即删除该答案
# 当前用户的当前答案,如果已存在,当再次点击的时候,取消答案,即删除该答案 current_vote_text = nil
current_vote_text = nil
# if user_votes.find_vote_text.present? # if user_votes.find_vote_text.present?
# current_vote_text = user_votes.find_vote_text.first # current_vote_text = user_votes.find_vote_text.first
# end # end
vote_answer_params = { vote_answer_params = {
:user_id => current_user.id, :user_id => current_user.id,
:poll_question_id => @poll_question.id, :poll_question_id => @poll_question.id,
:poll_answer_id => question_answer_id, :poll_answer_id => question_answer_id,
:vote_text => question_answer_text :vote_text => question_answer_text
} }
#begin #begin
if question_type == 1 if question_type == 1
if user_votes.present? #用户曾经回答过的,答案选择不一样,否则新建 if user_votes.present? #用户曾经回答过的,答案选择不一样,否则新建
current_user_answer = user_votes.first current_user_answer = user_votes.first
if current_user_answer&.poll_answer_id != question_answer_id #如果说更换了答案,则以前的答案删除,并新建记录 if current_user_answer&.poll_answer_id != question_answer_id #如果说更换了答案,则以前的答案删除,并新建记录
current_user_answer.destroy current_user_answer.destroy
PollVote.create!(vote_answer_params) PollVote.create!(vote_answer_params)
else else
if question_answer_text.present? if question_answer_text.present?
current_user_answer.update!(vote_text: question_answer_text) current_user_answer.update!(vote_text: question_answer_text)
end
end end
else
PollVote.create!(vote_answer_params)
end end
elsif question_type == 2 #多选题的话答案应该是1个以上 else
question_answer_ids = params[:poll_answer_id] ? params[:poll_answer_id] : [] #该答案的id PollVote.create!(vote_answer_params)
if question_answer_ids.present? end
if question_answer_text.present? #有文字输入,但是不存在其他选项的 elsif question_type == 2 #多选题的话答案应该是1个以上
ques_vote_id = question_answer_ids.map(&:to_i).max question_answer_ids = params[:poll_answer_id] ? params[:poll_answer_id] : [] #该答案的id
ques_vote = user_votes.find_by(poll_answer_id: ques_vote_id) if question_answer_ids.present?
if ques_vote.present? if question_answer_text.present? #有文字输入,但是不存在其他选项的
ques_vote.update!(vote_text: question_answer_text) ques_vote_id = question_answer_ids.map(&:to_i).max
else ques_vote = user_votes.find_by(poll_answer_id: ques_vote_id)
answer_option = { if ques_vote.present?
:user_id => current_user.id, ques_vote.update!(vote_text: question_answer_text)
:poll_question_id => @poll_question.id, else
:poll_answer_id => ques_vote_id, answer_option = {
:vote_text => question_answer_text :user_id => current_user.id,
} :poll_question_id => @poll_question.id,
PollVote.create!(answer_option) :poll_answer_id => ques_vote_id,
# 重新取一次poll_votes :vote_text => question_answer_text
user_votes = @poll_question.poll_votes.find_current_vote("user_id",current_user.id) }
end PollVote.create!(answer_option)
# if current_vote_text.present? #已有其他输入文字的选项 # 重新取一次poll_votes
# current_vote_text.update_attribute("vote_text", question_answer_text) user_votes = @poll_question.poll_votes.find_current_vote("user_id", current_user.id)
# else
#
# end
end end
# if current_vote_text.present? #已有其他输入文字的选项
# current_vote_text.update_attribute("vote_text", question_answer_text)
# else
#
# end
end
ea_ids = user_votes.pluck(:poll_answer_id) ea_ids = user_votes.pluck(:poll_answer_id)
common_answer_ids = question_answer_ids & ea_ids #已经存在的试卷选项id common_answer_ids = question_answer_ids & ea_ids #已经存在的试卷选项id
new_ids = question_answer_ids - common_answer_ids # 新增的id new_ids = question_answer_ids - common_answer_ids # 新增的id
old_ids = ea_ids - common_answer_ids #没有选择的,则删掉 old_ids = ea_ids - common_answer_ids #没有选择的,则删掉
if new_ids.size > 0 if new_ids.size > 0
new_ids.each do |e| new_ids.each do |e|
answer_option = { answer_option = {
:user_id => current_user.id, :user_id => current_user.id,
:poll_question_id => @poll_question.id, :poll_question_id => @poll_question.id,
:poll_answer_id => e, :poll_answer_id => e,
:vote_text => nil :vote_text => nil
} }
ex_a = PollVote.new(answer_option) ex_a = PollVote.new(answer_option)
ex_a.save! ex_a.save!
end
end end
if old_ids.size > 0
ea_answer = user_votes.find_current_vote("poll_answer_id",old_ids)
ea_answer.destroy_all
end
else
user_votes.destroy_all
end end
else #主观题的输入 if old_ids.size > 0
# current_vote_text = user_votes.find_vote_text ea_answer = user_votes.find_current_vote("poll_answer_id", old_ids)
if user_votes.present? ea_answer.destroy_all
user_votes.first.update!(vote_text: question_answer_text)
# if question_answer_text.present?
# user_votes.first.update_attribute("vote_text", question_answer_text)
# else
# user_votes.destroy_all
# end
else
PollVote.create!(vote_answer_params)
end end
else
user_votes.destroy_all
end end
@current_question_number = @poll_question.question_number else #主观题的输入
@current_question_necessary = @poll_question.is_necessary # current_vote_text = user_votes.find_vote_text
#问答记录存在,且有值,才会有返回值。 if user_votes.present?
@current_question_status = 0 user_votes.first.update!(vote_text: question_answer_text)
new_user_votes = question_votes.where(user_id: current_user.id) # if question_answer_text.present?
if new_user_votes.present? # user_votes.first.update_attribute("vote_text", question_answer_text)
vote_answer_id = new_user_votes.pluck(:poll_answer_id).reject(&:blank?).size # else
vote_text_count = new_user_votes.pluck(:vote_text).reject(&:blank?).size # user_votes.destroy_all
if vote_text_count > 0 || vote_answer_id > 0 # end
@current_question_status = 1 else
end PollVote.create!(vote_answer_params)
end
end
@current_question_number = @poll_question.question_number
@current_question_necessary = @poll_question.is_necessary
#问答记录存在,且有值,才会有返回值。
@current_question_status = 0
new_user_votes = question_votes.where(user_id: current_user.id)
if new_user_votes.present?
vote_answer_id = new_user_votes.pluck(:poll_answer_id).reject(&:blank?).size
vote_text_count = new_user_votes.pluck(:vote_text).reject(&:blank?).size
if vote_text_count > 0 || vote_answer_id > 0
@current_question_status = 1
end end
rescue Exception => e
uid_logger_error(e.message)
tip_exception("页面调用失败!")
raise ActiveRecord::Rollback
end end
end end
@ -128,14 +122,14 @@ class PollVotesController < ApplicationController
def get_poll_question def get_poll_question
@poll_question = PollQuestion.find_by_id(params[:poll_question_id]) @poll_question = PollQuestion.find_by_id(params[:poll_question_id])
if @poll_question.blank? if @poll_question.blank?
normal_status(-1,"问卷试题不存在!") normal_status(-1, "问卷试题不存在!")
else else
@poll = @poll_question.poll @poll = @poll_question.poll
@course = @poll.course @course = @poll.course
if @poll.blank? if @poll.blank?
normal_status(-1,"问卷不存在!") normal_status(-1, "问卷不存在!")
elsif @course.blank? elsif @course.blank?
normal_status(-1,"课堂不存在!") normal_status(-1, "课堂不存在!")
end end
end end
end end
@ -146,7 +140,7 @@ class PollVotesController < ApplicationController
question_type = @poll_question&.question_type question_type = @poll_question&.question_type
if (question_type == 1) && params[:poll_answer_id].blank? if (question_type == 1) && params[:poll_answer_id].blank?
normal_status(-1,"答案ID错误!") normal_status(-1, "答案ID错误!")
elsif question_type == 2 elsif question_type == 2
user_vote_count = params[:poll_answer_id].size user_vote_count = params[:poll_answer_id].size
if @poll_question.max_choices.present? if @poll_question.max_choices.present?
@ -155,10 +149,10 @@ class PollVotesController < ApplicationController
question_max_choices = 0 question_max_choices = 0
end end
if question_max_choices > 0 && (user_vote_count > question_max_choices) if question_max_choices > 0 && (user_vote_count > question_max_choices)
normal_status(-1,"多选题答案超过最大限制!") normal_status(-1, "多选题答案超过最大限制!")
end end
elsif (poll_user.present? && poll_user.commit_status == 1) || poll_user_status == 3 elsif (poll_user.present? && poll_user.commit_status == 1) || poll_user_status == 3
normal_status(-1,"已提交/已结束的问卷不允许修改!") normal_status(-1, "已提交/已结束的问卷不允许修改!")
end end
end end

File diff suppressed because it is too large Load Diff

@ -25,7 +25,7 @@ class ShixunsController < ApplicationController
before_action :special_allowed, only: [:send_to_course, :search_user_courses] before_action :special_allowed, only: [:send_to_course, :search_user_courses]
before_action :shixun_marker, only: [:new, :create] before_action :shixun_marker, only: [:new, :create]
before_action :validate_wachat_support, only: [:shixun_exec] #before_action :validate_wachat_support, only: [:shixun_exec]
skip_before_action :check_sign, only: [:download_file] skip_before_action :check_sign, only: [:download_file]
## 获取课程列表 ## 获取课程列表
@ -474,7 +474,7 @@ class ShixunsController < ApplicationController
if params[:shixun][:vnc] if params[:shixun][:vnc]
shixun_params.merge(vnc_evaluate: 1) shixun_params.merge(vnc_evaluate: 1)
else else
shixun_params shixun_params.merge(vnc_evaluate: 0)
end end
@shixun.update_attributes!(update_params) @shixun.update_attributes!(update_params)
end end
@ -1186,11 +1186,11 @@ private
md5.hexdigest md5.hexdigest
end end
def validate_wachat_support # def validate_wachat_support
#
if (params[:wechat].present? && !@shixun.is_wechat_support?) # if (params[:wechat].present? && !@shixun.is_wechat_support?)
tip_exception(-5, "..") # tip_exception(-5, "..")
end # end
end # end
end end

@ -72,7 +72,7 @@ class SubjectsController < ApplicationController
end end
# 排序 # 排序
order_str = reorder == "publish_time" ? "status = 2 desc, publish_time asc" : "updated_at desc" order_str = (reorder == "publish_time" ? "homepage_show desc, excellent desc, status = 2 desc, publish_time asc" : "homepage_show desc, excellent desc, updated_at desc")
@subjects = @subjects.reorder(order_str) @subjects = @subjects.reorder(order_str)
end end
@ -242,13 +242,13 @@ class SubjectsController < ApplicationController
## 云上实验室过滤 ## 云上实验室过滤
@courses = @courses.where(id: current_laboratory.all_courses) @courses = @courses.where(id: current_laboratory.all_courses)
@none_shixun_ids = ShixunSchool.where("school_id != #{current_user.user_extension.try(:school_id).to_i}").pluck(:shixun_id) @none_shixun_ids = @subject.shixuns.joins(:shixun_schools).where("school_id != #{current_user.user_extension.try(:school_id).to_i}").where(use_scope: 1).pluck(:id)
end end
def send_to_course def send_to_course
@course = Course.find_by!(id: params[:course_id]) @course = Course.find_by!(id: params[:course_id])
stages = @subject.stages.where(id: @subject.stage_shixuns.where(shixun_id: params[:shixun_ids]).pluck(:stage_id)) stages = @subject.stages.where(id: @subject.stage_shixuns.where(shixun_id: params[:shixun_ids]).pluck(:stage_id)).reorder("stages.position DESC")
order_ids = params[:shixun_ids].size > 0 ? params[:shixun_ids].reverse.join(',') : -1
course_module = @course.course_modules.where(module_type: "shixun_homework").first course_module = @course.course_modules.where(module_type: "shixun_homework").first
homework_ids = [] homework_ids = []
@ -259,7 +259,8 @@ class SubjectsController < ApplicationController
CourseSecondCategory.create!(name: stage.name, course_id: @course.id, category_type: "shixun_homework", CourseSecondCategory.create!(name: stage.name, course_id: @course.id, category_type: "shixun_homework",
course_module_id: course_module.id, position: course_module.course_second_categories.count + 1) course_module_id: course_module.id, position: course_module.course_second_categories.count + 1)
stage.shixuns.no_jupyter.where(id: params[:shixun_ids], status: 2).each do |shixun| shixuns = stage.shixuns.no_jupyter.published.where(id: params[:shixun_ids]).reorder("field(shixuns.id, #{order_ids})")
shixuns.each do |shixun|
homework = HomeworksService.new.create_homework shixun, @course, category, current_user homework = HomeworksService.new.create_homework shixun, @course, category, current_user
homework_ids << homework.id homework_ids << homework.id
end end

@ -2,8 +2,6 @@ class TagDisciplinesController < ApplicationController
before_action :require_login before_action :require_login
def create def create
tip_exception("请输入知识点") if params[:name].blank?
tip_exception("输入字符长度限制在15个以内") if params[:name].length > 15
sub_discipline = SubDiscipline.find_by!(id: params[:sub_discipline_id]) sub_discipline = SubDiscipline.find_by!(id: params[:sub_discipline_id])
tip_exception("重复的知识点") if sub_discipline.tag_disciplines.exists?(name: params[:name].to_s.strip) tip_exception("重复的知识点") if sub_discipline.tag_disciplines.exists?(name: params[:name].to_s.strip)
tag_discipline = TagDiscipline.create!(name: params[:name].to_s.strip, sub_discipline: sub_discipline, user_id: current_user.id) tag_discipline = TagDiscipline.create!(name: params[:name].to_s.strip, sub_discipline: sub_discipline, user_id: current_user.id)

@ -5,7 +5,7 @@ class TidingsController < ApplicationController
after_action :update_onclick_time!, only: [:index] after_action :update_onclick_time!, only: [:index]
def index def index
tidings = current_user.tidings tidings = current_user.tidings.visible
@onclick_time = current_user.click_time @onclick_time = current_user.click_time
tiding_types = tiding_types =
@ -19,8 +19,9 @@ class TidingsController < ApplicationController
end end
tidings = tidings.where(tiding_type: tiding_types) if tiding_types.present? tidings = tidings.where(tiding_type: tiding_types) if tiding_types.present?
tidings = tidings.where(container_type: 'JoinCourse') if params[:type] == 'course_apply' tidings = tidings.where(container_type: 'JoinCourse', status: 0) if params[:type] == 'course_apply'
@course_apply_count = tidings.where("created_at > '#{@onclick_time}'").where(container_type: 'JoinCourse').count # @course_apply_count = tidings.where("created_at > '#{@onclick_time}'").where(container_type: 'JoinCourse', status: 0).count
@course_apply_count = tidings.where(container_type: 'JoinCourse', status: 0).count
tidings = tidings.where(container_type: 'ProjectPackage') if params[:type] == 'project_package' tidings = tidings.where(container_type: 'ProjectPackage') if params[:type] == 'project_package'

@ -13,7 +13,7 @@ class Users::VideosController < Users::BaseController
end end
def update def update
return render_error('该状态下不能编辑视频信息') unless current_video.published? return render_error('该状态下不能编辑视频信息') unless (current_video.published? || current_video.course_videos.present?)
current_video.update!(title: params[:title]) current_video.update!(title: params[:title])
@ -39,6 +39,13 @@ class Users::VideosController < Users::BaseController
@videos = paginate videos @videos = paginate videos
end end
def get_video_data
start_time = params[:start_time].to_time.utc.strftime('%Y-%m-%dT%H:%M:%SZ')
end_time = params[:end_time].to_time.utc.strftime('%Y-%m-%dT%H:%M:%SZ')
result = AliyunVod::Service.video_data(current_video.uuid, start_time, end_time)
render :json => {data: result}
end
def batch_publish def batch_publish
Videos::BatchPublishService.call(observed_user, batch_publish_params) Videos::BatchPublishService.call(observed_user, batch_publish_params)
render_ok render_ok
@ -50,6 +57,14 @@ class Users::VideosController < Users::BaseController
def current_video def current_video
@_current_video ||= observed_user.videos.find_by(id: params[:id]) @_current_video ||= observed_user.videos.find_by(id: params[:id])
if @_current_video.nil?
video = Video.find_by(id: params[:id])
if video.course_videos.present?
video
end
else
@_current_video
end
end end
def search_params def search_params
@ -57,6 +72,6 @@ class Users::VideosController < Users::BaseController
end end
def batch_publish_params def batch_publish_params
params.permit(videos: %i[video_id title]) params.permit(videos: %i[video_id title course_id])
end end
end end

@ -52,7 +52,7 @@ class UsersController < ApplicationController
def attachment_show def attachment_show
file_name = params[:file_name] file_name = params[:file_name]
path = params[:path] path = params[:path] || edu_setting('attachment_folder')
send_file "#{path}/#{file_name}", :filename => "#{file_name}", send_file "#{path}/#{file_name}", :filename => "#{file_name}",
:type => 'game', :type => 'game',
:disposition => 'attachment' #inline can open in browser :disposition => 'attachment' #inline can open in browser

@ -0,0 +1,26 @@
class Weapps::ChallengesController < Weapps::BaseController
before_action :require_login
before_action :set_challenge
def is_play
# 关卡有展示效果 || 选择题 || jupyter实训 || vnc || 隐藏代码窗口 || html+css实训
# @challenge.show_type != -1 || @challenge.st == 1 || @shixun.is_jupyter? || @shixun.vnc ||
# @shixun.hide_code? || (@shixun.small_mirror_name & ["Css", "Html", "Web"]).present?
play = @challenge.st == 1 || @shixun.is_jupyter? || @shixun.vnc ||
@shixun.hide_code? || (@shixun.small_mirror_name & ["Css", "Html", "Web"]).present?
if play
normal_status(-5, "该关卡暂不支持小程序")
else
render_ok
end
end
private
def set_challenge
@challenge = Challenge.find_by!(id: params[:id])
@shixun = @challenge.shixun
end
end

@ -1,6 +1,7 @@
class Weapps::CoursesController < Weapps::BaseController class Weapps::CoursesController < Weapps::BaseController
before_action :require_login before_action :require_login
before_action :set_course, :user_course_identity, except: [:create] before_action :set_course, except: [:create]
before_action :user_course_identity, except: [:basic_info, :create]
before_action :check_account, only: [:create] before_action :check_account, only: [:create]
before_action :teacher_allowed, only: [:edit, :update] before_action :teacher_allowed, only: [:edit, :update]
before_action :teacher_or_admin_allowed, only: [:change_member_roles, :delete_course_teachers] before_action :teacher_or_admin_allowed, only: [:change_member_roles, :delete_course_teachers]
@ -9,19 +10,23 @@ class Weapps::CoursesController < Weapps::BaseController
# return render_error("只有老师身份才能创建课堂") unless current_user.is_teacher? # return render_error("只有老师身份才能创建课堂") unless current_user.is_teacher?
course = Course.new(tea_id: current_user.id) course = Course.new(tea_id: current_user.id)
Weapps::CreateCourseService.call(course, course_params) Weapps::CreateCourseService.call(course, course_params)
render_ok render_ok(id: course.id)
rescue ApplicationService::Error => ex rescue ApplicationService::Error => ex
render_error(ex.message) render_error(ex.message)
end end
def basic_info
@course = current_course
end
def edit def edit
@course = current_course @course = current_course
end end
def update def update
Weapps::UpdateCourseService.call(current_course, update_course_params) course = Weapps::UpdateCourseService.call(current_course, update_course_params)
render_ok render_ok(id: course.id)
end end
def show def show

@ -17,7 +17,13 @@ class Weapps::SessionsController < Weapps::BaseController
# session[:wechat_user_extra].delete(:nickName) # session[:wechat_user_extra].delete(:nickName)
# 绑定微信号 # 绑定微信号
OpenUsers::Wechat.create!(user: user, uid: session_unionid) if user.wechat_open_user.blank? # open_user = OpenUsers::Wechat.find_by(uid: session_unionid)
# if open_user.present? && open_user.user_id.nil?
# open_user.update!(user_id: user.id)
# els
if user.wechat_open_user.blank?
OpenUsers::Wechat.create!(user: user, uid: session_unionid)
end
successful_authentication(user) successful_authentication(user)
end end

@ -0,0 +1,15 @@
class Weapps::ShixunListsController < ApplicationController
before_action :require_login
def index
results = Weapps::ShixunSearchService.call(search_params, current_laboratory)
@total_count = results.size
@results = paginate results
end
private
def search_params
params.permit(:keyword, :type, :page, :limit, :order, :status, :diff, :sort, :no_jupyter)
end
end

@ -0,0 +1,28 @@
class Weapps::SubjectsController < Weapps::BaseController
before_action :require_login
before_action :find_subject, except: [:index]
# 首页
def index
subjects = Weapps::SubjectQuery.call(current_laboratory, params)
@subject_count = subjects.map(&:id).size
@subjects = paginate subjects
end
# 详情
def show
# 合作团队
Rails.logger.info("##########subject: #{@subject.id}")
@members = @subject.subject_members.includes(:user)
shixuns = @subject.shixuns.published.pluck(:id)
challenge_ids = Challenge.where(shixun_id: shixuns).pluck(:id)
# 实训路径中的所有实训标签
@tags = ChallengeTag.where(challenge_id: challenge_ids).pluck(:name).uniq
end
private
def find_subject
@subject = Subject.find(params[:id])
end
end

@ -0,0 +1,16 @@
class Weapps::UnbindAccountsController < Weapps::BaseController
before_action :require_login
def show
@user = current_user
end
def destroy
open_user = OpenUsers::Wechat.find_by!(user_id: current_user.id)
session[:unionid] = open_user.uid
open_user.destroy!
UserAction.create(action_id: current_user.id, action_type: "UnbindWechat", user_id: current_user.id, :ip => request.remote_ip)
logout_user
render_ok
end
end

@ -321,6 +321,10 @@ module TidingDecorator
I18n.t(locale_format(parent_container_type)) % container&.exercise_name I18n.t(locale_format(parent_container_type)) % container&.exercise_name
end end
def live_link_content
I18n.t(locale_format) % container&.course_name
end
def student_graduation_topic_content def student_graduation_topic_content
I18n.t(locale_format) % container&.graduation_topic.try(:name) I18n.t(locale_format) % container&.graduation_topic.try(:name)
end end

@ -65,6 +65,8 @@ module CoursesHelper
"/courses/#{course.id}/course_groups" "/courses/#{course.id}/course_groups"
when "statistics" when "statistics"
"/courses/#{course.id}/statistics" "/courses/#{course.id}/statistics"
when "video"
"/courses/#{course.id}/course_videos"
end end
end end
@ -126,6 +128,8 @@ module CoursesHelper
course.informs.count course.informs.count
when "online_learning" when "online_learning"
course.shixuns.count course.shixuns.count
when "video"
course.course_videos.count + course.live_links.count
end end
end end

@ -171,10 +171,10 @@ module HomeworkCommonsHelper
{status: status, time: time} {status: status, time: time}
end end
# 作品数统计type 1 已提交 0 未提交 # 作品数统计type 1 已提交 0 未提交 2 所有
def studentwork_count homework_common, type, member def studentwork_count homework_common, type, member
student_works = homework_common.teacher_works(member) student_works = homework_common.teacher_works(member)
type == 1 ? student_works.where("work_status != 0").size : student_works.where(work_status: 0).size type == 2 ? student_works.size : (type == 1 ? student_works.where("work_status != 0").size : student_works.where(work_status: 0).size)
end end
# 上次查重的时间 # 上次查重的时间

@ -152,7 +152,7 @@ module ShixunsHelper
challenge_program_name = [] challenge_program_name = []
shixun.challenges.map(&:exec_path).each do |exec_path| shixun.challenges.map(&:exec_path).each do |exec_path|
challenge_program_name << "\"#{exec_path}\"" challenge_program_name << "\"#{exec_path}\""
if shixun.main_mirror_name == "Java" if shixun.main_mirror_name == "Java" || shixun.main_mirror_name == "Openjdk10/VNC"
if exec_path.nil? || exec_path.split("src/")[1].nil? if exec_path.nil? || exec_path.split("src/")[1].nil?
source = "\"\"" source = "\"\""
else else

@ -1,15 +1,16 @@
module Weapps::CoursesHelper module Weapps::CoursesHelper
require 'chinese_pinyin' require 'chinese_pinyin'
def teacher_list teachers def teacher_list teachers, user_course_identity
data = [] data = []
teachers.each do |teacher| teachers.each do |teacher|
if teacher.user.present? if teacher.user.present?
teacher_user = teacher.user teacher_user = teacher.user
name = teacher_user.real_name name = teacher_user.real_name
role = teacher.role == "CREATOR" ? "管理员" : teacher.role == "PROFESSOR" ? "教师" : "助教" role = teacher.role == "CREATOR" ? "管理员" : teacher.role == "PROFESSOR" ? "教师" : "助教"
member_roles = user_course_identity < Course::ASSISTANT_PROFESSOR ? teacher_user.course_role(teacher.course) : []
item = {name: name, course_member_id: teacher.id, login: teacher_user.login, user_id: teacher.user_id, role: role, item = {name: name, course_member_id: teacher.id, login: teacher_user.login, user_id: teacher.user_id, role: role,
school: teacher_user.school_name, image_url: url_to_avatar(teacher_user)} school: teacher_user.school_name, image_url: url_to_avatar(teacher_user), member_roles: member_roles}
pinyin = Pinyin.t(name.strip, splitter: '') pinyin = Pinyin.t(name.strip, splitter: '')
first_char = pinyin[0] first_char = pinyin[0]
letter = first_letter first_char letter = first_letter first_char
@ -28,15 +29,16 @@ module Weapps::CoursesHelper
end end
def student_list students, excellent def student_list students, excellent, user_course_identity
data = [] data = []
students.each do |student| students.each do |student|
if student.user.present? if student.user.present?
student_user = student.user student_user = student.user
name = student_user.real_name name = student_user.real_name
phone = excellent ? "" : student_user.hidden_phone phone = excellent ? "" : student_user.hidden_phone
member_roles = user_course_identity < Course::ASSISTANT_PROFESSOR ? student_user.course_role(student.course) : []
item = {name: name, course_member_id: student.id, login: student_user.login, user_id: student.user_id, item = {name: name, course_member_id: student.id, login: student_user.login, user_id: student.user_id,
student_id: student_user.student_id, image_url: url_to_avatar(student_user), phone: phone} student_id: student_user.student_id, image_url: url_to_avatar(student_user), phone: phone, member_roles: member_roles}
pinyin = Pinyin.t(name.strip, splitter: '') pinyin = Pinyin.t(name.strip, splitter: '')
first_char = pinyin[0] first_char = pinyin[0]
letter = first_letter first_char letter = first_letter first_char

@ -0,0 +1,27 @@
# 直播开启的消息通知
class LivePublishJob < ApplicationJob
queue_as :notify
def perform(live_id)
live = LiveLink.find_by(id: live_id)
return if live.blank? || live.course.blank?
course = live.course
attrs = %i[
user_id trigger_user_id container_id container_type parent_container_id parent_container_type
belong_container_id belong_container_type viewed tiding_type created_at updated_at
]
same_attrs = {
trigger_user_id: live.user_id, container_id: live.id, container_type: 'LiveLink',
parent_container_id: live.id, parent_container_type: 'LiveLink',
belong_container_id: live.course_id, belong_container_type: 'Course',
viewed: 0, tiding_type: 'LiveLink'
}
Tiding.bulk_insert(*attrs) do |worker|
course.students.pluck(:user_id).each do |user_id|
worker.add same_attrs.merge(user_id: user_id)
end
end
end
end

@ -37,4 +37,19 @@ module AliyunVod::Service::VideoManage
result result
end end
# 视频播放数据
def video_data(video_id, start_time, end_time)
params = {
Action: 'DescribePlayVideoStatis',
VideoId: video_id,
StartTime: start_time,
EndTime: end_time,
}.merge(base_params)
puts params
result = request(:post, params)
result
end
end end

@ -4,4 +4,5 @@ module CustomRegexp
LASTNAME = /\A[a-zA-Z0-9\u4e00-\u9fa5]+\z/ LASTNAME = /\A[a-zA-Z0-9\u4e00-\u9fa5]+\z/
NICKNAME = /\A[\u4e00-\u9fa5_a-zA-Z0-9]+\z/ NICKNAME = /\A[\u4e00-\u9fa5_a-zA-Z0-9]+\z/
PASSWORD = /\A[a-z_A-Z0-9\-\.!@#\$%\\\^&\*\)\(\+=\{\}\[\]\/",'_<>~\·`\?:;|]{8,16}\z/ PASSWORD = /\A[a-z_A-Z0-9\-\.!@#\$%\\\^&\*\)\(\+=\{\}\[\]\/",'_<>~\·`\?:;|]{8,16}\z/
URL = /\Ahttps?:\/\/[-A-Za-z0-9+&@#\/%?=~_|!:,.;]+[-A-Za-z0-9+&@#\/%=~_|]\z/
end end

@ -28,7 +28,7 @@ class Challenge < ApplicationRecord
scope :fields_for_list, -> { select([:id, :subject, :st, :score, :position, :shixun_id]) } scope :fields_for_list, -> { select([:id, :subject, :st, :score, :position, :shixun_id]) }
validates :task_pass, length: { maximum: 10000, too_long: "不能超过10000个字符" } validates :task_pass, length: { maximum: 35000, too_long: "不能超过35000个字符" }
after_commit :create_diff_record after_commit :create_diff_record

@ -3,7 +3,7 @@ class ChallengeAnswer < ApplicationRecord
belongs_to :challenge belongs_to :challenge
has_many :game_answers, :dependent => :destroy has_many :game_answers, :dependent => :destroy
validates :contents, length: { maximum: 5000 , too_long: "不能超过5000个字符"} validates :contents, length: { maximum: 25000 , too_long: "不能超过25000个字符"}
def view_answer_time(user_id) def view_answer_time(user_id)
game_answers.where(user_id: user_id).last&.view_time game_answers.where(user_id: user_id).last&.view_time

@ -4,6 +4,6 @@ class ChallengeChoose < ApplicationRecord
has_many :challenge_tags, :dependent => :destroy has_many :challenge_tags, :dependent => :destroy
has_many :challenge_questions, dependent: :destroy has_many :challenge_questions, dependent: :destroy
validates :subject, length: { maximum: 1000, too_long: "不能超过1000个字符" } validates :subject, length: { maximum: 25000, too_long: "不能超过25000个字符" }
end end

@ -81,6 +81,13 @@ class Course < ApplicationRecord
# 老版的members弃用 现用course_members # 老版的members弃用 现用course_members
has_many :members has_many :members
# 视频
has_many :course_videos, dependent: :destroy
has_many :videos, through: :course_videos
# 直播
has_many :live_links, dependent: :destroy
validate :validate_sensitive_string validate :validate_sensitive_string
scope :hidden, ->(is_hidden = true) { where(is_hidden: is_hidden) } scope :hidden, ->(is_hidden = true) { where(is_hidden: is_hidden) }
@ -206,7 +213,7 @@ class Course < ApplicationRecord
end end
def all_course_module_types def all_course_module_types
%w[activity announcement online_learning shixun_homework common_homework group_homework exercise attachment course_group graduation poll board statistics] %w[activity announcement online_learning shixun_homework common_homework group_homework exercise attachment course_group graduation poll board statistics video]
end end
def get_course_module_by_type(type) def get_course_module_by_type(type)
@ -406,6 +413,7 @@ class Course < ApplicationRecord
when 'exercise' then '试卷' when 'exercise' then '试卷'
when 'poll' then '问卷' when 'poll' then '问卷'
when 'attachment' then '资源' when 'attachment' then '资源'
when 'video' then '视频直播'
when 'board' then '讨论' when 'board' then '讨论'
when 'course_group' then '分班' when 'course_group' then '分班'
when 'statistics' then '统计' when 'statistics' then '统计'
@ -425,9 +433,10 @@ class Course < ApplicationRecord
when 'exercise' then 8 when 'exercise' then 8
when 'poll' then 9 when 'poll' then 9
when 'attachment' then 10 when 'attachment' then 10
when 'board' then 11 when 'video' then 11
when 'course_group' then 12 when 'board' then 12
when 'statistics' then 13 when 'course_group' then 13
when 'statistics' then 14
else 100 else 100
end end
end end

@ -0,0 +1,4 @@
class CourseVideo < ApplicationRecord
belongs_to :course
belongs_to :video
end

@ -4,4 +4,7 @@ class Discipline < ApplicationRecord
has_many :shixun_sub_disciplines, -> { where("shixun = 1") }, class_name: "SubDiscipline" has_many :shixun_sub_disciplines, -> { where("shixun = 1") }, class_name: "SubDiscipline"
has_many :subject_sub_disciplines, -> { where("subject = 1") }, class_name: "SubDiscipline" has_many :subject_sub_disciplines, -> { where("subject = 1") }, class_name: "SubDiscipline"
has_many :question_sub_disciplines, -> { where("question = 1") }, class_name: "SubDiscipline" has_many :question_sub_disciplines, -> { where("question = 1") }, class_name: "SubDiscipline"
validates_presence_of :name
end end

@ -35,7 +35,7 @@ class HomeworkCommon < ApplicationRecord
# 学生的查重情况 # 学生的查重情况
has_many :homework_review_results, :dependent => :destroy has_many :homework_review_results, :dependent => :destroy
validates :name, length: { maximum: 60, too_long: "不能超过60个字符" } validates :name, presence: true, length: { maximum: 60, too_long: "不能超过60个字符" }
validates :description, length: { maximum: 15000, too_long: "不能超过15000个字符" } validates :description, length: { maximum: 15000, too_long: "不能超过15000个字符" }
validates :explanation, length: { maximum: 5000, too_long: "不能超过5000个字符" } validates :explanation, length: { maximum: 5000, too_long: "不能超过5000个字符" }
validates :reference_answer, length: { maximum: 15000, too_long: "不能超过15000个字符" } validates :reference_answer, length: { maximum: 15000, too_long: "不能超过15000个字符" }

@ -0,0 +1,21 @@
class LiveLink < ApplicationRecord
belongs_to :course
belongs_to :user
has_many :tidings, as: :container, dependent: :destroy
# validates :url, format: { with: CustomRegexp::URL, message: "必须为网址超链接" }
validates :description, length: { maximum: 100, too_long: "不能超过100个字符" }
validates :course_name, presence: true
validates :platform, presence: true
# validates :live_time, presence: true
validates :duration, numericality: { only_integer: true, greater_than: 0}, allow_blank: true
def op_auth?
user == User.current || User.current.admin_or_business?
end
def delete_auth?
user == User.current || User.current.admin?
end
end

@ -8,6 +8,7 @@ class MirrorRepository < ApplicationRecord
scope :published_mirror, -> { where(status: [1,2,3,5]) } scope :published_mirror, -> { where(status: [1,2,3,5]) }
scope :published_main_mirror, -> { published_mirror.where(main_type: 1) } scope :published_main_mirror, -> { published_mirror.where(main_type: 1) }
scope :published_small_mirror, -> { published_mirror.where(main_type: 0) } scope :published_small_mirror, -> { published_mirror.where(main_type: 0) }
scope :small_mirror, -> { where(main_type: 0) }
def deletable? def deletable?
status != 1 && !shixun_mirror_repositories.exists? status != 1 && !shixun_mirror_repositories.exists?

@ -171,7 +171,8 @@ class Shixun < ApplicationRecord
# 实训对应的镜像小类别名(已选) # 实训对应的镜像小类别名(已选)
def small_mirror_name def small_mirror_name
mirror_repositories.published_small_mirror.map(&:type_name) names = mirror_repositories.small_mirror.map(&:type_name)
names.blank? ? [] : names
end end
def small_mirror_id def small_mirror_id

@ -111,6 +111,7 @@ class StudentWork < ApplicationRecord
# 作品总体评价 # 作品总体评价
def overall_appraisal def overall_appraisal
return "--" if work_status == 0
case (self.work_score.to_f / homework_common.total_score).round(2) case (self.work_score.to_f / homework_common.total_score).round(2)
when (0.90..1.00) when (0.90..1.00)
'优秀' '优秀'

@ -1,9 +1,13 @@
class SubDiscipline < ApplicationRecord class SubDiscipline < ApplicationRecord
belongs_to :discipline belongs_to :discipline
has_many :tag_disciplines, dependent: :destroy has_many :tag_disciplines, dependent: :destroy
has_many :sub_discipline_containers, dependent: :destroy
has_one :hack has_one :hack
has_many :shixun_tag_disciplines, -> { where("shixun = 1") }, class_name: "TagDiscipline" has_many :shixun_tag_disciplines, -> { where("shixun = 1") }, class_name: "TagDiscipline"
has_many :subject_tag_disciplines, -> { where("subject = 1") }, class_name: "TagDiscipline" has_many :subject_tag_disciplines, -> { where("subject = 1") }, class_name: "TagDiscipline"
has_many :question_tag_disciplines, -> { where("question = 1") }, class_name: "TagDiscipline" has_many :question_tag_disciplines, -> { where("question = 1") }, class_name: "TagDiscipline"
validates_presence_of :name
end end

@ -0,0 +1,5 @@
class SubDisciplineContainer < ApplicationRecord
belongs_to :sub_discipline
belongs_to :container, polymorphic: true, optional: true, touch: true
end

@ -30,6 +30,8 @@ class Subject < ApplicationRecord
has_many :subject_course_records, dependent: :destroy has_many :subject_course_records, dependent: :destroy
has_many :subject_shixun_infos, dependent: :destroy has_many :subject_shixun_infos, dependent: :destroy
has_many :subject_user_infos, dependent: :destroy has_many :subject_user_infos, dependent: :destroy
has_many :sub_discipline_containers, as: :container, dependent: :destroy
has_many :sub_disciplines, through: :sub_discipline_containers
validates :name, length: { maximum: 60, too_long: "不能超过60个字符" } validates :name, length: { maximum: 60, too_long: "不能超过60个字符" }
validates :description, length: { maximum: 8000, too_long: "不能超过8000个字符" } validates :description, length: { maximum: 8000, too_long: "不能超过8000个字符" }
@ -63,6 +65,10 @@ class Subject < ApplicationRecord
excellent ? CourseMember.where(role: 4, course_id: courses.pluck(:id)).pluck(:user_id).length : shixuns.pluck(:myshixuns_count).sum excellent ? CourseMember.where(role: 4, course_id: courses.pluck(:id)).pluck(:user_id).length : shixuns.pluck(:myshixuns_count).sum
end end
def myshixuns_count
shixuns.pluck(:myshixuns_count).sum
end
def all_score def all_score
subject_shixun_score + subject_shixun_choose_score subject_shixun_score + subject_shixun_choose_score
end end

@ -4,6 +4,7 @@ class TagDiscipline < ApplicationRecord
has_many :tag_discipline_containers, dependent: :destroy has_many :tag_discipline_containers, dependent: :destroy
validates_presence_of :name validates_presence_of :name
validates :name, length: { maximum: 15, too_long: "不能超过15个字符" }
def discipline def discipline
sub_discipline&.discipline sub_discipline&.discipline

@ -1,7 +1,7 @@
class TestSet < ApplicationRecord class TestSet < ApplicationRecord
# match_rule: 匹配规则: full 完全匹配, last 末尾匹配 # match_rule: 匹配规则: full 完全匹配, last 末尾匹配
# #
validates :input, length: { maximum: 5000, too_long: "不能超过5000个字符" } validates :input, length: { maximum: 65000, too_long: "不能超过65000个字符" }
validates :output, length: { maximum: 5000, too_long: "不能超过5000个字符" } validates :output, length: { maximum: 65000, too_long: "不能超过65000个字符" }
end end

@ -7,6 +7,8 @@ class Tiding < ApplicationRecord
has_many :attachments, as: :container has_many :attachments, as: :container
scope :visible, -> { where(is_delete: 0) }
def identifier def identifier
value = nil value = nil

@ -4,6 +4,7 @@ class Video < ApplicationRecord
belongs_to :user belongs_to :user
has_many :video_applies, dependent: :destroy has_many :video_applies, dependent: :destroy
has_many :course_videos, dependent: :destroy
has_one :processing_video_apply, -> { where(status: :pending) }, class_name: 'VideoApply' has_one :processing_video_apply, -> { where(status: :pending) }, class_name: 'VideoApply'
aasm(:status) do aasm(:status) do
@ -33,4 +34,8 @@ class Video < ApplicationRecord
transitions from: :uploading, to: :uploaded transitions from: :uploading, to: :uploaded
end end
end end
def video_play_duration
(play_duration / (60*60.0)).ceil
end
end end

@ -0,0 +1,37 @@
class Weapps::SubjectQuery < ApplicationQuery
include CustomSortable
attr_reader :params
def initialize(current_laboratory, params)
@current_laboratory = current_laboratory
@params = params
end
def call
subjects = @current_laboratory.subjects.unhidden.visible
# 课程体系的过滤
if params[:sub_discipline_id].present?
subjects = subjects.joins(:sub_disciplines).where(sub_disciplines: {id: params[:sub_discipline_id]})
elsif params[:discipline_id].present?
subjects = subjects.joins(:sub_disciplines).where(sub_disciplines: {discipline_id: params[:discipline_id]})
else
subjects = subjects.joins(:sub_discipline_containers).where(sub_discipline_containers: {container_type: "Subject"})
end
subjects = subjects.left_joins(:shixuns).select('subjects.id, subjects.name, subjects.excellent, subjects.stages_count, subjects.status, subjects.homepage_show,
subjects.shixuns_count, subjects.updated_at, IFNULL(sum(shixuns.myshixuns_count), 0) myshixuns_count')
.group('subjects.id').order("subjects.homepage_show #{sort_type}, #{order_type} #{sort_type}")
subjects
end
private
def order_type
params[:order] || "updated_at"
end
def sort_type
params[:sort] || "desc"
end
end

@ -36,10 +36,10 @@ class Admins::ImportCourseMemberService < ApplicationService
member = course.course_members.find_by(user_id: user.id, role: data.role.to_i) member = course.course_members.find_by(user_id: user.id, role: data.role.to_i)
# 如果已是课堂成员且是学生身份and不在指定的分班则移动到该分班 # 如果已是课堂成员且是学生身份and不在指定的分班则移动到该分班
if member.present? && member.role == 'STUDENT' && course_group && member.course_group_id != course_group&.id if member.present? && member.role == 'STUDENT' && course_group && member.course_group_id != course_group&.id.to_i
member.update!(course_group_id: course_group&.id) member.update!(course_group_id: course_group&.id.to_i)
elsif member.blank? elsif member.blank?
course.course_members.create!(user_id: user.id, role: data.role.to_i, course_group_id: course_group&.id) course.course_members.create!(user_id: user.id, role: data.role.to_i, course_group_id: course_group&.id.to_i)
extra = extra =
case data.role.to_i case data.role.to_i
when 2 then 9 when 2 then 9

@ -60,7 +60,7 @@ class Subjects::CopySubjectService < ApplicationService
shixun = stage_shixun.shixun shixun = stage_shixun.shixun
to_shixun = Shixun.new to_shixun = Shixun.new
to_shixun.attributes = shixun.attributes.dup.except('id', 'user_id', 'identifier', 'homepage_show', to_shixun.attributes = shixun.attributes.dup.except('id', 'user_id', 'identifier', 'homepage_show',
'use_scope', 'averge_star', 'myshixuns_count', 'challenges_count', "public") 'use_scope', 'averge_star', 'myshixuns_count', 'challenges_count')
to_shixun.identifier = Util::UUID.generate_identifier(Shixun, 8) to_shixun.identifier = Util::UUID.generate_identifier(Shixun, 8)
to_shixun.user_id = user.id to_shixun.user_id = user.id
if laboratory if laboratory

@ -22,7 +22,7 @@ class Subjects::CourseUsedInfoService < ApplicationService
# choice_shixun_frequency: 选用该课程实训的次数 # choice_shixun_frequency: 选用该课程实训的次数
course_info = [] course_info = []
schools.find_in_batches do |s| schools.find_in_batches do |s|
Parallel.each(s) do |school| s.each do |school|
name = school.name name = school.name
course_count = school.course_count course_count = school.course_count
student_count = school.courses.joins(:course_members).where(course_members: {role: 4, course_id: course_ids}).size student_count = school.courses.joins(:course_members).where(course_members: {role: 4, course_id: course_ids}).size

@ -11,7 +11,7 @@ class Subjects::ShixunUsedInfoService < ApplicationService
position = stage.position position = stage.position
shixuns = stage.shixuns.includes(myshixuns: :games, homework_commons: :course) shixuns = stage.shixuns.includes(myshixuns: :games, homework_commons: :course)
shixuns.find_in_batches(batch_size: 1000) do |s| shixuns.find_in_batches(batch_size: 1000) do |s|
Parallel.each_with_index(s, in_processes: 2) do |shixun, index| s.each_with_index do |shixun, index|
stage = "#{position}-#{index+1}" stage = "#{position}-#{index+1}"
name = shixun.name name = shixun.name
myshixuns = shixun.myshixuns myshixuns = shixun.myshixuns

@ -13,7 +13,7 @@ class Subjects::UserUsedInfoService < ApplicationService
users_info = [] users_info = []
users = User.includes(myshixuns: :games).where(myshixuns: {shixun_id: shixun_ids}, games: {status: 2}, users: {is_test: false}) users = User.includes(myshixuns: :games).where(myshixuns: {shixun_id: shixun_ids}, games: {status: 2}, users: {is_test: false})
users.find_in_batches(batch_size: 500) do |u| users.find_in_batches(batch_size: 500) do |u|
Parallel.each(u, in_processes: 2) do |user| u.each do |user|
myshixuns = user.myshixuns.select{|m| shixun_ids.include?(m.shixun_id)} myshixuns = user.myshixuns.select{|m| shixun_ids.include?(m.shixun_id)}
name = "#{user.lastname}#{user.firstname}" name = "#{user.lastname}#{user.firstname}"
passed_myshixun_count = myshixuns.select{|m| m.status == 1}.size passed_myshixun_count = myshixuns.select{|m| m.status == 1}.size

@ -11,22 +11,38 @@ class Videos::BatchPublishService < ApplicationService
def call def call
video_params = Array.wrap(params[:videos]).compact video_params = Array.wrap(params[:videos]).compact
return if video_params.blank? return if video_params.blank?
Rails.logger.info("#####video_course: #{video_params}")
video_ids = [] video_ids = []
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
video_params.each do |param| video_params.each do |param|
video = user.videos.find_by(uuid: param[:video_id]) video = user.videos.find_by(uuid: param[:video_id])
Rails.logger.info("video.processing_video_apply:#{video}")
Rails.logger.info("video.processing_video_apply:#{video.blank? || video.processing_video_apply}")
next if video.blank? || video.processing_video_apply.present? next if video.blank? || video.processing_video_apply.present?
raise Error, '视频还未上传完成' if video.vod_uploading? raise Error, '视频还未上传完成' if video.vod_uploading?
video.title = param[:title].to_s.strip.presence || video.title video.title = param[:title].to_s.strip.presence || video.title
video.apply_publish video.apply_publish
if param[:course_id].present?
video.status = "published"
end
video.save! video.save!
video.video_applies.create! if param[:course_id].present?
video.video_applies.create!(status: "agreed")
else
video.video_applies.create!
end
video_ids << video.id video_ids << video.id
# 如果是课堂上传则创建课堂记录
Rails.logger.info("#####param: #{ param[:course_id]}")
if param[:course_id].present?
video.course_videos.create!(course_id: param[:course_id])
end
end end
end end

@ -20,6 +20,9 @@ class Videos::DispatchCallbackService < ApplicationService
return if video.cover_url.present? return if video.cover_url.present?
video.update!(cover_url: params['CoverUrl']) video.update!(cover_url: params['CoverUrl'])
when 'TranscodeComplete' then # 转码完成
return if video.play_url.present?
video.update!(play_url: params['FileUrl'])
end end
rescue => ex rescue => ex

@ -0,0 +1,53 @@
class Weapps::ShixunSearchService < ApplicationService
attr_reader :params, :laboratory
def initialize(params, laboratory)
@params = params
@laboratory = laboratory
end
def call
# 全部实训/我的实训
type = params[:type] || "all"
shixuns = laboratory.shixuns.published.no_jupyter
if type == "mine"
shixuns = shixuns.where(id: User.current.shixuns)
else
# 超级管理员用户显示所有未隐藏的实训、非管理员显示所有已发布的实训(对本单位公开且未隐藏未关闭)
if User.current.admin? || User.current.business? || !User.current.school_id
shixuns = shixuns.where(hidden: 0)
else
shixun_ids = ShixunSchool.where(school_id: User.current.school_id).pluck(:shixun_id)
shixun_ids = shixun_ids.reject(&:blank?).length == 0 ? -1 : shixun_ids.join(",")
shixuns = shixuns.where("use_scope = 0 or shixuns.id in (#{shixun_ids})").unhidden.publiced.or(shixuns.where(id: User.current.shixuns))
end
end
## 筛选 难度
if params[:diff].present? && params[:diff].to_i != 0
shixuns = shixuns.where(trainee: params[:diff])
end
unless params[:keyword].blank?
keyword = params[:keyword].strip
shixuns = shixuns.joins(:user).
where("concat(lastname, firstname) like :keyword or shixuns.name like :keyword",
keyword: "%#{keyword}%", name: "%#{keyword.split(" ").join("%")}%").distinct
end
shixuns.order("#{sort_str} #{order_str}")
end
private
def order_str
params[:order] || "desc"
end
def sort_str
params[:sort] || "myshixuns_count"
end
end

@ -21,6 +21,7 @@ class Weapps::UpdateCourseService < ApplicationService
end end
course.save! course.save!
end end
course
end end
private private

@ -1,2 +1,6 @@
<% if @message.present? %>
$.notify({ message: "<%= @message %>" });
<% else %>
$('.modal.admin-edit-discipline-modal').modal("hide"); $('.modal.admin-edit-discipline-modal').modal("hide");
$(".discipline-list-container").html("<%= j(render :partial => 'admins/disciplines/shared/list') %>"); $(".discipline-list-container").html("<%= j(render :partial => 'admins/disciplines/shared/list') %>");
<% end %>

@ -0,0 +1,2 @@
$.notify({ message: '删除成功' });
$(".discipline-item-<%= @repertoire_id %>").remove();

@ -0,0 +1,2 @@
$('.admin-modal-container').html("<%= j( render partial: 'admins/repertoires/shared/edit_repertoire_modal', locals: { repertoire: @repertoire } ) %>");
$('.modal.admin-edit-repertoire-modal').modal('show');

@ -0,0 +1,15 @@
<% define_admin_breadcrumbs do %>
<% add_admin_breadcrumb('技术体系', admins_repertoires_path) %>
<% end %>
<div class="box search-form-container repertoires-list-form rig">
<div class="flex-1">
<%= javascript_void_link '新增', class: 'btn btn-primary', data: { toggle: 'modal', target: '.admin-create-repertoire-modal' } %>
</div>
</div>
<div class="box admin-list-container repertoire-list-container">
<%= render(partial: 'admins/repertoires/shared/list') %>
</div>
<%= render 'admins/repertoires/shared/create_repertoire_modal' %>

@ -0,0 +1,28 @@
<div class="modal fade admin-create-repertoire-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-create-repertoire-form" data-url="<%= admins_repertoires_path %>">
<div class="form-group d-flex">
<label for="new_mirror_id" class="col-form-label">名称:</label>
<div class="w-75 d-flex flex-column">
<%= text_field_tag(:name, nil, class: 'form-control', placeholder: '请输入名称') %>
</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,23 @@
<div class="modal fade admin-edit-repertoire-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([:admins, repertoire], html: { class: 'admin-edit-repertoire-form' }, defaults: { wrapper_html: { class: 'offset-md-1 col-md-10' } }) do |f| %>
<%= f.input :name, as: :string, label: '名称' %>
<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 table-hover text-center repertoires-list-table">
<thead class="thead-light">
<tr>
<th width="6%">序号</th>
<th width="54%" class="text-left">技术体系</th>
<th width="16%">操作</th>
</tr>
</thead>
<tbody>
<% if @repertoires.present? %>
<% @repertoires.each_with_index do |repertoire, index| %>
<tr class="repertoire-item discipline-item-<%= repertoire.id %>">
<td><%= index + 1 %></td>
<td class="text-left">
<span><%= link_to repertoire.name, admins_sub_repertoires_path(repertoire_id: repertoire), :title => repertoire.name %></span>
</td>
<td>
<%= link_to '编辑', edit_admins_repertoire_path(repertoire), remote: true, class: 'action' %>
<%= delete_link '删除', admins_repertoire_path(repertoire, element: ".repertoire-item-#{repertoire.id}"), class: 'delete-repertoire-action' %>
</td>
</tr>
<% end %>
<% else %>
<%= render 'admins/shared/no_data_for_table' %>
<% end %>
</tbody>
</table>

@ -0,0 +1,2 @@
$('.modal.admin-edit-repertoire-modal').modal("hide");
$(".repertoire-list-container").html("<%= j(render :partial => 'admins/repertoires/shared/list') %>");

@ -35,6 +35,7 @@
<li> <li>
<%= sidebar_item_group('#subject-submenu', '实践课程', icon: 'th-list') do %> <%= sidebar_item_group('#subject-submenu', '实践课程', icon: 'th-list') do %>
<li><%= sidebar_item(admins_subjects_path, '课程列表', icon: 'cog', controller: 'admins-subjects') %></li> <li><%= sidebar_item(admins_subjects_path, '课程列表', icon: 'cog', controller: 'admins-subjects') %></li>
<li><%= sidebar_item(admins_subject_settings_path, '课程配置', icon: 'cog', controller: 'admins-subject_settings') %></li>
<% end %> <% end %>
</li> </li>
@ -86,6 +87,12 @@
<% end %> <% end %>
</li> </li>
<li>
<%= sidebar_item_group('#other-submenu', '其他', icon: 'list-alt') do %>
<li><%= sidebar_item(admins_repertoires_path, '技术体系', icon: 'sitemap', controller: 'admins-repertoire') %></li>
<% end %>
</li>
<li> <li>
<%= sidebar_item_group('#major-identification-submenu', '工程认证', icon: 'anchor') do %> <%= sidebar_item_group('#major-identification-submenu', '工程认证', icon: 'anchor') do %>
<li><%= sidebar_item(admins_major_informations_path, '本科专业目录', icon: 'outdent', controller: 'admins-major_informations') %></li> <li><%= sidebar_item(admins_major_informations_path, '本科专业目录', icon: 'outdent', controller: 'admins-major_informations') %></li>

@ -13,7 +13,7 @@
<%= select_tag(:use_scope, options_for_select(status_options,shixun.use_scope),class:"form-control shixun-setting-form",data:{id:shixun.id}) %> <%= select_tag(:use_scope, options_for_select(status_options,shixun.use_scope),class:"form-control shixun-setting-form",data:{id:shixun.id}) %>
</td> </td>
<td> <td>
<%= select_tag(:tag_repertoires, options_for_select(@shixun_tags,shixun.tag_repertoires.pluck(:id)),multiple:true,class:"form-control shixun-setting-form",data:{id:shixun.id},id:"tags-chosen-#{shixun.id}") %> <%= select_tag(:tag_repertoires, options_for_select(@shixun_tags,shixun.tag_repertoires.pluck(:id)),multiple:true,class:"form-control repertoire-setting-form",data:{id:shixun.id},id:"tags-chosen-#{shixun.id}") %>
</td> </td>
<td class="shixun-setting-image"> <td class="shixun-setting-image">
<% imageExists = File.exist?(disk_filename("Shixun",shixun.id)) %> <% imageExists = File.exist?(disk_filename("Shixun",shixun.id)) %>

@ -0,0 +1 @@
$.notify({ message: '更新成功' });

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

Loading…
Cancel
Save