dev_jupyter
daiao 5 years ago
commit 0b0241727e

@ -49,6 +49,8 @@ gem 'rqrcode_png'
gem 'acts-as-taggable-on', '~> 6.0' gem 'acts-as-taggable-on', '~> 6.0'
gem 'omniauth-cas'
group :development, :test do group :development, :test do
gem 'rspec-rails', '~> 3.8' gem 'rspec-rails', '~> 3.8'
end end

@ -120,5 +120,19 @@ $(document).on('turbolinks:load', function() {
}); });
} }
}); });
// ------------ 上移/下移 -------------
$('.discipline-list-container').on('click', ".move-action", function () {
var $doAction = $(this);
var disciplineId = $doAction.data('id');
var opr = $doAction.data('opr');
$.ajax({
url: '/admins/disciplines/' + disciplineId + '/adjust_position',
method: 'POST',
dataType: 'script',
data: {opr: opr}
});
});
} }
}); });

@ -5,13 +5,13 @@ $(document).on('turbolinks:load', function() {
var $addMemberModal = $('.admin-add-salesman-channel-user-modal'); var $addMemberModal = $('.admin-add-salesman-channel-user-modal');
var $addMemberForm = $addMemberModal.find('.admin-add-salesman-channel-user-form'); var $addMemberForm = $addMemberModal.find('.admin-add-salesman-channel-user-form');
var $memberSelect = $addMemberModal.find('.salesman-channel-user-select'); var $memberSelect = $addMemberModal.find('.salesman-channel-user-select');
var $salesmanIdInput = $('.salesman-channel-list-form').find(".btn-primary"); var $form = $addMemberModal.find('form.admin-add-salesman-user-form');
// 搜索
var searchscForm = $(".saleman-channel-list-form .search-form");
$addMemberModal.on('show.bs.modal', function(event){
var $link = $(event.relatedTarget);
// var salesmanId = $link.data('salesman_id');
// $salesmanIdInput.val(salesmanId);
$addMemberModal.on('show.bs.modal', function(event){
$memberSelect.select2('val', ' '); $memberSelect.select2('val', ' ');
}); });
@ -48,27 +48,72 @@ $(document).on('turbolinks:load', function() {
// var salesmanId = $salesmanIdInput.val(); // var salesmanId = $salesmanIdInput.val();
var memberIds = $memberSelect.val(); var memberIds = $memberSelect.val();
if (memberIds && memberIds.length > 0) { if (memberIds && memberIds.length > 0) {
var url = $form.data('url');
$.ajax({ $.ajax({
method: 'POST', method: 'POST',
dataType: 'json', dataType: 'json',
url: '/admins/salesman_channels/batch_add', url: url,
data: { salesman_id: $salesmanIdInput.data("salesman-id"), school_ids: memberIds }, data: $form.serialize(),
success: function(){ success: function(){
$.notify({ message: '创建成功' }); $.notify({ message: '创建成功' });
$addMemberModal.modal('hide'); $addMemberModal.modal('hide');
searchscForm.find('input[name="keyword"]').val('');
setTimeout(function(){ setTimeout(function(){
window.location.reload(); submitForm();
}, 500); }, 500);
}, },
error: function(res){ error: function(res){
var data = res.responseJSON; var data = res.responseJSON;
$form.find('.error').html(data.message); $addMemberForm.find('.error').html(data.message);
} }
}); });
} else { } else {
$addMemberModal.modal('hide'); $addMemberModal.modal('hide');
} }
}); });
// 清空
searchscForm.on('click', '.clear-btn', function () {
searchscForm.find('.start_date').val('');
searchscForm.find('.end_date').val('').trigger('change');
searchscForm.find('input[name="keyword"]').val('');
});
// 时间跨度
var baseOptions = {
autoclose: true,
language: 'zh-CN',
format: 'yyyy-mm-dd',
startDate: '2017-04-01'
};
var defineDateRangeSelect = function(element){
var options = $.extend({inputs: $(element).find('.start-date, .end-date')}, baseOptions);
$(element).datepicker(options);
$(element).find('.start-date').datepicker().on('changeDate', function(e){
$(element).find('.end-date').datepicker('setStartDate', e.date);
});
};
defineDateRangeSelect('.grow-date-input-daterange');
// 区间搜索
searchscForm.on('click', ".search-btn", function(){
submitForm();
});
var submitForm = function(){
var url = searchscForm.data('search-form-url');
var form = searchscForm;
$.ajax({
url: url,
data: form.serialize(),
dataType: "script"
})
};
} }
}); });

@ -58,7 +58,7 @@ $(document).on('turbolinks:load', function() {
$addMemberModal.modal('hide'); $addMemberModal.modal('hide');
setTimeout(function(){ setTimeout(function(){
window.location.reload(); listForm();
}, 500); }, 500);
}, },
error: function(res){ error: function(res){
@ -70,5 +70,13 @@ $(document).on('turbolinks:load', function() {
$addMemberModal.modal('hide'); $addMemberModal.modal('hide');
} }
}); });
var listForm = function(){
$.ajax({
url: '/admins/salesman_customers?salesman_id='+ $salesmanIdInput.data("salesman-id"),
dataType: "script"
});
};
} }
}); });

@ -72,5 +72,18 @@ $(document).on('turbolinks:load', function () {
data: json data: json
}); });
}); });
// ------------ 上移/下移 -------------
$('.sub-discipline-list-container').on('click', ".move-action", function () {
var $doAction = $(this);
var objectId = $doAction.data('id');
var opr = $doAction.data('opr');
$.ajax({
url: '/admins/sub_disciplines/' + objectId + '/adjust_position',
method: 'POST',
dataType: 'script',
data: {opr: opr}
});
});
} }
}); });

@ -29,6 +29,7 @@ $(document).on('turbolinks:load', function () {
} }
}); });
$(".subject-setting-list-container").on("change", '.subject-setting-form', function () { $(".subject-setting-list-container").on("change", '.subject-setting-form', function () {
var s_id = $(this).attr("data-id"); var s_id = $(this).attr("data-id");
var s_value = $(this).val(); var s_value = $(this).val();

@ -72,5 +72,19 @@ $(document).on('turbolinks:load', function () {
data: json data: json
}); });
}); });
// ------------ 上移/下移 -------------
$('.tag-discipline-list-container').on('click', ".move-action", function () {
var $doAction = $(this);
var objectId = $doAction.data('id');
var opr = $doAction.data('opr');
$.ajax({
url: '/admins/tag_disciplines/' + objectId + '/adjust_position',
method: 'POST',
dataType: 'script',
data: {opr: opr}
});
});
} }
}); });

@ -51,12 +51,12 @@ class AccountsController < ApplicationController
# todo user_extension # todo user_extension
UserExtension.create!(user_id: @user.id) UserExtension.create!(user_id: @user.id)
# 注册完成手机号或邮箱想可以奖励500金币 # 注册完成手机号或邮箱想可以奖励500金币
RewardGradeService.call( # RewardGradeService.call(
@user, # @user,
container_id: @user.id, # container_id: @user.id,
container_type: pre == 'p' ? 'Phone' : 'Mail', # container_type: pre == 'p' ? 'Phone' : 'Mail',
score: 500 # score: 500
) # )
# 注册时,记录是否是引流用户 # 注册时,记录是否是引流用户
ip = request.remote_ip ip = request.remote_ip
ua = UserAgent.find_by_ip(ip) ua = UserAgent.find_by_ip(ip)

@ -7,7 +7,7 @@ class Admins::DisciplinesController < Admins::BaseController
def create def create
name = params[:name].to_s.strip name = params[:name].to_s.strip
return render_error('名称重复') if Discipline.where(name: name).exists? return render_error('名称重复') if Discipline.where(name: name).exists?
Discipline.create!(name: name) Discipline.create!(name: name, position: Discipline.all.pluck(:position).max + 1)
render_ok render_ok
end end
@ -39,7 +39,31 @@ class Admins::DisciplinesController < Admins::BaseController
def destroy def destroy
@discipline_id = params[:id] @discipline_id = params[:id]
current_discipline.destroy! ActiveRecord::Base.transaction do
Discipline.where("position > #{current_discipline.position}").update_all("position=position-1")
current_discipline.destroy!
end
end
def adjust_position
max_position = Discipline.all.pluck(:position).max
opr = params[:opr] || "down"
if (params[:opr] == "up" && current_discipline.position == 1) || (params[:opr] == "down" && current_discipline.position == max_position)
@message = "超出范围"
else
ActiveRecord::Base.transaction do
if opr == "up"
Discipline.find_by("position = #{current_discipline.position - 1}")&.update!(position: current_discipline.position)
current_discipline.update!(position: current_discipline.position - 1)
else
Discipline.find_by("position = #{current_discipline.position + 1}")&.update!(position: current_discipline.position)
current_discipline.update!(position: current_discipline.position + 1)
end
end
end
@disciplines = Discipline.all
rescue Exception => e
@message = e.message
end end
private private

@ -2,7 +2,12 @@ class Admins::SalesmanChannelsController < Admins::BaseController
before_action :set_salesman before_action :set_salesman
def index def index
@channels = SalesmanChannel.all @channels = @salesman.salesman_channels
if params[:keyword].present?
@channels = @channels.joins(:school).where("schools.name like ?", "%#{params[:keyword]}%")
end
@start_time = params[:start_date]
@end_time = params[:end_date].blank? ? Time.now : params[:end_date]
end end
def batch_add def batch_add
@ -10,10 +15,12 @@ class Admins::SalesmanChannelsController < Admins::BaseController
school_ids = params[:school_ids] - channel_ids school_ids = params[:school_ids] - channel_ids
school_ids.each do |school_id| school_ids.each do |school_id|
school = School.find_by(id: school_id) school = School.find_by(id: school_id)
next if school.blank? next if school.blank? || @salesman.salesman_channels.where(school_id: school.id).exists?
@salesman.salesman_channels.create!(school_id: school.id) @salesman.salesman_channels.create!(school_id: school.id)
end end
render_ok render_ok
rescue Exception => ex
render_error(ex.message)
end end
def destroy def destroy

@ -10,7 +10,7 @@ class Admins::SalesmanCustomersController < Admins::BaseController
user_ids = params[:user_ids] - customer_ids user_ids = params[:user_ids] - customer_ids
user_ids.each do |user_id| user_ids.each do |user_id|
user = UserExtension.find_by(user_id: user_id) user = UserExtension.find_by(user_id: user_id)
next if user.blank? next if user.blank? || @salesman.salesman_customers.where(user_id: user.user_id).exists?
@salesman.salesman_customers.create!(user_id: user.user_id, school_id: user.school_id) @salesman.salesman_customers.create!(user_id: user.user_id, school_id: user.school_id)
end end
render_ok render_ok

@ -18,7 +18,7 @@ class Admins::ShixunSettingsController < Admins::BaseController
task_pass: params[:task_pass].present? ? params[:task_pass] : false, task_pass: params[:task_pass].present? ? params[:task_pass] : false,
code_hidden: params[:code_hidden].present? ? params[:code_hidden] : false, code_hidden: params[:code_hidden].present? ? params[:code_hidden] : false,
vip: params[:vip].present? ? params[:vip] : false, vip: params[:vip].present? ? params[:vip] : false,
is_wechat_support: params[:is_wechat_support].present? ? params[:is_wechat_support] : false no_subject: params[:no_subject].present? ? params[:no_subject] : false
} }
@shixuns_type_check = MirrorRepository.pluck(:type_name,:id) @shixuns_type_check = MirrorRepository.pluck(:type_name,:id)
@ -135,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) :code_hidden,:vip,:page_no,:id, :no_subject)
end end
end end

@ -9,7 +9,7 @@ class Admins::SubDisciplinesController < Admins::BaseController
name = params[:name].to_s.strip name = params[:name].to_s.strip
return render_error('名称不能为空') if name.blank? 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, position: current_discipline.sub_disciplines.pluck(:position).max + 1)
render_ok render_ok
end end
@ -38,9 +38,36 @@ class Admins::SubDisciplinesController < Admins::BaseController
def destroy def destroy
@sub_discipline_id = params[:id] @sub_discipline_id = params[:id]
current_sub_discipline.destroy! ActiveRecord::Base.transaction do
discipline = current_sub_discipline.discipline
discipline.sub_disciplines.where("position > #{current_sub_discipline.position}").update_all("position=position-1")
current_sub_discipline.destroy!
end
end end
def adjust_position
discipline = current_sub_discipline.discipline
max_position = discipline.sub_disciplines.pluck(:position).max
opr = params[:opr] || "down"
if (params[:opr] == "up" && current_sub_discipline.position == 1) || (params[:opr] == "down" && current_sub_discipline.position == max_position)
@message = "超出范围"
else
ActiveRecord::Base.transaction do
if opr == "up"
discipline.sub_disciplines.find_by("position = #{current_sub_discipline.position - 1}")&.update!(position: current_sub_discipline.position)
current_sub_discipline.update!(position: current_sub_discipline.position - 1)
else
discipline.sub_disciplines.find_by("position = #{current_sub_discipline.position + 1}")&.update!(position: current_sub_discipline.position)
current_sub_discipline.update!(position: current_sub_discipline.position + 1)
end
end
end
@sub_disciplines = discipline&.sub_disciplines
rescue Exception => e
@message = e.message
end
private private
def current_sub_discipline def current_sub_discipline

@ -20,6 +20,11 @@ class Admins::SubjectSettingsController < Admins::BaseController
end end
end end
def update_mobile_show
subject = Subject.find(params[:subject_id])
subject.update_attributes(:show_mobile => params[:show_mobile])
end
private private
def current_subject def current_subject

@ -8,7 +8,8 @@ class Admins::TagDisciplinesController < Admins::BaseController
def create def create
name = params[:name].to_s.strip name = params[:name].to_s.strip
return render_error('名称重复') if current_sub_discipline.tag_disciplines.where(name: name).exists? return render_error('名称重复') if current_sub_discipline.tag_disciplines.where(name: name).exists?
TagDiscipline.create!(name: name, sub_discipline_id: current_sub_discipline.id, user_id: current_user.id) TagDiscipline.create!(name: name, sub_discipline_id: current_sub_discipline.id, user_id: current_user.id,
position: current_sub_discipline.tag_disciplines.pluck(:position).max + 1)
render_ok render_ok
end end
@ -32,9 +33,36 @@ class Admins::TagDisciplinesController < Admins::BaseController
def destroy def destroy
@tag_discipline_id = params[:id] @tag_discipline_id = params[:id]
current_tag_discipline.destroy! ActiveRecord::Base.transaction do
sub_discipline = current_tag_discipline.sub_discipline
sub_discipline.tag_disciplines.where("position > #{current_tag_discipline.position}").update_all("position=position-1")
current_tag_discipline.destroy!
end
end
def adjust_position
sub_discipline = current_tag_discipline.sub_discipline
max_position = sub_discipline.tag_disciplines.pluck(:position).max
opr = params[:opr] || "down"
if (params[:opr] == "up" && current_tag_discipline.position == 1) || (params[:opr] == "down" && current_tag_discipline.position == max_position)
@message = "超出范围"
else
ActiveRecord::Base.transaction do
if opr == "up"
sub_discipline.tag_disciplines.find_by("position = #{current_tag_discipline.position - 1}")&.update!(position: current_tag_discipline.position)
current_tag_discipline.update!(position: current_tag_discipline.position - 1)
else
sub_discipline.tag_disciplines.find_by("position = #{current_tag_discipline.position + 1}")&.update!(position: current_tag_discipline.position)
current_tag_discipline.update!(position: current_tag_discipline.position + 1)
end
end
end
@tag_disciplines = sub_discipline&.tag_disciplines
rescue Exception => e
@message = e.message
end end
private private
def current_sub_discipline def current_sub_discipline

@ -1,13 +1,35 @@
class BindUsersController < ApplicationController class BindUsersController < ApplicationController
before_action :require_login # before_action :require_login
def create def create
user = CreateBindUserService.call(current_user, create_params) # user = CreateBindUserService.call(create_params)
successful_authentication(user) if user.id != current_user.id #
if params[:type] == "qq"
begin
user = CreateBindUserService.call(current_user, create_params)
successful_authentication(user) if user.id != current_user.id
render_ok render_ok
rescue ApplicationService::Error => ex rescue ApplicationService::Error => ex
render_error(ex.message) render_error(ex.message)
end
else
begin
tip_exception '系统错误' if session[:unionid].blank?
bind_user = User.try_to_login(params[:username], params[:password])
tip_exception '用户名或者密码错误' if bind_user.blank?
tip_exception '用户名或者密码错误' unless bind_user.check_password?(params[:password].to_s)
tip_exception '该账号已被绑定,请更换其他账号进行绑定' if bind_user.bind_open_user?(params[:type].to_s)
OpenUsers::Wechat.create!(user: bind_user, uid: session[:unionid])
successful_authentication(bind_user)
render_ok
rescue Exception => e
render_error(e.message)
end
end
end end
def new_user def new_user

@ -6,11 +6,21 @@ 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| rescue_from ActiveRecord::StatementInvalid do |e|
Util.logger_error e Util.logger_error e
render json: {status: -1, message: "接口数据异常"} render json: {status: -1, message: "接口数据异常"}
end end
rescue_from NoMethodError do |e|
Util.logger_error e
render json: {status: -1, message: "接口方法异常"}
end
rescue_from ActionController::UnknownFormat do |e|
render json: {status: -1, message: "接口调用非JSON格式"}
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
@ -26,10 +36,6 @@ module ControllerRescueHandler
render_error(ex.record.errors.full_messages.join(',')) render_error(ex.record.errors.full_messages.join(','))
end end
rescue_from ActionController::UnknownFormat do |e|
render json: {status: -1, message: "接口调用非JSON格式"}
end
# rescue_from RuntimeError do |ex| # rescue_from RuntimeError do |ex|
# Util.logger_error "#######ex:#{ex}" # Util.logger_error "#######ex:#{ex}"
# render_error(ex.message) # render_error(ex.message)

@ -13,7 +13,7 @@ class CoursesController < ApplicationController
end end
before_action :require_login, except: [:index, :show, :students, :teachers, :board_list, :mine, :all_course_groups, before_action :require_login, except: [:index, :show, :students, :teachers, :board_list, :mine, :all_course_groups,
:left_banner, :top_banner, :informs, :online_learning, :course_groups] :left_banner, :top_banner, :informs, :online_learning, :course_groups, :search_slim]
before_action :check_account, only: [:new, :create, :apply_to_join_course, :join_excellent_course] before_action :check_account, only: [:new, :create, :apply_to_join_course, :join_excellent_course]
before_action :check_auth, except: [:index, :show, :students, :teachers, :board_list, :mine, :all_course_groups, before_action :check_auth, except: [:index, :show, :students, :teachers, :board_list, :mine, :all_course_groups,
:left_banner, :top_banner, :apply_to_join_course, :exit_course, :course_groups] :left_banner, :top_banner, :apply_to_join_course, :exit_course, :course_groups]
@ -742,12 +742,15 @@ class CoursesController < ApplicationController
# 切换为教师 # 切换为教师
def switch_to_teacher def switch_to_teacher
begin begin
course_member = @course.course_members.find_by!(user_id: current_user.id, is_active: 1) course_student = @course.students.find_by!(user_id: current_user.id, is_active: 1)
tip_exception("切换失败") unless course_member.STUDENT? tip_exception("切换失败") unless course_student.present?
course_teacher = CourseMember.find_by!(user_id: current_user.id, role: %i[CREATOR PROFESSOR], course_id: @course.id) course_teacher = CourseMember.find_by!(user_id: current_user.id, role: %i[CREATOR PROFESSOR], course_id: @course.id)
course_member.update!(is_active: 0) ActiveRecord::Base.transaction do
course_teacher.update!(is_active: 1) course_student.destroy!
course_teacher.update!(is_active: 1)
CourseDeleteStudentDeleteWorksJob.perform_later(@course.id, [current_user.id])
end
normal_status(0, "切换成功") normal_status(0, "切换成功")
rescue => e rescue => e
uid_logger_error(e.message) uid_logger_error(e.message)
@ -758,12 +761,15 @@ class CoursesController < ApplicationController
# 切换为助教 # 切换为助教
def switch_to_assistant def switch_to_assistant
begin begin
course_member = @course.course_members.find_by!(user_id: current_user.id, is_active: 1) course_student = @course.course_members.find_by!(user_id: current_user.id, is_active: 1)
tip_exception("切换失败") unless course_member.STUDENT? tip_exception("切换失败") unless course_student.present?
course_teacher = CourseMember.find_by!(user_id: current_user.id, role: %i[ASSISTANT_PROFESSOR], course_id: @course.id) course_teacher = CourseMember.find_by!(user_id: current_user.id, role: %i[ASSISTANT_PROFESSOR], course_id: @course.id)
course_member.update!(is_active: 0) ActiveRecord::Base.transaction do
course_teacher.update!(is_active: 1) course_student.destroy!
course_teacher.update!(is_active: 1)
CourseDeleteStudentDeleteWorksJob.perform_later(@course.id, [current_user.id])
end
normal_status(0, "切换成功") normal_status(0, "切换成功")
rescue => e rescue => e
uid_logger_error(e.message) uid_logger_error(e.message)

@ -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("course_group_id", group_id) #试卷所分班的全部人数 exercise_students = @course_all_members.course_find_by_ids("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

@ -524,11 +524,11 @@ class GamesController < ApplicationController
else else
{updated_at: Time.now} {updated_at: Time.now}
end end
logger.info("#############myshixuns_update: ##{myshixuns_update}") #logger.info("#############myshixuns_update: ##{myshixuns_update}")
@myshixun.update_attributes!(myshixuns_update) @myshixun.update_attributes!(myshixuns_update)
gitUrl = repo_ip_url @myshixun.repo_path gitUrl = repo_ip_url @myshixun.repo_path
logger.info("#############giturl: ##{gitUrl}") #logger.info("#############giturl: ##{gitUrl}")
gitUrl = Base64.urlsafe_encode64(gitUrl) gitUrl = Base64.urlsafe_encode64(gitUrl)
shixun_tomcat = edu_setting('cloud_bridge') shixun_tomcat = edu_setting('cloud_bridge')
@ -554,7 +554,7 @@ class GamesController < ApplicationController
testSet << test_cases testSet << test_cases
end end
logger.info("##############testSet: #{testSet}") #logger.info("##############testSet: #{testSet}")
testCases = Base64.urlsafe_encode64(testSet.to_json) unless testSet.blank? testCases = Base64.urlsafe_encode64(testSet.to_json) unless testSet.blank?
# 评测类型: 012 用于webssh的评测 3用于vnc # 评测类型: 012 用于webssh的评测 3用于vnc
@ -581,7 +581,7 @@ class GamesController < ApplicationController
if secret_rep&.repo_name if secret_rep&.repo_name
secretGitUrl = repo_ip_url secret_rep.repo_path secretGitUrl = repo_ip_url secret_rep.repo_path
br_params.merge!({secretGitUrl: Base64.urlsafe_encode64(secretGitUrl), secretDir: secret_rep.secret_dir_path}) br_params.merge!({secretGitUrl: Base64.urlsafe_encode64(secretGitUrl), secretDir: secret_rep.secret_dir_path})
logger.info("#######br_params:#{br_params}") #logger.info("#######br_params:#{br_params}")
end end
# 中间层交互 # 中间层交互
@ -691,7 +691,7 @@ class GamesController < ApplicationController
next_game: next_game&.identifier} next_game: next_game&.identifier}
rescue Exception => e rescue Exception => e
uid_logger("choose build failed #{e.message}") uid_logger("choose build failed #{e.message}")
@result = [status: -1, contents: "#{e.message}"] tip_exception(-1, e.message)
end end
# 轮询获取状态 # 轮询获取状态
@ -700,10 +700,10 @@ class GamesController < ApplicationController
resubmit_identifier = @game.resubmit_identifier resubmit_identifier = @game.resubmit_identifier
# 如果没有超时并且正在评测中 # 如果没有超时并且正在评测中
# 判断评测中的状态有两种1、如果之前没有通关的只需判断status为1即可如果通过关则判断game的resubmit_identifier是否更新 # 判断评测中的状态有两种1、如果之前没有通关的只需判断status为1即可如果通过关则判断game的resubmit_identifier是否更新
uid_logger("################game_status: #{@game.status}") #uid_logger("################game_status: #{@game.status}")
uid_logger("################params[:resubmit]: #{params[:resubmit]}") #uid_logger("################params[:resubmit]: #{params[:resubmit]}")
uid_logger("################resubmit_identifier: #{resubmit_identifier}") #uid_logger("################resubmit_identifier: #{resubmit_identifier}")
uid_logger("################time_out: #{params[:time_out]}") #uid_logger("################time_out: #{params[:time_out]}")
sec_key = params[:sec_key] sec_key = params[:sec_key]
if (params[:time_out] == "false") && ((params[:resubmit].blank? && @game.status == 1) || (params[:resubmit].present? && if (params[:time_out] == "false") && ((params[:resubmit].blank? && @game.status == 1) || (params[:resubmit].present? &&
(params[:resubmit] != resubmit_identifier))) (params[:resubmit] != resubmit_identifier)))
@ -764,7 +764,7 @@ class GamesController < ApplicationController
end end
end end
uid_logger("game is #{@game.id}, record id is #{e_record.try(:id)}, time is**** #{Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")}") #uid_logger("game is #{@game.id}, record id is #{e_record.try(:id)}, time is**** #{Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")}")
# 记录前端总耗时 # 记录前端总耗时
record_consume_time = e_record.try(:pod_execute) record_consume_time = e_record.try(:pod_execute)
max_mem = e_record.try(:max_mem) max_mem = e_record.try(:max_mem)
@ -850,7 +850,7 @@ class GamesController < ApplicationController
@allowed_hidden_testset = @identity < User::EDU_GAME_MANAGER || @game.test_sets_view #解锁的用户 @allowed_hidden_testset = @identity < User::EDU_GAME_MANAGER || @game.test_sets_view #解锁的用户
if max_query_index > 0 if max_query_index > 0
uid_logger("max_query_index is #{max_query_index} game id is #{@game.id}, challenge_id is #{challenge.id}") #uid_logger("max_query_index is #{max_query_index} game id is #{@game.id}, challenge_id is #{challenge.id}")
@qurey_test_sets = TestSet.find_by_sql("SELECT o.code, o.actual_output, o.out_put, o.result, o.test_set_position, o.ts_time, o.ts_mem, @qurey_test_sets = TestSet.find_by_sql("SELECT o.code, o.actual_output, o.out_put, o.result, o.test_set_position, o.ts_time, o.ts_mem,
o.query_index, t.is_public, t.input, t.output, o.compile_success FROM outputs o, games g, challenges c, o.query_index, t.is_public, t.input, t.output, o.compile_success FROM outputs o, games g, challenges c,
test_sets t where g.id=#{@game.id} and c.id=#{challenge.id} and o.query_index=#{max_query_index} test_sets t where g.id=#{@game.id} and c.id=#{challenge.id} and o.query_index=#{max_query_index}

@ -876,10 +876,12 @@ class HomeworkCommonsController < ApplicationController
subjects = Subject.where(id: params[:subject_ids], status: 2).includes(stages: :shixuns).reorder("id desc") subjects = Subject.where(id: params[:subject_ids], status: 2).includes(stages: :shixuns).reorder("id desc")
@homework_ids = [] @homework_ids = []
none_shixun_ids = ShixunSchool.where("school_id != #{current_user.school_id}").pluck(:shixun_id) # none_shixun_ids = ShixunSchool.where("school_id != #{current_user.school_id}").pluck(:shixun_id)
course_module = @course.course_modules.find_by(module_type: "shixun_homework") course_module = @course.course_modules.find_by(module_type: "shixun_homework")
subjects.each do |subject| subjects.each do |subject|
shixun_ids = subject.shixuns.where(use_scope: 0).pluck(:id) +
subject.shixuns.joins(:shixun_schools).where("school_id = #{current_user.try(:school_id).to_i} and use_scope = 1").pluck(:id)
subject.stages.each do |stage| subject.stages.each do |stage|
@ -889,7 +891,7 @@ class HomeworkCommonsController < ApplicationController
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.not(shixuns: {id: none_shixun_ids}).unhidden.each do |shixun| stage.shixuns.no_jupyter.where(id: shixun_ids).unhidden.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
CreateStudentWorkJob.perform_later(homework.id) CreateStudentWorkJob.perform_later(homework.id)
@ -981,8 +983,8 @@ class HomeworkCommonsController < ApplicationController
end end
homework.homework_detail_manual.update_attributes!(comment_status: 1) homework.homework_detail_manual.update_attributes!(comment_status: 1)
if homework.course_acts.size == 0 if homework.course_act.blank?
homework.course_acts << CourseActivity.new(user_id: homework.user_id, course_id: homework.course_id) homework.course_act << CourseActivity.new(user_id: homework.user_id, course_id: homework.course_id)
end end
# 发消息 # 发消息
HomeworkCommonPushNotifyJob.perform_later(homework.id, tiding_group_ids) HomeworkCommonPushNotifyJob.perform_later(homework.id, tiding_group_ids)
@ -1043,7 +1045,7 @@ class HomeworkCommonsController < ApplicationController
def end_homework def end_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
time = Time.now.strftime("%Y-%m-%d %H:%M:%S") time = Time.now
# 已发布且未截止的作业才能立即截止 # 已发布且未截止的作业才能立即截止
@ -1084,7 +1086,7 @@ class HomeworkCommonsController < ApplicationController
homework.end_time = time homework.end_time = time
end end
homework_detail_manual.update_attributes!(comment_status: 2) if homework.end_time <= time # homework_detail_manual.update_attributes!(comment_status: 2) if homework.end_time <= time
# 实训作业的作品需要计算是否迟交 # 实训作业的作品需要计算是否迟交
if homework.homework_type == "practice" if homework.homework_type == "practice"

@ -20,11 +20,8 @@ class MainController < ApplicationController
uid_logger("main start is #{cookies[:_educoder_session]}") uid_logger("main start is #{cookies[:_educoder_session]}")
end end
# TODO: 这块之后需要整合者架构重新变化统一跳转到index后再路由分发
if params[:path] && params[:path]&.include?("educoderh5") && params[:path].split("/").first == "educoderh5" if params[:path] && params[:path]&.include?("h5educoderbuild") && params[:path].split("/").first == "h5educoderbuild"
render file: 'public/h5build/index.html', :layout => false
# TODO: 这块之后需要整合到上面去或者架构重新变化统一跳转到index后再路由分发
elsif params[:path] && params[:path]&.include?("h5educoderbuild") && params[:path].split("/").first == "h5educoderbuild"
render file: 'public/h5educoderbuild/index.html', :layout => false render file: 'public/h5educoderbuild/index.html', :layout => false
else else
render file: 'public/react/build/index.html', :layout => false render file: 'public/react/build/index.html', :layout => false

@ -91,7 +91,7 @@ class MyshixunsController < ApplicationController
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
begin begin
t1 = Time.now t1 = Time.now
uid_logger_dubug("@@@222222#{params[:jsonTestDetails]}") #uid_logger_dubug("@@@222222#{params[:jsonTestDetails]}")
jsonTestDetails = JSON.parse(params[:jsonTestDetails]) jsonTestDetails = JSON.parse(params[:jsonTestDetails])
timeCost = JSON.parse(params[:timeCost]) timeCost = JSON.parse(params[:timeCost])
brige_end_time = Time.parse(timeCost['evaluateEnd']) if timeCost['evaluateEnd'].present? brige_end_time = Time.parse(timeCost['evaluateEnd']) if timeCost['evaluateEnd'].present?
@ -101,7 +101,7 @@ class MyshixunsController < ApplicationController
sec_key = jsonTestDetails['sec_key'] sec_key = jsonTestDetails['sec_key']
server_url = jsonTestDetails['showServer'] server_url = jsonTestDetails['showServer']
uid_logger_dubug("training_task_status start-#{game_id}-1#{Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")}") #uid_logger_dubug("training_task_status start-#{game_id}-1#{Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")}")
resubmit = jsonTestDetails['resubmit'] resubmit = jsonTestDetails['resubmit']
outPut = tran_base64_decode64(jsonTestDetails['outPut']) outPut = tran_base64_decode64(jsonTestDetails['outPut'])
@ -267,7 +267,7 @@ class MyshixunsController < ApplicationController
@sec_key = generate_identifier(EvaluateRecord, 12) @sec_key = generate_identifier(EvaluateRecord, 12)
record = EvaluateRecord.create!(:user_id => current_user.id, :shixun_id => @myshixun.shixun_id, :game_id => game_id, record = EvaluateRecord.create!(:user_id => current_user.id, :shixun_id => @myshixun.shixun_id, :game_id => game_id,
:identifier => @sec_key, :exec_time => exec_time) :identifier => @sec_key, :exec_time => exec_time)
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的都不需要走版本库
vnc = @myshixun.shixun&.vnc vnc = @myshixun.shixun&.vnc
@ -282,8 +282,6 @@ class MyshixunsController < ApplicationController
else else
params[:content] params[:content]
end end
uid_logger_dubug("content_#{@myshixun.identifier}: #{content}")
uid_logger_dubug("###last_content_#{@myshixun.identifier}####{last_content}")
if content != last_content if content != last_content
@content_modified = 1 @content_modified = 1
@ -291,9 +289,6 @@ class MyshixunsController < ApplicationController
author_name = current_user.real_name author_name = current_user.real_name
author_email = current_user.git_mail author_email = current_user.git_mail
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_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,

@ -30,4 +30,22 @@ class Oauth::BaseController < ActionController::Base
@_default_yun_session = "#{request.subdomain.split('.').first}_user_id" @_default_yun_session = "#{request.subdomain.split('.').first}_user_id"
# @_default_yun_session = "#{current_laboratory.try(:identifier).split('.').first}_user_id" # @_default_yun_session = "#{current_laboratory.try(:identifier).split('.').first}_user_id"
end end
def session_openid
session[:openid]
end
def set_session_openid(openid)
Rails.logger.info("[wechat] set session openid: #{openid}")
session[:openid] = openid
end
def session_unionid
session[:unionid]
end
def set_session_unionid(unionid)
Rails.logger.info("[wechat] set session unionid: #{unionid}")
session[:unionid] = unionid
end
end end

@ -0,0 +1,13 @@
class Oauth::CasController < Oauth::BaseController
def create
user, is_new_user = Oauth::CreateORFindCasUserService.call(current_user, auth_hash)
successful_authentication(user)
redirect_to root_url
end
def auth_hash
JSON.parse(CGI.unescape(request.env['omniauth.auth'].extra.to_json))
end
end

@ -1,11 +1,32 @@
class Oauth::WechatController < Oauth::BaseController class Oauth::WechatController < Oauth::BaseController
def create def create
user, new_user = Oauth::CreateOrFindWechatAccountService.call(current_user ,params) # user, new_user = Oauth::CreateOrFindWechatAccountService.call(current_user ,params)
successful_authentication(user) begin
code = params['code'].to_s.strip
tip_exception("code不能为空") if code.blank?
new_user = false
render_ok(new_user: new_user) result = WechatOauth::Service.access_token(code)
rescue Oauth::CreateOrFindWechatAccountService::Error => ex result = WechatOauth::Service.user_info(result['access_token'], result['openid'])
render_error(ex.message)
# 存在该用户
open_user = OpenUsers::Wechat.find_by(uid: result['unionid'])
if open_user.present? && open_user.user.present?
successful_authentication(open_user.user)
else
if current_user.blank? || !current_user.logged?
new_user = true
set_session_openid(result['openid'])
set_session_unionid(result['unionid'])
else
OpenUsers::Wechat.create!(user: current_user, uid: result['unionid'])
end
end
render_ok(new_user: new_user)
rescue WechatOauth::Error => ex
render_error(ex.message)
end
end end
end end

@ -4,7 +4,8 @@ class TagDisciplinesController < ApplicationController
def create def create
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,
position: sub_discipline.tag_disciplines.pluck(:position).max + 1)
render_ok({tag_discipline_id: tag_discipline.id}) render_ok({tag_discipline_id: tag_discipline.id})
end end
end end

@ -6,7 +6,7 @@ class Weapps::ChallengesController < Weapps::BaseController
# 关卡有展示效果 || 选择题 || jupyter实训 || vnc || 隐藏代码窗口 || html+css实训 # 关卡有展示效果 || 选择题 || jupyter实训 || vnc || 隐藏代码窗口 || html+css实训
# @challenge.show_type != -1 || @challenge.st == 1 || @shixun.is_jupyter? || @shixun.vnc || # @challenge.show_type != -1 || @challenge.st == 1 || @shixun.is_jupyter? || @shixun.vnc ||
# @shixun.hide_code? || (@shixun.small_mirror_name & ["Css", "Html", "Web"]).present? # @shixun.hide_code? || (@shixun.small_mirror_name & ["Css", "Html", "Web"]).present?
play = @challenge.st == 1 || @shixun.is_jupyter? || @shixun.vnc || play = @shixun.is_jupyter? || @shixun.vnc ||
@shixun.hide_code? || (@shixun.small_mirror_name & ["Css", "Html", "Web"]).present? @shixun.hide_code? || (@shixun.small_mirror_name & ["Css", "Html", "Web"]).present?
if play if play

@ -6,6 +6,23 @@ class Weapps::CoursesController < Weapps::BaseController
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]
def course_activities
@course = current_course
homework_commons = @course.homework_commons.where(homework_type: ["practice", "normal"]).homework_published
member = @course.course_members.find_by(user_id: current_user.id, is_active: 1)
if (@user_course_identity == Course::STUDENT && member.try(:course_group_id).to_i == 0) || @user_course_identity > Course::STUDENT
homework_commons = homework_commons.unified_setting
elsif @user_course_identity == Course::STUDENT
not_homework_ids = @course.homework_group_settings.none_published.where("course_group_id = #{member.try(:course_group_id)}").pluck(:homework_common_id)
homework_commons = homework_commons.where.not(id: not_homework_ids)
end
homework_ids = homework_commons.blank? ? "(-1)" : "(" + homework_commons.pluck(:id).join(",") + ")"
activities = @course.course_activities.where("course_act_type in ('Course', 'CourseMessage') or
(course_act_type = 'HomeworkCommon' and course_act_id in #{homework_ids})").order("id desc")
@activities = paginate activities.includes(:course_act, user: :user_extension)
end
def create def create
# 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)

@ -1,5 +1,4 @@
class Weapps::ShixunListsController < ApplicationController class Weapps::ShixunListsController < ApplicationController
before_action :require_login
def index def index
results = Weapps::ShixunSearchService.call(search_params, current_laboratory) results = Weapps::ShixunSearchService.call(search_params, current_laboratory)

@ -1,5 +1,5 @@
class Weapps::SubjectsController < Weapps::BaseController class Weapps::SubjectsController < Weapps::BaseController
before_action :require_login before_action :require_login, except: [:index, :show]
before_action :find_subject, except: [:index] before_action :find_subject, except: [:index]
# 首页 # 首页

@ -169,6 +169,7 @@ module ShixunsHelper
source_class_name << source if source.present? source_class_name << source if source.present?
end end
end end
logger.info("####source_class_name: #{source_class_name}")
script = if script.include?("sourceClassName") && script.include?("challengeProgramName") script = if script.include?("sourceClassName") && script.include?("challengeProgramName")
script.gsub(/challengeProgramNames=\(.*\)/,"challengeProgramNames=\(#{challenge_program_name.reject(&:blank?).join(" ")}\)").gsub(/sourceClassNames=\(.*\)/, "sourceClassNames=\(#{source_class_name.reject(&:blank?).join(" ")}\)") script.gsub(/challengeProgramNames=\(.*\)/,"challengeProgramNames=\(#{challenge_program_name.reject(&:blank?).join(" ")}\)").gsub(/sourceClassNames=\(.*\)/, "sourceClassNames=\(#{source_class_name.reject(&:blank?).join(" ")}\)")
else else

@ -70,7 +70,9 @@ class Course < ApplicationRecord
# 课堂动态 # 课堂动态
has_many :course_acts, class_name: 'CourseActivity', as: :course_act, dependent: :destroy has_one :course_act, class_name: 'CourseActivity', as: :course_act, dependent: :destroy
has_many :course_activities
has_many :tidings, as: :container, dependent: :destroy has_many :tidings, as: :container, dependent: :destroy
# 开放课堂 # 开放课堂
@ -300,7 +302,7 @@ class Course < ApplicationRecord
#课程动态公共表记录 #课程动态公共表记录
def act_as_course_activity def act_as_course_activity
self.course_acts << CourseActivity.new(user_id: tea_id, course_id: id) self.course_act << CourseActivity.new(user_id: tea_id, course_id: id)
end end
# 当前老师分班下的所有学生 # 当前老师分班下的所有学生

@ -4,9 +4,26 @@ class CourseActivity < ApplicationRecord
belongs_to :user belongs_to :user
belongs_to :exercise belongs_to :exercise
belongs_to :poll belongs_to :poll
belongs_to :course_message
belongs_to :homework_common
# after_create :add_course_lead # after_create :add_course_lead
def container_name
case course_act_type
when "HomeworkCommon"
course_act&.name
when "Exercise"
course_act&.exercise_name
when "Poll"
course_act&.poll_name
when "Message"
course_act&.subject
else
""
end
end
# 发布新课导语 # 发布新课导语
# 导语要放置在课程创建信息之后 # 导语要放置在课程创建信息之后
def add_course_lead def add_course_lead

@ -2,6 +2,7 @@ class CourseMessage < ApplicationRecord
enum status: { UNHANDLED: 0, PASSED: 1, REJECTED: 2 } enum status: { UNHANDLED: 0, PASSED: 1, REJECTED: 2 }
belongs_to :course belongs_to :course
belongs_to :user belongs_to :user
has_one :course_act, class_name: 'CourseActivity', as: :course_act, dependent: :destroy
scope :find_by_course, ->(course) { where(course_id: course.id) } scope :find_by_course, ->(course) { where(course_id: course.id) }
scope :join_course_requests, -> { where(course_message_type: "JoinCourseRequest") } scope :join_course_requests, -> { where(course_message_type: "JoinCourseRequest") }
@ -9,6 +10,8 @@ class CourseMessage < ApplicationRecord
scope :unhandled_join_course_requests_by_course, ->(course) { find_by_course(course).join_course_requests.unhandled } scope :unhandled_join_course_requests_by_course, ->(course) { find_by_course(course).join_course_requests.unhandled }
after_create :act_as_course_activity
def pass! def pass!
update!(status: :PASSED) update!(status: :PASSED)
send_deal_tiding(1) send_deal_tiding(1)
@ -25,6 +28,11 @@ class CourseMessage < ApplicationRecord
private private
#课程动态公共表记录
def act_as_course_activity
self.course_act << CourseActivity.new(user_id: course_message_id, course_id: course_id)
end
def send_deal_tiding deal_status def send_deal_tiding deal_status
# 发送申请处理结果消息 # 发送申请处理结果消息
Tiding.create!( Tiding.create!(

@ -1,5 +1,7 @@
class Discipline < ApplicationRecord class Discipline < ApplicationRecord
has_many :sub_disciplines, dependent: :destroy default_scope { order(position: :asc) }
has_many :sub_disciplines, -> { order("sub_disciplines.position ASC") }, dependent: :destroy
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"

@ -3,5 +3,5 @@ class ExaminationIntelligentSetting < ApplicationRecord
belongs_to :user belongs_to :user
has_many :examination_type_settings, dependent: :destroy has_many :examination_type_settings, dependent: :destroy
has_many :tag_discipline_containers, as: :container, dependent: :destroy has_many :tag_discipline_containers, as: :container, dependent: :destroy
has_many :item_baskets, dependent: :destroy has_many :item_baskets, -> { order("item_baskets.position ASC") }, dependent: :destroy
end end

@ -1,3 +1,4 @@
class HackCode < ApplicationRecord class HackCode < ApplicationRecord
# 编程题代码相关 # 编程题代码相关
belongs_to :hack
end end

@ -28,7 +28,7 @@ class HomeworkCommon < ApplicationRecord
belongs_to :course_second_category, optional: true belongs_to :course_second_category, optional: true
# 课堂动态 # 课堂动态
has_many :course_acts, class_name: 'CourseActivity', as: :course_act, dependent: :destroy has_one :course_act, class_name: 'CourseActivity', as: :course_act, dependent: :destroy
has_many :tidings, as: :container, dependent: :destroy has_many :tidings, as: :container, dependent: :destroy
# 实训作业的分班查重记录 # 实训作业的分班查重记录
has_many :homework_group_reviews, :dependent => :destroy has_many :homework_group_reviews, :dependent => :destroy

@ -0,0 +1,9 @@
class OpenUsers::Cas < OpenUser
def nickname
extra&.[]('nickname')
end
def en_type
'cas'
end
end

@ -6,20 +6,21 @@ class SalesmanChannel < ApplicationRecord
school.name school.name
end end
def teacher_count def teacher_count(start_time, end_time)
UserExtension.where(school_id: school_id).where.not(identity: 1).count UserExtension.where("identity = 0 and school_id = #{school_id} and created_at between '#{start_time}' and '#{end_time}'").count
# UserExtension.where(school_id: school_id).where(query).count
end end
def student_count def student_count(start_time, end_time)
UserExtension.where(school_id: school_id, identity: 1).count UserExtension.where("identity = 1 and school_id = #{school_id} and created_at between '#{start_time}' and '#{end_time}'").count
end end
def course_count def course_count(start_time, end_time)
Course.where(school_id: school_id).count Course.where("school_id = #{school_id} and courses.created_at between '#{start_time}' and '#{end_time}'").count
end end
def shixuns_count def shixuns_count(start_time, end_time)
ShixunMember.joins("join user_extensions on user_extensions.user_id = shixun_members.user_id") ShixunMember.joins("join user_extensions on user_extensions.user_id = shixun_members.user_id and shixun_members.created_at between '#{start_time}' and '#{end_time}'")
.where(user_extensions: {school_id: school_id}).pluck(:shixun_id).uniq.count .where(user_extensions: {school_id: school_id}).pluck(:shixun_id).uniq.count
end end

@ -1,6 +1,6 @@
class SalesmanCustomer < ApplicationRecord class SalesmanCustomer < ApplicationRecord
belongs_to :salesman, :touch => true, counter_cache: true belongs_to :salesman, :touch => true, counter_cache: true
belongs_to :school belongs_to :school, optional: true
belongs_to :user belongs_to :user
def name def name
@ -8,7 +8,7 @@ class SalesmanCustomer < ApplicationRecord
end end
def school_name def school_name
school.name school&.name
end end
def courses_count def courses_count

@ -1,6 +1,6 @@
class SubDiscipline < ApplicationRecord class SubDiscipline < ApplicationRecord
belongs_to :discipline belongs_to :discipline
has_many :tag_disciplines, dependent: :destroy has_many :tag_disciplines, -> { order("tag_disciplines.position ASC") }, dependent: :destroy
has_many :sub_discipline_containers, dependent: :destroy has_many :sub_discipline_containers, dependent: :destroy
has_one :hack has_one :hack

@ -41,6 +41,7 @@ class Subject < ApplicationRecord
scope :published, lambda{where(status: 1)} scope :published, lambda{where(status: 1)}
scope :unhidden, lambda{where(hidden: 0)} scope :unhidden, lambda{where(hidden: 0)}
scope :publiced, lambda{ where(public: 2) } scope :publiced, lambda{ where(public: 2) }
scope :show_moblied, lambda{ where(show_mobile: true) }
after_create :send_tiding after_create :send_tiding
def send_tiding def send_tiding

@ -51,7 +51,10 @@ class Admins::ShixunSettingsQuery < ApplicationQuery
all_shixuns = all_shixuns.where(task_pass: params[:task_pass]) if params[:task_pass] all_shixuns = all_shixuns.where(task_pass: params[:task_pass]) if params[:task_pass]
all_shixuns = all_shixuns.where(code_hidden: params[:code_hidden]) if params[:code_hidden] all_shixuns = all_shixuns.where(code_hidden: params[:code_hidden]) if params[:code_hidden]
all_shixuns = all_shixuns.where(vip: params[:vip]) if params[:vip] all_shixuns = all_shixuns.where(vip: params[:vip]) if params[:vip]
all_shixuns = all_shixuns.where(is_wechat_support: params[:is_wechat_support]) if params[:is_wechat_support] if params[:no_subject]
shixun_ids = StageShixun.pluck(:shixun_id).uniq
all_shixuns = all_shixuns.published.where.not(id: shixun_ids)
end
custom_sort(all_shixuns, params[:sort_by], params[:sort_direction]) custom_sort(all_shixuns, params[:sort_by], params[:sort_direction])
end end

@ -18,9 +18,9 @@ class Admins::SubjectQuery < ApplicationQuery
status = status =
case params[:status].to_s.strip case params[:status].to_s.strip
when "editing" then {status: 0} when "editing" then {status: 0}
when "processed" then {status: 2, public: 0} when "applying" then {status: 2, public: [0, 1]}
when "pending" then {public: 1} when "pending" then {public: 1}
when "publiced" then {public: 2} when "published" then {public: 2}
end end
subjects = subjects.where(status) if status subjects = subjects.where(status) if status

@ -19,17 +19,20 @@ class OptionalItemQuery < ApplicationQuery
end end
if hacks.present? if hacks.present?
items = ItemBank.where(container_id: hacks.pluck(:id), container_type: "Hack").or(ItemBank.where(id: items.pluck(:id))) items = ItemBank.where(container_id: hacks.where(status: 1).pluck(:id), container_type: "Hack")
.or(ItemBank.where(id: items.pluck(:id)).where("item_type != '6'"))
end end
# 来源
public = source.present? ? source.to_i : 1 public = source.present? ? source.to_i : 1
public = public == 2 ? [0, 1] : public if public == 1
items = items.where(public: public) items = items.where(public: 1)
elsif public == 0
items = items.where(user_id: User.current.id)
end
# 难度 # 难度
difficulty = difficulty ? difficulty.to_i : 1 diff = difficulty ? difficulty.to_i : 1
items = items.where(difficulty: difficulty) items = items.where(difficulty: diff)
items items
end end
end end

@ -8,7 +8,7 @@ class Weapps::SubjectQuery < ApplicationQuery
end end
def call def call
subjects = @current_laboratory.subjects.unhidden.publiced subjects = @current_laboratory.subjects.unhidden.publiced.show_moblied
# 课程体系的过滤 # 课程体系的过滤
if params[:sub_discipline_id].present? if params[:sub_discipline_id].present?

@ -29,14 +29,14 @@ class Admins::ImportDisciplineService < ApplicationService
return unless discipline_name.present? return unless discipline_name.present?
discipline = Discipline.find_by(name: discipline_name) discipline = Discipline.find_by(name: discipline_name)
if discipline.blank? if discipline.blank?
discipline = Discipline.create!(name: discipline_name) discipline = Discipline.create!(name: discipline_name, position: Discipline.all.pluck(:position).max + 1)
count += 1 count += 1
end end
if sub_discipline_name.present? if sub_discipline_name.present?
sub_discipline = SubDiscipline.find_by(name: discipline_name, discipline: discipline) sub_discipline = SubDiscipline.find_by(name: discipline_name, discipline: discipline)
if sub_discipline.blank? if sub_discipline.blank?
SubDiscipline.create!(name: sub_discipline_name, discipline: discipline) SubDiscipline.create!(name: sub_discipline_name, discipline: discipline, position: discipline.sub_disciplines.pluck(:position).max + 1)
count += 1 count += 1
end end
end end

@ -17,6 +17,7 @@ class CreateBindUserService < ApplicationService
bind_user = User.try_to_login(params[:username], params[:password]) bind_user = User.try_to_login(params[:username], params[:password])
raise Error, '用户名或者密码错误' if bind_user.blank? raise Error, '用户名或者密码错误' if bind_user.blank?
raise Error, '用户名或者密码错误' unless bind_user.check_password?(params[:password].to_s)
raise Error, '该账号已被绑定,请更换其他账号进行绑定' if bind_user.bind_open_user?(params[:type].to_s) raise Error, '该账号已被绑定,请更换其他账号进行绑定' if bind_user.bind_open_user?(params[:type].to_s)
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do

@ -133,8 +133,10 @@ class HomeworksService
# 计算实训作品学生的效率分 # 计算实训作品学生的效率分
def update_student_eff_score homework def update_student_eff_score homework
if homework.work_efficiency && homework.max_efficiency != 0 if homework.work_efficiency && homework.max_efficiency != 0
max_efficiency = homework.student_works.where("compelete_status != 0").pluck(:efficiency).max
homework.update_column("max_efficiency", max_efficiency)
homework.student_works.where("compelete_status != 0").each do |student_work| homework.student_works.where("compelete_status != 0").each do |student_work|
eff_score = student_work.efficiency / homework.max_efficiency * homework.eff_score eff_score = student_work.efficiency / max_efficiency * homework.eff_score
student_work.eff_score = format("%.2f", eff_score) student_work.eff_score = format("%.2f", eff_score)
student_work.late_penalty = student_work.work_status == 1 ? 0 : homework.late_penalty student_work.late_penalty = student_work.work_status == 1 ? 0 : homework.late_penalty
unless student_work.ultimate_score unless student_work.ultimate_score
@ -333,7 +335,10 @@ class HomeworksService
work.compelete_status = myshixun_endtime < setting_time.end_time ? 2 : 3 work.compelete_status = myshixun_endtime < setting_time.end_time ? 2 : 3
# 如果作业的最大效率值有变更则更新所有作品的效率分 # 如果作业的最大效率值有变更则更新所有作品的效率分
homework.update_column("max_efficiency", work.efficiency) if homework.work_efficiency && homework.max_efficiency < work.efficiency if homework.work_efficiency && homework.max_efficiency < work.efficiency
homework.max_efficiency = work.efficiency
homework.save(validate: false)
end
else else
work.compelete_status = 1 # 未通关 work.compelete_status = 1 # 未通关
end end

@ -0,0 +1,31 @@
class Oauth::CreateORFindCasUserService < ApplicationService
def initialize(user, params)
@user = user
@params = params
end
def call
return [@user, false] if @user
open_user = OpenUsers::Cas.find_or_initialize_by(uid: @params['user']) do |u|
u.extra = @params
end
return [open_user.user, false] if open_user.persisted?
@user = User.new(login: User.generate_login('C'), type: 'User', status: User::STATUS_ACTIVE, nickname: @params['comsys_name'], lastname: @params['comsys_name'])
ActiveRecord::Base.transaction do
@user.save!
@user.create_user_extension!
open_user.user = @user
open_user.save!
Rails.cache.write(open_user.can_bind_cache_key, 1, expires_in: 1.hours)
end
[@user, true]
end
end

@ -18,18 +18,22 @@ class Oauth::CreateOrFindWechatAccountService < ApplicationService
# 存在该用户 # 存在该用户
open_user = OpenUsers::Wechat.find_by(uid: result['unionid']) open_user = OpenUsers::Wechat.find_by(uid: result['unionid'])
return [open_user.user, new_user] if open_user.present? return [open_user.user, new_user] if open_user.present? && open_user.user.present?
if user.blank? || !user.logged? if user.blank? || !user.logged?
new_user = true new_user = true
# 新用户 # 新用户
login = User.generate_login('w') # login = User.generate_login('w')
# result['nickname'] = regix_emoji(result['nickname']) # result['nickname'] = regix_emoji(result['nickname'])
@user = User.new(login: login, type: 'User', status: User::STATUS_ACTIVE) # @user = User.new(login: login, type: 'User', status: User::STATUS_ACTIVE)
#@user = User.new(login: login, nickname: result['nickname'], type: 'User', status: User::STATUS_ACTIVE) # @user = User.new(login: login, nickname: result['nickname'], type: 'User', status: User::STATUS_ACTIVE)
set_session_openid(result['openid'])
set_session_unionid(result['unionid'])
else
OpenUsers::Wechat.create!(user: user, uid: result['unionid'])
end end
=begin
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
if new_user if new_user
user.save! user.save!
@ -46,6 +50,7 @@ class Oauth::CreateOrFindWechatAccountService < ApplicationService
Rails.cache.write(new_open_user.can_bind_cache_key, 1, expires_in: 1.hours) if new_user # 方便后面进行账号绑定 Rails.cache.write(new_open_user.can_bind_cache_key, 1, expires_in: 1.hours) if new_user # 方便后面进行账号绑定
end end
=end
[user, new_user] [user, new_user]
rescue WechatOauth::Error => ex rescue WechatOauth::Error => ex

@ -73,9 +73,11 @@ class UpdateHomeworkPublishSettingService < ApplicationService
# 作业在"提交中"状态时 # 作业在"提交中"状态时
else else
if homework.end_time > Time.now && homework.unified_setting # 实训作业截止时间已过也可修改截止时间,其他作业暂不支持修改
if (homework.homework_type == "practice" || homework.end_time > Time.now) && homework.unified_setting
tip_exception("截止时间不能为空") if params[:end_time].blank? tip_exception("截止时间不能为空") if params[:end_time].blank?
tip_exception("截止时间不能早于当前时间") if params[:end_time].to_time <= Time.now tip_exception("截止时间必须晚于发布时间") if params[:end_time].to_time <= homework.publish_time
# tip_exception("截止时间不能早于当前时间") if params[:end_time].to_time <= Time.now
tip_exception("截止时间不能晚于课堂结束时间(#{course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")}") if tip_exception("截止时间不能晚于课堂结束时间(#{course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")}") if
course.end_date.present? && params[:end_time].to_time > course.end_date.end_of_day course.end_date.present? && params[:end_time].to_time > course.end_date.end_of_day
@ -93,19 +95,29 @@ class UpdateHomeworkPublishSettingService < ApplicationService
# 如果该发布规则 没有已发布的分班则需判断发布时间 # 如果该发布规则 没有已发布的分班则需判断发布时间
tip_exception("发布时间不能早于等于当前时间") if setting[:publish_time].to_time <= Time.now && group_settings.group_published.count == 0 tip_exception("发布时间不能早于等于当前时间") if setting[:publish_time].to_time <= Time.now && group_settings.group_published.count == 0
tip_exception("截止时间不能早于等于当前时间") if setting[:end_time].to_time <= Time.now && group_settings.none_end.count > 0 # tip_exception("截止时间不能早于等于当前时间") if setting[:end_time].to_time <= Time.now && group_settings.none_end.count > 0
tip_exception("截止时间不能早于发布时间") if setting[:publish_time].to_time > setting[:end_time].to_time tip_exception("截止时间不能早于发布时间") if setting[:publish_time].to_time > setting[:end_time].to_time
tip_exception("截止时间不能晚于课堂结束时间(#{course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")}") if tip_exception("截止时间不能晚于课堂结束时间(#{course.end_date.end_of_day.strftime("%Y-%m-%d %H:%M")}") if
course.end_date.present? && setting[:end_time].to_time > course.end_date.end_of_day course.end_date.present? && setting[:end_time].to_time > course.end_date.end_of_day
group_settings.none_published.update_all(publish_time: setting[:publish_time]) group_settings.none_published.update_all(publish_time: setting[:publish_time])
group_settings.none_end.update_all(end_time: setting[:end_time]) # 实训作业截止时间已过也可修改截止时间,其他作业暂不支持修改
if homework.homework_type == "practice"
group_settings.update_all(end_time: setting[:end_time])
else
group_settings.none_end.update_all(end_time: setting[:end_time])
end
end end
homework.end_time = homework.max_group_end_time homework.end_time = homework.max_group_end_time
end end
end end
if homework.end_time > Time.now && homework.homework_detail_manual.try(:comment_status) > 1
homework.homework_detail_manual.update_attributes!(comment_status: 1)
end
homework.save! homework.save!
UpdateShixunWorkScoreJob.perform_later(homework.id)
HomeworkCommonPushNotifyJob.perform_later(homework.id, publish_group_ids) if send_tiding HomeworkCommonPushNotifyJob.perform_later(homework.id, publish_group_ids) if send_tiding
end end

@ -50,7 +50,7 @@ class Users::UpdateAccountService < ApplicationService
end end
if first_full_reward if first_full_reward
RewardGradeService.call(user, container_id: user.id, container_type: 'Account', score: 500) # RewardGradeService.call(user, container_id: user.id, container_type: 'Account', score: 500)
if user.user_extension.teacher? if user.user_extension.teacher?
join_course(user.id,1309, 2) join_course(user.id,1309, 2)
# sms_notify_admin(user.lastname) # sms_notify_admin(user.lastname)

@ -3,7 +3,7 @@ class Videos::DispatchCallbackService < ApplicationService
def initialize(params) def initialize(params)
@video = Video.find_by(uuid: params[:VideoId]) @video = Video.find_by(uuid: params[:VideoId])
@params = params @params = params``
end end
def call def call

@ -4,17 +4,33 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="Content-type" content="text/html; charset=utf-8" /> <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.10.0-rc.1/katex.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.11.1/katex.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.11.1/katex.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.11.1/katex.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.11.1/contrib/auto-render.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.11.1/contrib/auto-render.min.js"></script>
<script> <script>
document.addEventListener("DOMContentLoaded", function() { document.addEventListener("DOMContentLoaded", function() {
renderMathInElement(document.getElementById('markdown_content'), { renderMathInElement(document.getElementById('markdown_content'), {
displayMode: true,
delimiters: [ delimiters: [
{left: "$$", right: "$$", display: true}, {left: "$$", right: "$$", display: true},
{left: "$", right: "$", display: false} {left: "$", right: "$", display: false}
] ]
}); });
function fix_frac_line(){
var win = window;
var frac_lines = document.getElementsByClassName("frac-line");
for (var i = 0; i < frac_lines.length; i++) {
var frac = frac_lines[i];
if (win.getComputedStyle) {
style = win.getComputedStyle(frac, '');
if (style['border-bottom-width'] == '0px') {
frac.style['border-bottom-width'] = '1px';
}
}
}
};
fix_frac_line();
}) })
</script> </script>
</head> </head>

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

@ -1,3 +1,4 @@
<% max_position = @disciplines.pluck(:position).max %>
<table class="table table-hover text-center discipline-list-table"> <table class="table table-hover text-center discipline-list-table">
<thead class="thead-light"> <thead class="thead-light">
<tr> <tr>
@ -11,9 +12,9 @@
</thead> </thead>
<tbody> <tbody>
<% if @disciplines.present? %> <% if @disciplines.present? %>
<% @disciplines.each_with_index do |discipline, index| %> <% @disciplines.each do |discipline| %>
<tr class="discipline-item discipline-item-<%= discipline.id %>"> <tr class="discipline-item discipline-item-<%= discipline.id %>">
<td><%= index + 1 %></td> <td><%= discipline.position %></td>
<td class="text-left"> <td class="text-left">
<span><%= link_to discipline.name, admins_sub_disciplines_path(discipline_id: discipline), :title => discipline.name %></span> <span><%= link_to discipline.name, admins_sub_disciplines_path(discipline_id: discipline), :title => discipline.name %></span>
</td> </td>
@ -21,6 +22,9 @@
<td><%= check_box_tag :shixun,!discipline.shixun,discipline.shixun,remote:true,data:{id:discipline.id},class:"discipline-source-form" %></td> <td><%= check_box_tag :shixun,!discipline.shixun,discipline.shixun,remote:true,data:{id:discipline.id},class:"discipline-source-form" %></td>
<td><%= check_box_tag :question,!discipline.question,discipline.question,remote:true,data:{id:discipline.id},class:"discipline-source-form" %></td> <td><%= check_box_tag :question,!discipline.question,discipline.question,remote:true,data:{id:discipline.id},class:"discipline-source-form" %></td>
<td> <td>
<%= javascript_void_link('上移', class: 'move-action', data: { id: discipline.id, opr: "up" }, style: discipline.position == 1 ? 'display:none' : '') %>
<%= javascript_void_link('下移', class: 'move-action', data: { id: discipline.id, opr: "down" }, style: discipline.position == max_position ? 'display:none' : '') %>
<%= link_to '编辑', edit_admins_discipline_path(discipline), remote: true, class: 'action' %> <%= link_to '编辑', edit_admins_discipline_path(discipline), remote: true, class: 'action' %>
<%= delete_link '删除', admins_discipline_path(discipline, element: ".discipline-item-#{discipline.id}"), class: 'delete-discipline-action' %> <%= delete_link '删除', admins_discipline_path(discipline, element: ".discipline-item-#{discipline.id}"), class: 'delete-discipline-action' %>
</td> </td>

@ -1,4 +1,9 @@
<% is_processed = params[:status].to_s != 'pending' %> <% is_processed = params[:status].to_s != 'pending' %>
<link rel="stylesheet" href="/quill/quill.snow.css"/>
<div id="editor" style="display: none">
</div>
<script src="/quill/quill.min.js"></script>
<table class="table table-hover text-center professional-authentication-list-table"> <table class="table table-hover text-center professional-authentication-list-table">
<thead class="thead-light"> <thead class="thead-light">
<tr> <tr>
@ -30,11 +35,13 @@
</td> </td>
<td><%= user.real_name %></td> <td><%= user.real_name %></td>
<td><%= raw [user.school_name.presence, user.department_name.presence].compact.join('<br/>') %></td> <td><%= raw [user.school_name.presence, user.department_name.presence].compact.join('<br/>') %></td>
<td> <td class="text-left">
<% if item.item_type == "PROGRAM" %> <% if item.item_type == "PROGRAM" %>
<%= link_to item.name, "/problems/#{item.container&.identifier}/edit", target: "_blank" %> <%= link_to item.name, "/problems/#{item.container&.identifier}/edit", id: "item_name_#{index}", class: "d-inline-block text-truncate",
style: "max-width: 280px", target: "_blank", data: { toggle: 'tooltip', title: "#{item.name}"} %>
<% else %> <% else %>
<%= link_to item.name, admins_item_authentication_path(apply), remote: true %> <%= link_to item.name, admins_item_authentication_path(apply), remote: true, id: "item_name_#{index}", class: "d-inline-block text-truncate",
style: "max-width: 280px", data: { toggle: 'tooltip', title: "#{item.name}"} %>
<% end %> <% end %>
</td> </td>
<td><%= item.type_string %></td> <td><%= item.type_string %></td>
@ -57,4 +64,18 @@
</tbody> </tbody>
</table> </table>
<%= render partial: 'admins/shared/paginate', locals: { objects: applies } %> <%= render partial: 'admins/shared/paginate', locals: { objects: applies } %>
<script>
var quill = new Quill('#editor', {
theme: 'snow'
});
var content = "";
<% applies.each_with_index do |apply, index| %>
<% item = ItemBank.find apply.container_id %>
content = JSON.parse(<%= item.name %>);
quill.setContents(content);
$("#item_name_<%= index %>").html(quill.container.firstChild.innerHTML);
<% end %>
</script>

@ -2,12 +2,33 @@
<% add_admin_breadcrumb("#{@salesman.name}的渠道", admins_salesmans_path) %> <% add_admin_breadcrumb("#{@salesman.name}的渠道", admins_salesmans_path) %>
<% end %> <% end %>
<div class="box search-form-container salesman-channel-list-form rig"> <% define_admin_breadcrumbs do %>
<div class="flex-1"> <% add_admin_breadcrumb('数据变化报表', admins_school_statistics_path) %>
<%= javascript_void_link '新增渠道', class: 'btn btn-primary', data: {salesman_id: @salesman.id, toggle: 'modal', target: '.admin-add-salesman-channel-user-modal' } %> <% end %>
<div class="box search-form-container saleman-channel-list-form">
<form class="form-inline search-form d-flex" data-search-form-url="<%= admins_salesman_channels_path(salesman_id: @salesman.id) %>">
<div class="time-select">
<div class="form-group grow-date-container">
<div class="input-group input-daterange grow-date-input-daterange">
<%= text_field_tag :start_date, params[:start_date], class: 'form-control start-date mx-0', placeholder: '开始时间' %>
<div class="input-group-prepend"><span class="input-group-text">到</span></div>
<%= text_field_tag :end_date, params[:end_date], class: 'form-control end-date mx-0', placeholder: '结束时间' %>
</div>
</div>
</div>
<%= text_field_tag :keyword, params[:keyword], placeholder: 'ID/单位名称检索', class: 'form-control mx-3 search-input' %>
<%= javascript_void_link '搜索', class: 'btn btn-primary search-btn', target: '' %>
<input type="reset" class="btn btn-secondary clear-btn ml-3" value="清空"/>
</form>
<div class="flex-12">
<%= javascript_void_link '新增渠道', class: 'btn btn-primary', data: {toggle: 'modal', target: '.admin-add-salesman-channel-user-modal' } %>
</div> </div>
</div> </div>
<div class="box admin-list-container salesman-channel-list-container"> <div class="box admin-list-container salesman-channel-list-container">
<%= render(partial: 'admins/salesman_channels/shared/list') %> <%= render(partial: 'admins/salesman_channels/shared/list') %>
</div> </div>

@ -0,0 +1 @@
$(".salesman-channel-list-container").html("<%= j(render partial: 'admins/salesman_channels/shared/list') %>")

@ -8,13 +8,12 @@
</button> </button>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<form class="admin-add-salesman-user-form"> <form class="admin-add-salesman-user-form" data-url="<%= batch_add_admins_salesman_channels_path(salesman_id: @salesman.id) %>">
<%= hidden_field_tag(:salesman_id, nil) %>
<div class="form-group d-flex"> <div class="form-group d-flex">
<label class="col-form-label">单位:</label> <label class="col-form-label">单位:</label>
<div class="d-flex flex-column-reverse w-75"> <div class="d-flex flex-column-reverse w-75">
<select id="user_ids" name="user_ids" class="form-control salesman-channel-user-select"></select> <select id="school_ids" name="school_ids[]" class="form-control salesman-channel-user-select"></select>
</div> </div>
</div> </div>

@ -19,16 +19,16 @@
<span><%= channel.school_name %></span> <span><%= channel.school_name %></span>
</td> </td>
<td class="text-left"> <td class="text-left">
<span><%= channel.teacher_count %></span> <span><%= channel.teacher_count(@start_time, @end_time) %></span>
</td> </td>
<td class="text-left"> <td class="text-left">
<span><%= channel.student_count %></span> <span><%= channel.student_count(@start_time, @end_time) %></span>
</td> </td>
<td> <td>
<%= channel.course_count %> <%= channel.course_count(@start_time, @end_time) %>
</td> </td>
<td> <td>
<%= channel.shixuns_count %> <%= channel.shixuns_count(@start_time, @end_time) %>
</td> </td>
<td> <td>
<%= delete_link '删除', admins_salesman_channel_path(channel, salesman_id: channel.salesman_id, element: ".salesman-channel-item-#{channel.id}"), class: 'delete-salesman-action' %> <%= delete_link '删除', admins_salesman_channel_path(channel, salesman_id: channel.salesman_id, element: ".salesman-channel-item-#{channel.id}"), class: 'delete-salesman-action' %>

@ -0,0 +1 @@
$(".salesman-customer-list-container").html("<%= j(render partial: 'admins/salesman_customers/shared/list') %>")

@ -2,9 +2,9 @@
<thead class="thead-light"> <thead class="thead-light">
<tr> <tr>
<th width="6%">序号</th> <th width="6%">序号</th>
<th width="20%" class="text-left">名称</th> <th width="20%" class="text-left">业务员</th>
<th width="30%" class="text-left">客户(点击数字客户列表)</th> <th width="30%" class="text-left">重点跟踪客户(点击数字客户列表)</th>
<th width="30%" class="text-left">渠道数(点击数字渠道列表)</th> <th width="30%" class="text-left">重点跟踪院校(点击数字渠道列表)</th>
<th width="14%">操作</th> <th width="14%">操作</th>
</tr> </tr>
</thead> </thead>

@ -88,14 +88,14 @@
</li> </li>
<li> <li>
<%= sidebar_item_group('#running_data', '运营数据', icon: 'bar-chart') do %> <%= sidebar_item_group('#running-data', '运营数据', icon: 'bar-chart') do %>
<li><%= sidebar_item(admins_salesmans_path, '销售数据列表', icon: 'columns', controller: 'admins-salesman') %></li> <li><%= sidebar_item(admins_salesmans_path, '销售数据列表', icon: 'columns', controller: 'admins-salesmans') %></li>
<% end %> <% end %>
</li> </li>
<li> <li>
<%= sidebar_item_group('#other-submenu', '其他', icon: 'list-alt') do %> <%= sidebar_item_group('#other-submenu', '其他', icon: 'list-alt') do %>
<li><%= sidebar_item(admins_repertoires_path, '技术体系', icon: 'sitemap', controller: 'admins-repertoire') %></li> <li><%= sidebar_item(admins_repertoires_path, '技术体系', icon: 'sitemap', controller: 'admins-repertoires') %></li>
<% end %> <% end %>
</li> </li>

@ -73,8 +73,8 @@
</div> </div>
<div class="mr-5"> <div class="mr-5">
<label for="is_wechat_support"> <label for="is_wechat_support">
<%= check_box_tag :is_wechat_support, !@sort_json[:is_wechat_support],@sort_json[:is_wechat_support], class:"shixun-settings-select" %> <%= check_box_tag :no_subject, !@sort_json[:no_subject],@sort_json[:no_subject], class:"shixun-settings-select" %>
<span class="only_view">只看小程序可用</span> <span class="only_view">已发布没关联课程</span>
</label> </label>
</div> </div>

@ -0,0 +1,5 @@
<% if @message.present? %>
$.notify({ message: "<%= @message %>" });
<% else %>
$(".sub-discipline-list-container").html("<%= j(render :partial => 'admins/sub_disciplines/shared/list') %>");
<% end %>

@ -1,3 +1,4 @@
<% max_position = @sub_disciplines.pluck(:position).max %>
<table class="table table-hover text-center sub-discipline-list-table"> <table class="table table-hover text-center sub-discipline-list-table">
<thead class="thead-light"> <thead class="thead-light">
<tr> <tr>
@ -11,9 +12,9 @@
</thead> </thead>
<tbody> <tbody>
<% if @sub_disciplines.present? %> <% if @sub_disciplines.present? %>
<% @sub_disciplines.each_with_index do |sub, index| %> <% @sub_disciplines.each do |sub| %>
<tr class="sub-discipline-item sub-discipline-item-<%= sub.id %>"> <tr class="sub-discipline-item sub-discipline-item-<%= sub.id %>">
<td><%= index + 1 %></td> <td><%= sub.position %></td>
<td class="text-left"> <td class="text-left">
<span><%= link_to sub.name, admins_tag_disciplines_path(sub_discipline_id: sub), :title => sub.name %></span> <span><%= link_to sub.name, admins_tag_disciplines_path(sub_discipline_id: sub), :title => sub.name %></span>
</td> </td>
@ -21,6 +22,9 @@
<td><%= check_box_tag :shixun,!sub.shixun,sub.shixun,disabled:!sub.discipline&.shixun,remote:true,data:{id:sub.id},class:"sub-discipline-source-form" %></td> <td><%= check_box_tag :shixun,!sub.shixun,sub.shixun,disabled:!sub.discipline&.shixun,remote:true,data:{id:sub.id},class:"sub-discipline-source-form" %></td>
<td><%= check_box_tag :question,!sub.question,sub.question,disabled:!sub.discipline&.question,remote:true,data:{id:sub.id},class:"sub-discipline-source-form" %></td> <td><%= check_box_tag :question,!sub.question,sub.question,disabled:!sub.discipline&.question,remote:true,data:{id:sub.id},class:"sub-discipline-source-form" %></td>
<td> <td>
<%= javascript_void_link('上移', class: 'move-action', data: { id: sub.id, opr: "up" }, style: sub.position == 1 ? 'display:none' : '') %>
<%= javascript_void_link('下移', class: 'move-action', data: { id: sub.id, opr: "down" }, style: sub.position == max_position ? 'display:none' : '') %>
<%= link_to '编辑', edit_admins_sub_discipline_path(sub), remote: true, class: 'action' %> <%= link_to '编辑', edit_admins_sub_discipline_path(sub), remote: true, class: 'action' %>
<%= delete_link '删除', admins_sub_discipline_path(sub, element: ".sub-discipline-item-#{sub.id}"), class: 'delete-sub-discipline-action' %> <%= delete_link '删除', admins_sub_discipline_path(sub, element: ".sub-discipline-item-#{sub.id}"), class: 'delete-sub-discipline-action' %>
</td> </td>

@ -6,7 +6,7 @@
<%= form_tag(admins_subject_settings_path, method: :get, class: 'form-inline search-form flex-1', remote: true) do %> <%= form_tag(admins_subject_settings_path, method: :get, class: 'form-inline search-form flex-1', remote: true) do %>
<div class="form-group mr-1"> <div class="form-group mr-1">
<label for="status">状态:</label> <label for="status">状态:</label>
<% status_options = [['全部', ''], ['编辑中', 'pending'], ['审核中', 'applying'], ['已发布', 'published']] %> <% status_options = [['全部', ''], ['编辑中', 'pending'], ['审核中', 'applying'], ['已公开', 'published']] %>
<%= select_tag(:status, options_for_select(status_options), class: 'form-control') %> <%= select_tag(:status, options_for_select(status_options), class: 'form-control') %>
</div> </div>

@ -1,14 +1,14 @@
<table class="table table-hover text-center subject-list-table"> <table class="table table-hover text-center subject-list-table">
<thead class="thead-light"> <thead class="thead-light">
<tr> <tr>
<th width="4%">序号</th> <th width="5%">序号</th>
<th width="25%" class="text-left">名称</th> <th width="23%" class="text-left">名称</th>
<th width="12%">技术体系</th> <th width="10%">老版技术体系</th>
<th width="10%">等级体系</th> <th width="10%">状态</th>
<th width="25%">课程体系</th> <th width="25%">课程体系</th>
<th width="10%">封面</th> <th width="10%">封面</th>
<th width="8%">开课人数</th> <th width="5%">开课人数</th>
<th width="6%">操作</th> <th width="12%">操作</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>

@ -5,7 +5,7 @@
<span class="badge badge-pill badge-info excellent-badge" style="<%= subject.excellent? ? '' : 'display:none' %>">金课</span> <span class="badge badge-pill badge-info excellent-badge" style="<%= subject.excellent? ? '' : 'display:none' %>">金课</span>
</td> </td>
<td><%= display_text subject.repertoire&.name %></td> <td><%= display_text subject.repertoire&.name %></td>
<td><%= display_text subject.subject_level_system&.name %></td> <td><%= display_text subject.public == 2 ? "已公开" : ((subject.public == 1 && subject.status == 2) ? "审核中" : "未发布") %></td>
<td> <td>
<%= select_tag(:sub_disciplines, options_for_select(@sub_disciplines, subject.sub_disciplines.pluck(:id)),multiple:true,class:"form-control subject-setting-form",data:{id:subject.id},id:"tags-chosen-#{subject.id}") %> <%= select_tag(:sub_disciplines, options_for_select(@sub_disciplines, subject.sub_disciplines.pluck(:id)),multiple:true,class:"form-control subject-setting-form",data:{id:subject.id},id:"tags-chosen-#{subject.id}") %>
</td> </td>
@ -16,6 +16,8 @@
</td> </td>
<td><%= subject.student_count %></td> <td><%= subject.student_count %></td>
<td class="action-container"> <td class="action-container">
<%= check_box_tag :show_mobile, !subject.show_mobile, subject.show_mobile, remote: true,
data: {id: subject.id, toggle: "tooltip", placement: "top"}, class: "subject-mobile-form mr10", title: "小程序端显示" %>
<%= link_to('编辑', edit_admins_subject_path(subject), remote: true, class: 'edit-action') %> <%= link_to('编辑', edit_admins_subject_path(subject), remote: true, class: 'edit-action') %>
</td> </td>
@ -24,4 +26,22 @@
multiple: true, multiple: true,
maximumSelectionLength: 3, maximumSelectionLength: 3,
placeholder: '请选择课程体系'}); placeholder: '请选择课程体系'});
$(".action-container").on("change", '.subject-mobile-form', function () {
var s_id = $(this).attr("data-id");
var s_value = $(this).val();
var s_name = $(this).attr("name");
var json = {};
var s_index = $(this).parent("td").siblings(".shixun-line-no").text();
json[s_name] = s_value;
json["page_no"] = s_index;
$.ajax({
url: "/admins/subject_settings/update_mobile_show?subject_id=" + s_id,
type: "POST",
dataType:'script',
data: json
});
});
</script> </script>

@ -0,0 +1,5 @@
<% if @message.present? %>
$.notify({ message: "<%= @message %>" });
<% else %>
$(".tag-discipline-list-container").html("<%= j(render :partial => 'admins/tag_disciplines/shared/list') %>");
<% end %>

@ -1,3 +1,4 @@
<% max_position = @tag_disciplines.pluck(:position).max %>
<table class="table table-hover text-center tag-discipline-list-table"> <table class="table table-hover text-center tag-discipline-list-table">
<thead class="thead-light"> <thead class="thead-light">
<tr> <tr>
@ -12,9 +13,9 @@
</thead> </thead>
<tbody> <tbody>
<% if @tag_disciplines.present? %> <% if @tag_disciplines.present? %>
<% @tag_disciplines.each_with_index do |tag, index| %> <% @tag_disciplines.each do |tag| %>
<tr class="tag-discipline-item tag-discipline-item-<%= tag.id %>"> <tr class="tag-discipline-item tag-discipline-item-<%= tag.id %>">
<td><%= index + 1 %></td> <td><%= tag.position %></td>
<td class="text-left"><%= tag.name %></td> <td class="text-left"><%= tag.name %></td>
<td> <td>
<% if tag.user.present? %> <% if tag.user.present? %>
@ -36,6 +37,9 @@
<%= check_box_tag :question,!tag.question,tag.question,disabled:disabled,remote:true,data:{id:tag.id},class:"tag-discipline-source-form" %> <%= check_box_tag :question,!tag.question,tag.question,disabled:disabled,remote:true,data:{id:tag.id},class:"tag-discipline-source-form" %>
</td> </td>
<td> <td>
<%= javascript_void_link('上移', class: 'move-action', data: { id: tag.id, opr: "up" }, style: tag.position == 1 ? 'display:none' : '') %>
<%= javascript_void_link('下移', class: 'move-action', data: { id: tag.id, opr: "down" }, style: tag.position == max_position ? 'display:none' : '') %>
<%= link_to '编辑', edit_admins_tag_discipline_path(tag), remote: true, class: 'action' %> <%= link_to '编辑', edit_admins_tag_discipline_path(tag), remote: true, class: 'action' %>
<%= delete_link '删除', admins_tag_discipline_path(tag, element: ".tag-discipline-item-#{tag.id}"), class: 'delete-tag-discipline-action' %> <%= delete_link '删除', admins_tag_discipline_path(tag, element: ".tag-discipline-item-#{tag.id}"), class: 'delete-tag-discipline-action' %>
</td> </td>

@ -0,0 +1,12 @@
json.activities @activities do |activity|
json.(activity, :course_act_id, :course_act_type)
json.author do
user = activity.user
json.name user.real_name
json.login user.login
json.img url_to_avatar(user)
end
json.created_at activity.created_at.strftime('%m-%d %H:%M:')
json.container_name activity.container_name
json.container_type activity.course_act_type == "HomeworkCommon" ? activity.course_act&.homework_type : ""
end

@ -29,6 +29,10 @@ module Educoderplus
# job # job
config.active_job.queue_adapter = :sidekiq config.active_job.queue_adapter = :sidekiq
config.middleware.use OmniAuth::Builder do
provider :cas, url: 'https://urp.tfswufe.edu.cn/cas'
end
config.middleware.insert_before 0, Rack::Cors do config.middleware.insert_before 0, Rack::Cors do
allow do allow do
origins '*' origins '*'

@ -8,8 +8,8 @@ Rails.application.routes.draw do
get 'attachments/download/:id/:filename', to: 'attachments#show' get 'attachments/download/:id/:filename', to: 'attachments#show'
get 'auth/qq/callback', to: 'oauth/qq#create' get 'auth/qq/callback', to: 'oauth/qq#create'
get 'auth/failure', to: 'oauth/base#auth_failure' get 'auth/failure', to: 'oauth/base#auth_failure'
get 'auth/cas/callback', to: 'oauth/cas#create'
resources :edu_settings resources :edu_settings
scope '/api' do scope '/api' do
@ -26,7 +26,7 @@ Rails.application.routes.draw do
put 'commons/unhidden', to: 'commons#unhidden' put 'commons/unhidden', to: 'commons#unhidden'
delete 'commons/delete', to: 'commons#delete' delete 'commons/delete', to: 'commons#delete'
resources :jupyters do resources :jupyters do
collection do collection do
get :save_with_tpi get :save_with_tpi
get :save_with_tpm get :save_with_tpm
@ -42,7 +42,7 @@ Rails.application.routes.draw do
post :import_with_tpm post :import_with_tpm
end end
end end
resources :memos do resources :memos do
member do member do
post :sticky_or_cancel post :sticky_or_cancel
@ -1040,12 +1040,13 @@ Rails.application.routes.draw do
member do member do
get :shixun_homework_category get :shixun_homework_category
get :teachers get :teachers
delete :delete_course_teachers
post :change_member_roles
get :students get :students
delete :delete_course_students
get :course_groups get :course_groups
get :basic_info get :basic_info
get :course_activities
post :change_member_roles
delete :delete_course_teachers
delete :delete_course_students
end end
collection do collection do
@ -1328,7 +1329,9 @@ Rails.application.routes.draw do
post :drag, on: :collection post :drag, on: :collection
end end
resources :subject_settings, only: [:index, :update] resources :subject_settings, only: [:index, :update] do
post :update_mobile_show, on: :collection
end
resources :subjects, only: [:index, :edit, :update, :destroy] do resources :subjects, only: [:index, :edit, :update, :destroy] do
member do member do
@ -1353,9 +1356,15 @@ Rails.application.routes.draw do
resources :projects, only: [:index, :destroy] resources :projects, only: [:index, :destroy]
resources :disciplines, only: [:index, :create, :edit, :update, :destroy] resources :disciplines, only: [:index, :create, :edit, :update, :destroy] do
resources :sub_disciplines, only: [:index, :create, :edit, :update, :destroy] post :adjust_position, on: :member
resources :tag_disciplines, only: [:index, :create, :edit, :update, :destroy] end
resources :sub_disciplines, only: [:index, :create, :edit, :update, :destroy] do
post :adjust_position, on: :member
end
resources :tag_disciplines, only: [:index, :create, :edit, :update, :destroy] do
post :adjust_position, on: :member
end
resources :repertoires, only: [:index, :create, :edit, :update, :destroy] resources :repertoires, only: [:index, :create, :edit, :update, :destroy]
resources :sub_repertoires, only: [:index, :create, :edit, :update, :destroy] resources :sub_repertoires, only: [:index, :create, :edit, :update, :destroy]

@ -0,0 +1,5 @@
class AddShowMoblieToSubjects < ActiveRecord::Migration[5.2]
def change
add_column :subjects, :show_mobile, :boolean, :default => false
end
end

@ -0,0 +1,8 @@
class SyncSubjectdsMobile < ActiveRecord::Migration[5.2]
def change
SubDisciplineContainer.find_each do |sc|
Subject.find(sc.container_id).update_column(:show_mobile, true)
end
end
end

@ -0,0 +1,7 @@
class AddPositionToDiscipline < ActiveRecord::Migration[5.2]
def change
add_column :disciplines, :position, :integer, default: 0
add_column :sub_disciplines, :position, :integer, default: 0
add_column :tag_disciplines, :position, :integer, default: 0
end
end

@ -0,0 +1,15 @@
class MigrateDisciplinePosition < ActiveRecord::Migration[5.2]
def change
Discipline.all.each_with_index do |discipline, i|
discipline.update_column("position", i + 1)
discipline.sub_disciplines.each_with_index do |sub, j|
sub.update_column("position", j + 1)
sub.tag_disciplines.each_with_index do |tag, k|
tag.update_column("position", k + 1)
end
end
end
end
end

@ -0,0 +1,10 @@
class AddUniqIndexToSalesmanChannel < ActiveRecord::Migration[5.2]
def change
sql = %Q(delete from salesman_channels where (salesman_id, school_id) in
(select * from (select salesman_id, school_id from salesman_channels group by salesman_id, school_id having count(*) > 1) a)
and id not in (select * from (select min(id) from salesman_channels group by salesman_id, school_id having count(*) > 1 order by id) b))
ActiveRecord::Base.connection.execute sql
add_index :salesman_channels, [:salesman_id, :school_id], unique: true
end
end

@ -0,0 +1,10 @@
class AddUniqIndexToSalesmanCustomer < ActiveRecord::Migration[5.2]
def change
sql = %Q(delete from salesman_customers where (salesman_id, user_id) in
(select * from (select salesman_id, user_id from salesman_customers group by salesman_id, user_id having count(*) > 1) a)
and id not in (select * from (select min(id) from salesman_customers group by salesman_id, user_id having count(*) > 1 order by id) b))
ActiveRecord::Base.connection.execute sql
add_index :salesman_customers, [:salesman_id, :user_id], unique: true
end
end

@ -0,0 +1,5 @@
class MigrateCourseMessageAct < ActiveRecord::Migration[5.2]
def change
CourseActivity.where(course_act_type: "JoinCourse").update_all(course_act_type: "CourseMessage")
end
end

@ -45,7 +45,7 @@ namespace :homework_publishtime do
end end
end end
homework.course_acts << CourseActivity.new(user_id: homework.user_id, course_id: homework.course_id) if !homework.course_acts.exists? homework.course_act << CourseActivity.new(user_id: homework.user_id, course_id: homework.course_id) if !homework.course_act.present?
end end
# 分组设置发布时间的作业 # 分组设置发布时间的作业
@ -66,7 +66,7 @@ namespace :homework_publishtime do
.where("homework_type = 4 and end_time <= '#{Time.now}'") .where("homework_type = 4 and end_time <= '#{Time.now}'")
homework_commons.each do |homework| homework_commons.each do |homework|
# homework_challenge_settings = homework.homework_challenge_settings # homework_challenge_settings = homework.homework_challenge_settings
homework.homework_detail_manual.update_column("comment_status", 2) # homework.homework_detail_manual.update_column("comment_status", 2)
if homework.allow_late if homework.allow_late
if homework.unified_setting if homework.unified_setting

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

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

Loading…
Cancel
Save