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

dev_forum
jingquan huang 6 years ago
commit c536e3bc67

1
.gitignore vendored

@ -44,6 +44,7 @@
/config/secrets.yml
/config/redis.yml
/config/elasticsearch.yml
public/upload.html
/config/configuration.yml

@ -90,4 +90,4 @@ gem 'sinatra'
gem 'bulk_insert'
# elasticsearch
# gem 'searchkick'
gem 'searchkick'

@ -90,6 +90,14 @@ GEM
connection_pool (2.2.2)
crass (1.0.4)
diff-lcs (1.3)
elasticsearch (7.2.0)
elasticsearch-api (= 7.2.0)
elasticsearch-transport (= 7.2.0)
elasticsearch-api (7.2.0)
multi_json
elasticsearch-transport (7.2.0)
faraday
multi_json
erubi (1.7.1)
execjs (2.7.0)
faraday (0.15.4)
@ -100,6 +108,7 @@ GEM
grape-entity (0.7.1)
activesupport (>= 4.0)
multi_json (>= 1.3.2)
hashie (3.6.0)
htmlentities (4.3.4)
httparty (0.16.2)
multi_xml (>= 0.5.2)
@ -255,6 +264,10 @@ GEM
sprockets (>= 2.8, < 4.0)
sprockets-rails (>= 2.0, < 4.0)
tilt (>= 1.1, < 3)
searchkick (3.1.3)
activemodel (>= 4.2)
elasticsearch (>= 5)
hashie
selenium-webdriver (3.14.0)
childprocess (~> 0.5)
rubyzip (~> 1.2)
@ -344,6 +357,7 @@ DEPENDENCIES
ruby-ole
rubyzip
sass-rails (~> 5.0)
searchkick
selenium-webdriver
sidekiq
simple_xlsx_reader

@ -1,6 +1,5 @@
class AccountsController < ApplicationController
include ErrorCommon
#skip_before_action :check_account, :only => [:logout]
def index
@ -39,7 +38,7 @@ class AccountsController < ApplicationController
code = generate_identifier User, 8
login = pre + code
@user = User.new(admin: false, login: login, mail: email, phone: phone)
@user = User.new(admin: false, login: login, mail: email, phone: phone, type: "User")
@user.password = params[:password]
# 现在因为是验证码,所以在注册的时候就可以激活
@user.activate

@ -30,6 +30,10 @@ class ApplicationController < ActionController::Base
end
end
def admin_or_business?
User.current.admin? || User.current.business?
end
def user_course_identity
@user_course_identity = current_user.course_identity(@course)
if @user_course_identity > Course::STUDENT && @course.is_public == 0
@ -43,14 +47,14 @@ class ApplicationController < ActionController::Base
# params[:type] 1: 注册2忘记密码
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}$/
tip_exception("请输入正确的手机号或邮箱")
tip_exception(-2, "请输入正确的手机号或邮箱")
end
# 考虑到安全参数问题多一次查询去掉Union
user = User.where(phone: login).first || User.where(mail: login).first
if type.to_i == 1 && !user.nil?
tip_exception(-2, "该手机号码或邮箱已被注册")
elsif type.to_i == 2 && user.nil?
tip_exception("该手机号码或邮箱未注册")
tip_exception(-2, "该手机号码或邮箱未注册")
end
sucess_status
end

@ -5,7 +5,6 @@ class AttachmentsController < ApplicationController
before_action :require_login, :check_auth
before_action :find_file, only: %i[show destroy]
include ErrorCommon
include ApplicationHelper
def show
@ -39,7 +38,8 @@ class AttachmentsController < ApplicationController
content_type = upload_file.content_type.presence || 'application/octet-stream'
remote_path = file_save_to_ucloud(local_path[folder.size, local_path.size], local_path, content_type)
# remote_path = file_save_to_ucloud(local_path[folder.size, local_path.size], local_path, content_type)
remote_path = nil # TODO 暂时本地上传,待域名配置后方可上传至云端
logger.info "local_path: #{local_path}"
logger.info "remote_path: #{remote_path}"

@ -2,10 +2,10 @@ class BoardsController < ApplicationController
before_action :require_login, :check_auth
before_action :find_course, only: [:create]
before_action :set_board, except: [:create]
before_action :teacher_allowed
before_action :teacher_or_admin_allowed
def index
@boards = @course.boards.includes(messages: [:last_reply, :author]);
@boards = @course.boards.includes(messages: [:last_reply, :author])
end
def show

@ -0,0 +1,11 @@
class Competitions::BaseController < ApplicationController
include PaginateHelper
before_action :require_login
helper_method :current_competition
def current_competition
@_current_competition ||= Competition.find_by!(identifier: params[:competition_id].presence || params[:id])
end
end

@ -0,0 +1,4 @@
class Competitions::CompetitionStaffsController < Competitions::BaseController
def show
end
end

@ -0,0 +1,32 @@
class Competitions::CompetitionsController < Competitions::BaseController
skip_before_action :require_login
def index
# 已上架 或者 即将上架
competitions = Competition.where(status: true).or(Competition.where.not(published_at: nil))
competitions =
case params[:category]
when 'nearly_published' then competitions.where(status: false)
when 'progressing' then competitions.where('end_time > NOW()')
when 'ended' then competitions.where('end_time < NOW()')
else competitions
end
@count = competitions.count
competitions = competitions.order(published_at: :desc, online_time: :desc)
@competitions = paginate(competitions.includes(current_stage_section: :competition_stage))
ids = @competitions.map(&:id)
@member_count_map = TeamMember.where(competition_id: ids).group(:competition_id).count
@stage_count_map = CompetitionStage.where(competition_id: ids).group(:competition_id).count
end
def show
unless current_competition.published? || admin_or_business?
render_forbidden
return
end
end
end

@ -2,6 +2,10 @@ module ControllerRescueHandler
extend ActiveSupport::Concern
included do
rescue_from Exception do |e|
logger.error e
render json: {status: -1, message: e.message}
end
# rescue_from ActionView::MissingTemplate, with: :object_not_found
# rescue_from ActiveRecord::RecordNotFound, with: :object_not_found
rescue_from Educoder::TipException, with: :tip_show

@ -1,10 +0,0 @@
module ErrorCommon
extend ActiveSupport::Concern
included do
rescue_from Exception do |e|
logger.error e
render json: {status: -1, message: e.message}
end
end
end

@ -0,0 +1,8 @@
module PaginateHelper
def paginate(objs, **opts)
page = params[:page].to_i <= 0 ? 1 : params[:page].to_i
per_page = params[:per_page].to_i > 0 ? params[:per_page].to_i : 20
Kaminari.paginate_array(objs).page(page).per(per_page)
end
end

@ -2,7 +2,7 @@ class CourseModulesController < ApplicationController
before_action :require_login, :check_auth
before_action :set_module, except: [:unhidden_modules]
before_action :find_course, only: [:unhidden_modules]
before_action :teacher_allowed
before_action :teacher_or_admin_allowed
# 模块置顶
def sticky_module
@ -16,6 +16,7 @@ class CourseModulesController < ApplicationController
# 模块隐藏
def hidden_module
tip_exception("请至少保留一个课堂模块") if @course.none_hidden_course_modules.where.not(id: @course_module.id).size == 0
@course_module.update_attributes(hidden: 1)
normal_status(0, "更新成功")
end

@ -1,7 +1,7 @@
class CourseSecondCategoriesController < ApplicationController
before_action :require_login, :check_auth
before_action :set_category
before_action :teacher_allowed
before_action :teacher_or_admin_allowed
# 目录重命名
def rename_category

@ -62,15 +62,12 @@ class CoursesController < ApplicationController
if @order == "mine"
@courses = Course.joins(:course_members)
.where("is_delete = 0 AND is_hidden = 0 AND course_members.user_id = ?", @user.id)
.order("courses.id = 1309 DESC, courses.#{order_str} DESC")
elsif @order == "created_at"
# REDO:Extension
@courses = Course.where(is_delete: 0, is_hidden: 0, is_end: 0)
.order("courses.id = 1309 DESC, courses.#{order_str} DESC")
else
# REDO:Extension
@courses = Course.where(is_delete: 0, is_hidden: 0)
.order("courses.id = 1309 DESC, courses.#{order_str} DESC")
end
# 根据搜索关键字进一步筛选
@ -89,14 +86,15 @@ class CoursesController < ApplicationController
@courses = @courses.joins(:school, course_members: :user)
.where("#{sql}", keyword: "%#{params[:search]}%").distinct
end
@courses_count = @courses.size
@courses_count = @courses.count("courses.id")
@courses = @courses.order("courses.id = 1309 DESC, courses.#{order_str} DESC")
# 分页
page = params[:page] || 1
limit = params[:limit] || 16
@courses = @courses.page(page).per(limit)
@courses = @courses.preload(:school, teacher: :user_extension)
@courses = @courses.preload(:school, :none_hidden_course_modules, teacher: :user_extension)
end
def visits_plus_one
@ -1059,6 +1057,7 @@ class CoursesController < ApplicationController
tip_exception("课堂名称应以课程名称开头命名") unless params[:course][:name].index(params[:course_list_name]) &&
params[:course][:name].index(params[:course_list_name]) == 0
tip_exception("课堂所属单位不能为空!") if params[:school].blank?
tip_exception("请至少添加一个课堂模块") if params[:course_module_types].blank?
@school = School.find_by!(name: params[:school].strip)
end

@ -689,7 +689,7 @@ class ExercisesController < ApplicationController
ActiveRecord::Base.transaction do
begin
check_ids = Exercise.where(id: params[:check_ids])
ex_end_time = params[:end_time] || Time.at(((1.month.since.to_i)/3600.0).ceil * 3600)
ex_end_time = params[:end_time].to_time
check_ids.each do |exercise|
if exercise.present?
if exercise.unified_setting
@ -701,20 +701,13 @@ class ExercisesController < ApplicationController
if ex_status == 1 #如果试卷存在已发布的,或者是已截止的,那么则直接跳过
g_course = params[:group_ids] #表示是否传入分班参数,如果传入分班的参数,那么试卷的统一设置需修改
if g_course
# course_groups = @course.teacher_course_groups.get_user_groups(current_user.id)
#
# if course_groups.blank?
# user_course_groups = @course.course_groups.present? ? @course.course_groups.pluck(:id) : []
# else
# user_course_groups = course_groups.pluck(:course_group_id).reject(&:blank?).uniq
# end
user_course_groups = @course.charge_group_ids(current_user)
if g_course.map(&:to_i).sort == user_course_groups.sort # 如果是设置为全部班级,则试卷不用分组,且试卷设定为统一设置,否则则分组设置
exercise.exercise_group_settings.destroy_all
ex_unified = true
e_time = ex_end_time
else
e_time = exercise.exercise_group_settings.end_time_no_null.map(&:end_time).max
ex_unified = false
g_course.each do |i|
exercise_group_setting = exercise.exercise_group_settings.find_in_exercise_group("course_group_id",i).first #根据课堂分班的id寻找试卷所在的班级
@ -732,20 +725,14 @@ class ExercisesController < ApplicationController
new_exercise_group.save
end
end
group_ids = params[:group_ids]
end
else
exercise.exercise_group_settings.destroy_all
ex_unified = true
end
if exercise.end_time.blank?
e_time = ex_end_time
elsif exercise.exercise_group_settings.end_time_no_null.count > 0 # 该试卷分组有结束时间为空的
e_time = exercise.exercise_group_settings.end_time_no_null.map(&:end_time).max
else
e_time = exercise.end_time
end
ex_status = set_exercise_status(Time.now,e_time)
exercise_params = {
:publish_time => Time.now,
@ -1294,7 +1281,7 @@ class ExercisesController < ApplicationController
def export_exercise
@request_url = request.base_url
@exercise_questions = @exercise.exercise_questions.includes(:exercise_choices).order("question_number ASC")
filename_ = "#{@exercise.user.real_name}_#{@course.name}__#{Time.now.strftime('%Y%m%d_%H%M%S')}"
filename_ = "#{@exercise.user.real_name}_#{@course.name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}.pdf"
stylesheets = "#{Rails.root}/app/templates/exercise_export/exercise_export.css"
render pdf: 'exercise_export/blank_exercise', filename: filename_, stylesheets: stylesheets
end
@ -1329,8 +1316,6 @@ class ExercisesController < ApplicationController
@exercise_all_users = @exercise.exercise_users
ex_common_ids = @exercise.common_published_ids(current_user.id)
@exercise_course_groups = @course.get_ex_published_course(ex_common_ids)
@exercise_users_list = @exercise.all_exercise_users(current_user.id)
@course_all_members_count = @exercise_users_list.size
#班级的选择
if params[:exercise_group_id].present?
@ -1338,6 +1323,10 @@ class ExercisesController < ApplicationController
exercise_students = @course_all_members.course_find_by_ids("course_group_id",group_id) # 试卷所分班的全部人数
user_ids = exercise_students.pluck(:user_id).reject(&:blank?)
@exercise_all_users = @exercise.exercise_users.exercise_commit_users(user_ids)
@course_all_members_count = @exercise_all_users.size
else
@exercise_users_list = @exercise.all_exercise_users(current_user.id)
@course_all_members_count = @exercise_users_list.size
end
@exercise_commit_users = @exercise_all_users.commit_exercise_by_status(1) #试卷的已提交用户
@exercise_commit_user_ids = @exercise_commit_users.pluck(:user_id).uniq #已提交试卷的全部用户id

@ -448,7 +448,7 @@ class HomeworkCommonsController < ApplicationController
tip_exception("发布时间不能早于当前时间") if params[:publish_time] <= Time.now.strftime("%Y-%m-%d %H:%M:%S")
tip_exception("截止时间不能早于当前时间") if params[:end_time] <= Time.now.strftime("%Y-%m-%d %H:%M:%S")
tip_exception("截止时间不能早于发布时间") if params[:publish_time] > params[:end_time]
tip_exception("截止时间不能于课堂结束时间") if @course.end_date.present? && params[:end_time] > @course.end_date.end_of_day
tip_exception("截止时间不能于课堂结束时间") if @course.end_date.present? && params[:end_time] > @course.end_date.end_of_day
@homework.unified_setting = 1
@homework.homework_group_settings.destroy_all
@ -470,7 +470,7 @@ class HomeworkCommonsController < ApplicationController
tip_exception("发布时间不能早于当前时间") if setting[:publish_time] <= strf_time(Time.now)
tip_exception("截止时间不能早于当前时间") if setting[:end_time] <= strf_time(Time.now)
tip_exception("截止时间不能早于发布时间") if setting[:publish_time] > setting[:end_time]
tip_exception("截止时间不能于课堂结束时间") if @course.end_date.present? && setting[:end_time] > @course.end_date.end_of_day
tip_exception("截止时间不能于课堂结束时间") if @course.end_date.present? && setting[:end_time] > @course.end_date.end_of_day
publish_time = setting[:publish_time] == "" ? Time.now : setting[:publish_time]
@ -504,7 +504,7 @@ class HomeworkCommonsController < ApplicationController
if @homework.end_time > Time.now && @homework.unified_setting
tip_exception("截止时间不能为空") if params[:end_time].blank?
tip_exception("截止时间不能早于当前时间") if params[:end_time] <= strf_time(Time.now)
tip_exception("截止时间不能于课堂结束时间") if @course.end_date.present? && params[:end_time] > strf_time(@course.end_date.end_of_day)
tip_exception("截止时间不能于课堂结束时间") if @course.end_date.present? && params[:end_time] > strf_time(@course.end_date.end_of_day)
@homework.end_time = params[:end_time]
@ -522,7 +522,7 @@ class HomeworkCommonsController < ApplicationController
tip_exception("截止时间不能早于等于当前时间") if setting[:end_time] <= strf_time(Time.now)
tip_exception("截止时间不能早于发布时间") if setting[:publish_time] > setting[:end_time]
tip_exception("截止时间不能于课堂结束时间") if setting[:end_time] > strf_time(@course.end_date.end_of_day)
tip_exception("截止时间不能于课堂结束时间") if @course.end_date.present? && setting[:end_time] > strf_time(@course.end_date.end_of_day)
group_settings.none_published.update_all(publish_time: setting[:publish_time])
group_settings.none_end.update_all(end_time: setting[:end_time])
@ -822,66 +822,98 @@ class HomeworkCommonsController < ApplicationController
@main_catrgory = @course.course_modules.where(module_type: "shixun_homework")
@homework_category = @main_catrgory.take.course_second_categories
## 我的实训
@shixuns =
if params[:order_by] == 'mine'
current_user.my_shixuns.unhidden
else
if current_user.admin?
Shixun.unhidden
else
none_shixun_ids = ShixunSchool.where("school_id != #{current_user.school_id}").pluck(:shixun_id)
@shixuns = Shixun.where.not(id: none_shixun_ids).unhidden
end
end
search = params[:search]
type = params[:type]
# 超级管理员用户显示所有未隐藏的实训、非管理员显示所有已发布的实训(对本单位公开且未隐藏未关闭)
if current_user.admin?
@shixuns = Shixun.unhidden
else
none_shixun_ids = ShixunSchool.where("school_id != #{current_user.school_id}").pluck(:shixun_id)
## 方向
if params[:tag_level].present? && params[:tag_id].present?
@shixuns = @shixuns.filter_tag(params[:tag_level].to_i, params[:tag_id].to_i)
case params[:tag_level].to_i
when 1 #大类
@search_tags = Repertoire.find(params[:tag_id].to_i).name
when 2 #子类
@search_tags = SubRepertoire.find(params[:tag_id].to_i).name
when 3 #tag
tag = TagRepertoire.find(params[:tag_id].to_i)
@search_tags = "#{tag.sub_repertoire.name} / #{tag.name}"
end
@shixuns = Shixun.where.not(id: none_shixun_ids).unhidden
end
## 搜索关键字创建者、实训名称、院校名称
if params[:keyword].present?
keyword = params[:keyword].strip
@shixuns = @shixuns.joins(user: [user_extenison: :school]).
where("schools.name like '%#{keyword}%'
or concat(lastname, firstname) like '%#{keyword}%'
or shixuns.name like '%#{keyword.split(" ").join("%")}%'").distinct
end
# 实训的所有标签
@tags = TagRepertoire.select([:id, :name]).joins(:shixuns).where(shixuns: {id: @shixuns}).distinct
## 筛选 难度
if params[:diff].present? && params[:diff].to_i != 0
@shixuns = @shixuns.where(trainee: params[:diff])
if params[:search] && params[:search].strip != ""
@shixuns = @shixuns.joins(:user).where("shixuns.name like ? or concat(users.lastname, users.firstname) like ?",
"%#{search}%", "%#{search}%").distinct
end
## 排序参数
bsort = params[:sort] || 'desc'
case params[:order_by] || 'hot'
when 'hot'
@shixuns = @shixuns.order("myshixuns_count #{bsort}")
when 'mine'
@shixuns = @shixuns.order("shixuns.created_at #{bsort}")
else
@shixuns = @shixuns.order("myshixuns_count #{bsort}")
unless type.blank? || type == "all"
@shixuns = @shixuns.joins(:shixun_tag_repertoires).where(shixun_tag_repertoires: {tag_repertoire_id: type}).distinct
end
@total_count = @shixuns.count
@shixuns = @shixuns.select([:id, :name, :status, :myshixuns_count, :identifier, :user_id, :trainee]).reorder("shixuns.created_at desc")
@shixuns_count = @shixuns.size
## 分页参数
page = params[:page] || 1
limit = params[:limit] || 15
@shixuns = @shixuns.includes(:challenges, user: [user_extension: :school]).page(page).per(limit)
page = params[:page] || 1
@shixuns = @shixuns.includes(:challenges, user: [user_extension: :school]).page(page).per(10)
# 新版用下面的代码
# ## 我的实训
# @shixuns =
# if params[:order_by] == 'mine'
# current_user.my_shixuns.unhidden
# else
# if current_user.admin?
# Shixun.unhidden
# else
# none_shixun_ids = ShixunSchool.where("school_id != #{current_user.school_id}").pluck(:shixun_id)
#
# @shixuns = Shixun.where.not(id: none_shixun_ids).unhidden
# end
# end
#
# ## 方向
# if params[:tag_level].present? && params[:tag_id].present?
# @shixuns = @shixuns.filter_tag(params[:tag_level].to_i, params[:tag_id].to_i)
# case params[:tag_level].to_i
# when 1 #大类
# @search_tags = Repertoire.find(params[:tag_id].to_i).name
# when 2 #子类
# @search_tags = SubRepertoire.find(params[:tag_id].to_i).name
# when 3 #tag
# tag = TagRepertoire.find(params[:tag_id].to_i)
# @search_tags = "#{tag.sub_repertoire.name} / #{tag.name}"
# end
# end
#
# ## 搜索关键字创建者、实训名称、院校名称
# if params[:keyword].present?
# keyword = params[:keyword].strip
# @shixuns = @shixuns.joins(user: [user_extenison: :school]).
# where("schools.name like '%#{keyword}%'
# or concat(lastname, firstname) like '%#{keyword}%'
# or shixuns.name like '%#{keyword.split(" ").join("%")}%'").distinct
# end
#
# ## 筛选 难度
# if params[:diff].present? && params[:diff].to_i != 0
# @shixuns = @shixuns.where(trainee: params[:diff])
# end
#
# ## 排序参数
# bsort = params[:sort] || 'desc'
# case params[:order_by] || 'hot'
# when 'hot'
# @shixuns = @shixuns.order("myshixuns_count #{bsort}")
# when 'mine'
# @shixuns = @shixuns.order("shixuns.created_at #{bsort}")
# else
# @shixuns = @shixuns.order("myshixuns_count #{bsort}")
# end
#
# @total_count = @shixuns.count
#
# ## 分页参数
# page = params[:page] || 1
# limit = params[:limit] || 15
#
# @shixuns = @shixuns.includes(:challenges, user: [user_extension: :school]).page(page).per(limit)
#
end
def create_shixun_homework
@ -1016,7 +1048,8 @@ class HomeworkCommonsController < ApplicationController
def publish_homework
tip_exception("请至少选择一个分班") if params[:group_ids].blank? && @course.course_groups.size != 0
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)
tip_exception("截止时间不能晚于课堂结束时间") if @course.end_date.present? && params[:end_time] > strf_time(@course.end_date.end_of_day)
homeworks = @course.homework_commons.where(id: params[:homework_ids])
homeworks = homeworks.includes(:homework_group_settings, :homework_detail_manual)
@ -1035,6 +1068,7 @@ class HomeworkCommonsController < ApplicationController
if @course.course_groups.where(id: publish_groups).size == @course.course_groups.size
homework.homework_group_settings.destroy_all
homework.unified_setting = true
homework.end_time = params[:end_time]
else
homework.unified_setting = false
# 创建作业分班设置homework_group_setting
@ -1053,7 +1087,7 @@ class HomeworkCommonsController < ApplicationController
homework.publish_time = Time.now
# 截止时间不为空的保持原状,为空的改为一个月后, 非统一设置的更新为最大分班截止时间
# 截止时间的处理
if homework.end_time.nil?
homework.end_time = params[:end_time]
elsif homework.max_group_end_time

@ -258,15 +258,12 @@ class PollsController < ApplicationController
g_course = params[:group_ids] #表示是否传入分班参数,如果传入分班的参数那么poll的统一设置需修改
if g_course
user_course_groups = @course.charge_group_ids(current_user)
# if course_groups.blank?
# user_course_groups = @course.course_groups.present? ? @course.course_groups.pluck(:id) : []
# else
# user_course_groups = course_groups.pluck(:course_group_id)
# end
if g_course.map(&:to_i).sort == user_course_groups.sort # 如果是设置为全部班级,则问卷不用分组,且问卷设定为统一设置,否则则分组设置
poll.poll_group_settings.destroy_all
poll_unified = true
e_time = ex_end_time
else
e_time = poll.poll_group_settings.end_time_present.map(&:end_time).max
poll_unified = false
g_course.each do |i|
poll_group_setting = poll.poll_group_settings.find_in_poll_group("course_group_id",i).first #根据课堂分班的id寻找问卷所在的班级
@ -289,13 +286,7 @@ class PollsController < ApplicationController
else
poll.poll_group_settings.destroy_all
poll_unified = true
end
if poll.end_time.blank?
e_time = ex_end_time
elsif poll.poll_group_settings.end_time_present.count > 0 # 该问卷分组有结束时间为空的
e_time = poll.poll_group_settings.end_time_present.map(&:end_time).max
else
e_time = poll.end_time
end
poll_status = set_poll_status(Time.now,e_time)

@ -501,8 +501,8 @@ class ShixunsController < ApplicationController
# TODO: 目前实训只做软删除.
def destroy
# apply_records = ApplyAction.where(container_id: @shixun.id, container_type: "ApplyShixun")
# apply_records.delete_all if apply_records
apply_records = ApplyAction.where(container_id: @shixun.id, container_type: "ApplyShixun")
apply_records.delete_all if apply_records
# HomeworkCommonShixuns.where(shixun_id: @shixun).delete_all
# @shixun.destroy
@shixun.update_column(:status, -1)

@ -51,6 +51,13 @@ class UsersController < ApplicationController
:disposition => 'attachment' #inline can open in browser
end
def html_show
@contents = File.read("#{params[:path]}")
respond_to do |format|
format.html {render :layout => false}
end
end
# Redo: 消息总数缓存
def get_navigation_info
@old_domain = edu_setting('old_edu_host')

@ -0,0 +1,9 @@
module ApplicationDecorator
def display_time_method(*columns, format: '%Y-%m-%d %H:%M:%S')
columns.each do |column_name|
define_method "display_#{column_name}" do
public_send(column_name)&.strftime(format)
end
end
end
end

@ -0,0 +1,6 @@
module CompetitionDecorator
extend ApplicationDecorator
display_time_method :start_time, :end_time, :enroll_end_time
end

@ -0,0 +1,5 @@
module CompetitionStageSectionDecorator
extend ApplicationDecorator
display_time_method :start_time, :end_time
end

@ -87,12 +87,13 @@ module ExercisesHelper
def exercise_commit_result(questions,user_ids)
question_infos = []
percent = 0.0
questions.each do |ex|
questions.includes(:exercise_choices).each do |ex|
ex_total_score = user_ids.count * ex&.question_score #该试卷的已回答的总分
ex_answers = ex.exercise_answers.includes(:exercise_choice)
ex_answers = ex.exercise_answers
if ex.question_type != Exercise::PRACTICAL
ques_title = ex.question_title
ques_less_title = nil
ex_answers = ex.exercise_answers
effictive_users = ex_answers.search_answer_users("user_id",user_ids)
else
ques_title = ex.shixun.name
@ -111,21 +112,24 @@ module ExercisesHelper
question_answer_infos = []
if ex.question_type <= Exercise::JUDGMENT #选择题和判断题
ex_choices = ex.exercise_choices
standard_answer = ex.exercise_standard_answers.pluck(:exercise_choice_id).sort #标准答案的位置
right_users_count = 0 #该问题的回答正确的人数
#计算每个问题的答案人数
# commit_users.transaction do
#
# end
user_ids.each do |user_id|
answer_choice_array = effictive_users.select(:user_id,:exercise_choice_id).find(user_id:user_id)&.map {|s| s.exercise_choice.choice_position}.uniq
if answer_choice_array.sort == standard_answer
right_users_count += 1
if ex.question_type == Exercise::MULTIPLE #多选题
user_ids.each do |user_id|
ex_choice_ids = effictive_users.map{|e| e.exercise_choice_id if e.user_id == user_id}.reject(&:blank?).uniq
answer_choice_array = ex_choices.map{|a| a.choice_position if ex_choice_ids.include?(a.id)}.reject(&:blank?).uniq
if answer_choice_array.sort == standard_answer
right_users_count += 1
end
end
else #单选题和判断题
standard_answer_choice_id = ex.exercise_choices.find_by(choice_position: standard_answer.first)&.id
right_users_count = effictive_users.select{|answer| answer.exercise_choice_id == standard_answer_choice_id}.size
end
percent = effictive_users_count > 0 ? (right_users_count / effictive_users_count.to_f).round(3)*100 : 0.0
ex.exercise_choices.each do |c|
ex_choices.each do |c|
right_answer = standard_answer.include?(c.choice_position) #选项的标准答案为选项的位置
answer_this_choice = effictive_users.search_exercise_answer("exercise_choice_id",c.id)
answer_users_count = answer_this_choice.size

@ -39,6 +39,7 @@ module Util
end
def extract_content(str)
return '' if str.blank?
str.gsub(/<\/?.*?>/, '').gsub(/[\n\t\r]/, '').gsub(/&nbsp;/, '')
end
end

@ -6,4 +6,5 @@ class ApplyUserAuthentication < ApplicationRecord
scope :real_name_auth, -> { where(auth_type: 1) }
scope :professional_auth, -> { where(auth_type: 2) }
scope :processing, -> { where(status: 0) }
scope :passed, -> { where(status: 1) }
end

@ -1,6 +1,5 @@
class ChallengeTag < ApplicationRecord
# TODO: ES feature
# include Searchable::Dependents::ChallengeTag
include Searchable::Dependents::ChallengeTag
belongs_to :challenge, counter_cache: true
belongs_to :challenge_choose, optional: true

@ -0,0 +1,40 @@
class Competition < ApplicationRecord
has_many :competition_modules, dependent: :destroy
has_many :competition_stages, dependent: :destroy
has_many :competition_stage_sections, dependent: :destroy
has_one :current_stage_section, -> { where('end_time > NOW()') }, class_name: 'CompetitionStageSection'
has_many :team_members, dependent: :destroy
has_many :competition_staffs, dependent: :destroy
has_one :teacher_staff, -> { where(category: :teacher) }, class_name: 'CompetitionStaff'
has_one :member_staff, -> { where.not(category: :teacher) }, class_name: 'CompetitionStaff'
has_many :attachments, as: :container
after_create :create_competition_modules
# 是否上架
def published?
status?
end
# 报名是否结束
def enroll_ended?
enroll_end_time.blank? || enroll_end_time < Time.now
end
# 是否已经报名
def enrolled?(user)
team_members.exists?(user_id: user.id)
end
private
def create_competition_modules
CompetitionModule.bulk_insert(*%i[competition_id name position]) do |worker|
%w(首页 报名 通知公告 排行榜 资料下载).each_with_index do |name, index|
worker.add(competition_id: id, name: name, position: index + 1)
end
end
end
end

@ -0,0 +1,4 @@
class CompetitionEntry < ApplicationRecord
belongs_to :competition_stage
belongs_to :competition_stage_section
end

@ -0,0 +1,7 @@
class CompetitionModule < ApplicationRecord
default_scope { order('position ASC') }
belongs_to :competition
has_one :competition_module_md_content, dependent: :destroy
end

@ -0,0 +1,5 @@
class CompetitionModuleMdContent < ApplicationRecord
belongs_to :competition_module
has_many :attachments, as: :container, dependent: :destroy
end

@ -0,0 +1,3 @@
class CompetitionStaff < ApplicationRecord
belongs_to :competition
end

@ -0,0 +1,7 @@
class CompetitionStage < ApplicationRecord
belongs_to :competition
has_many :competition_stage_sections, dependent: :destroy
has_many :competition_entries, dependent: :destroy
end

@ -0,0 +1,6 @@
class CompetitionStageSection < ApplicationRecord
belongs_to :competition
belongs_to :competition_stage
has_many :competition_entries, dependent: :destroy
end

@ -0,0 +1,8 @@
class CompetitionTeam < ApplicationRecord
belongs_to :user
belongs_to :competition
has_many :team_members, dependent: :destroy
has_many :members, -> { without_teachers }, class_name: 'TeamMember'
has_many :teachers, -> { only_teachers }, class_name: 'TeamMember'
end

@ -1,6 +1,5 @@
class Course < ApplicationRecord
# TODO: ES feature
# include Searchable::Course
include Searchable::Course
has_many :boards, dependent: :destroy
@ -11,6 +10,7 @@ class Course < ApplicationRecord
has_many :course_infos, dependent: :destroy
# 课堂左侧导航栏的模块
has_many :course_modules, dependent: :destroy
has_many :none_hidden_course_modules, -> { not_hidden }, class_name: "CourseModule"
has_many :board_course_modules, -> { board_module }, class_name: "CourseModule"
has_many :attachment_course_modules, -> { attachment_module }, class_name: "CourseModule"
has_many :common_course_modules, -> { common_homework_module }, class_name: "CourseModule"
@ -311,15 +311,13 @@ class Course < ApplicationRecord
#获取试卷/问卷已发布的班级id名称和人数。当为统一设置时显示全部否则只显示当前已发布的班级信息
def get_ex_published_course(common_ids)
teacher_power_courses = []
if course_groups.present?
common_ids.each do |i|
if i == 0
student_count = students.where(course_group_id:i).count
teacher_power_courses << {course_name:"未分班",course_id:0,student_count:student_count}
else
course_group_name = course_groups.find_by(id:i)
teacher_power_courses << {course_name:course_group_name&.name,course_id:i,student_count:course_group_name&.course_members_count}
end
publish_groups = course_groups.where(id: common_ids)
if common_ids.include?(0)
teacher_power_courses << {course_name:"未分班", course_id: 0, student_count: none_group_count}
end
if publish_groups.present?
publish_groups.each do |group|
teacher_power_courses << {course_name: group&.name,course_id: group&.id, student_count: group&.course_members_count}
end
end
teacher_power_courses

@ -31,7 +31,7 @@ class Game < ApplicationRecord
# 根据得分比例来算实际得分(试卷、实训作业)
def real_score score
final_score == challenge.score ? score : (final_score.to_f / challenge.score) * score
(final_score.to_f / challenge.all_score) * score
end
# 判断实训是否全部通关

@ -1,6 +1,5 @@
class Memo < ApplicationRecord
# TODO: ES feature
# include Searchable::Memo
include Searchable::Memo
has_many :memo_tag_repertoires, :dependent => :destroy
has_many :tag_repertoires, :through => :memo_tag_repertoires

@ -26,6 +26,7 @@ module Searchable::Memo
{
descendants_contents: Util.map_or_pluck(descendants, :content)
.map { |content| Util.extract_content(content)[0..Searchable::MAXIMUM_LENGTH] }
.join('<br/>')
}
end

@ -21,8 +21,8 @@ module Searchable::Shixun
def searchable_user_data
{
author_name: user.real_name,
author_school_name: user.school_name,
author_name: user&.real_name,
author_school_name: user&.school_name,
}
end
@ -31,7 +31,7 @@ module Searchable::Shixun
.each_with_index.map { |subject, index| "#{index + 1}#{subject}" }
{
challenge_names: challenge_names,
challenge_names: challenge_names.join(' '),
challenge_tag_names: Util.map_or_pluck(challenge_tags, :name).uniq.join(' ')
}
end

@ -31,15 +31,9 @@ module Searchable::Subject
end
def searchable_stages_data
subject_stages =
stages.map do |stage|
{
name: stage.name,
description: Util.extract_content(stage.description)[0..Searchable::MAXIMUM_LENGTH]
}
end
{ subject_stages: subject_stages}
subject_stages = stages.map { |stage| "#{stage.name} #{Util.extract_content(stage.description)}"[0..Searchable::MAXIMUM_LENGTH] }
{ subject_stages: subject_stages.join('<br/>') }
end
def to_searchable_json

@ -1,6 +1,5 @@
class Shixun < ApplicationRecord
# TODO: ES feature
# include Searchable::Shixun
include Searchable::Shixun
# status: 0编辑 1申请发布 2正式发布 3关闭 -1软删除
# hide_code 隐藏代码窗口

@ -1,6 +1,5 @@
class Stage < ApplicationRecord
# TODO: ES feature
# include Searchable::Dependents::Stage
include Searchable::Dependents::Stage
belongs_to :subject, counter_cache: true

@ -2,8 +2,7 @@
# 可以在初始创建的时候
class Subject < ApplicationRecord
# TODO: ES feature
# include Searchable::Subject
include Searchable::Subject
#status :0 编辑中 1 审核中 2 发布
belongs_to :repertoire

@ -0,0 +1,8 @@
class TeamMember < ApplicationRecord
belongs_to :user
belongs_to :competition
belongs_to :competition_team
scope :only_teachers, -> { where(is_teacher: true) }
scope :without_teachers, -> { where(is_teacher: false) }
end

@ -1,7 +1,6 @@
class User < ApplicationRecord
include Watchable
# TODO: ES feature
# include Searchable::Dependents::User
include Searchable::Dependents::User
# Account statuses
STATUS_ANONYMOUS = 0
@ -59,7 +58,7 @@ class User < ApplicationRecord
has_many :tidings, :dependent => :destroy
has_many :games, :dependent => :destroy
has_many :created_subjects
has_many :created_subjects, foreign_key: :user_id, class_name: 'Subject'
has_many :subjects, :through => :subject_members
has_many :subject_members, :dependent => :destroy
has_many :grades, :dependent => :destroy
@ -545,15 +544,6 @@ class User < ApplicationRecord
Educoder::Utils.random_hex(16)
end
# 基本资料是否完善
def base_info_completed?
user_columns = %i[nickname lastname]
user_extension_columns = %i[gender location location_city identity school_id department]
user_columns.all? { |column| public_send(column).present? } &&
user_extension_columns.all? { |column| user_extension.send(column).present? }
end
# 全部已认证
def all_certified?
authentication? && professional_certification?

@ -35,6 +35,13 @@ class Users::UpdateAccountService < ApplicationService
extension.technical_title = params[:technical_title]
end
# 职业、学校变动需要重新进行职业认证
if extension.identity_changed? || extension.school_id_changed?
user.professional_certification = false
# 撤销之前的职业认证
user.apply_user_authentication.professional_auth.passed.update_all(status: 3)
end
# 表示资料完整
user.profile_completed = true

@ -0,0 +1,26 @@
competition = current_competition
json.enroll_ended competition.enroll_ended?
json.enrolled competition.enrolled?(current_user)
# 教师报名设置
if competition.teacher_staff.present?
json.teacher_staff do
json.minimum competition.teacher_staff.minimum
json.maximum competition.teacher_staff.maximum
json.mutiple_limited competition.teacher_staff.mutiple_limited
end
else
json.teacher_staff nil
end
# 教师报名设置
if competition.member_staff.present?
json.member_staff do
json.minimum competition.member_staff.minimum
json.maximum competition.member_staff.maximum
json.mutiple_limited competition.member_staff.mutiple_limited
end
else
json.member_staff nil
end

@ -0,0 +1,29 @@
json.count @count
json.competitions do
json.array! @competitions.each do |competition|
json.extract! competition, :id, :identifier, :name, :sub_title
json.visits_count competition.visits
member_count = @member_count_map&.fetch(competition.id, 0) || competition.team_members.count
json.member_count member_count.zero? ? 268 : member_count
json.image url_to_avatar(competition)
json.published competition.published?
json.nearly_published competition.published_at.present?
json.single_stage (@stage_count_map&.fetch(competition.id, 0) || competition.competition_stages.count) == 1
json.start_time competition.display_start_time
json.end_time competition.display_end_time
json.enroll_end_time competition.display_enroll_end_time
section = competition.current_stage_section
if section
json.current_stage do
json.name = section.competition_stage.name
json.start_time section.display_start_time
json.end_time section.display_end_time
end
end
end
end

@ -0,0 +1,36 @@
competition = current_competition
json.extract! competition, :id, :name, :sub_title, :identifier
json.start_time competition.display_start_time
json.end_time competition.display_end_time
json.enroll_end_time competition.display_enroll_end_time
json.images do
json.array! competition.attachments, partial: 'attachments/attachment_simple', as: :attachment
end
json.competition_stages do
stages = competition.competition_stages.includes(competition_stage_sections: :competition_entries)
json.array! stages.each do |stage|
json.extract! stage, :id, :name
json.sections do
json.array! stage.competition_stage_sections.each do |section|
json.extract! section, :id, :name
decorator_section = ActiveDecorator::Decorator.instance.decorate(section)
json.start_time decorator_section.display_start_time
json.end_time decorator_section.display_end_time
is_start = section.start_time > Time.now
json.entries do
json.array! section.competition_entries.each do |entry|
json.extract! entry, :id, :name
json.url is_start ? entry.url : ''
end
end
end
end
end
end

@ -11,5 +11,6 @@ json.courses @courses do |course|
json.is_public course.is_public
json.is_accessible course.is_public == 1 || @user.course_identity(course) < Course::NORMAL
json.is_end course.is_end
json.first_category_url module_url(course.none_hidden_course_modules.first, course)
end
json.courses_count @courses_count

@ -1,5 +1,4 @@
json.question_id question.id
# json.question_number question.question_number
q_positon = question.question_number
if ques_position.present?
q_positon = ques_position
@ -22,7 +21,7 @@ if question.question_type <= 2 #当为选择题或判断题时,只显示选
user_answer_b = user_answer.include?(a.id)
json.c_position (index+1) if ex_choice_random_boolean #当选项随机时,选项位置以此为准,否则不出现
json.choice_id a.id
json.choice_text a.choice_text
json.choice_text "#{(index+65).chr}.#{a.choice_text}"
json.choice_position a.choice_position
if exercise_type == 1 || exercise_type == 4 #1为教师编辑/预览 试卷或问题2为空白试卷即标准答案和用户答案都不显示3为用户开始答题的显示4为老师评阅试卷或学生在截止后查看试卷
json.standard_boolean standard_answer_b

@ -34,9 +34,16 @@ json.commit_results do
json.effictive_counts q[:ques_effictive_counts]
if q[:type] != Exercise::PRACTICAL
json.ques_details do
json.array! q[:ques_details] do |d|
json.array! q[:ques_details].each_with_index.to_a do |d,index|
if q[:type] <= Exercise::MULTIPLE
ques_index = (index+65).chr
elsif q[:type] == Exercise::JUDGMENT
ques_index = (index+1).to_s
else
ques_index = nil
end
json.choice_position d[:choice_position]
json.choice_text d[:choice_text]
json.choice_text ques_index.present? ? "#{ques_index}.#{d[:choice_text]}" : d[:choice_text]
json.choice_users_count d[:choice_users_count]
json.choice_percent d[:choice_percent]
json.choice_right_boolean d[:right_answer]

@ -1,12 +1,27 @@
# json.shixun_list @shixuns do |shixun|
# json.shixun_identifier shixun.identifier
# json.name shixun.name
# json.creator shixun.user&.full_name
# json.creator_login shixun.user&.login
# json.school shixun.user&.school_name
# json.myshixuns_count shixun.myshixuns_count
# json.level level_to_s(shixun.trainee)
# json.challenge_tags shixun.challenge_tags_name
# end
json.shixun_list @shixuns do |shixun|
json.shixun_identifier shixun.identifier
json.name shixun.name
json.creator shixun.user&.full_name
json.creator_login shixun.user&.login
json.school shixun.user&.school_name
json.shixun_id shixun.id
json.identifier shixun.identifier
json.shixun_name shixun.name
json.myshixuns_count shixun.myshixuns_count
json.school shixun.user&.school_name
json.creator shixun.user&.full_name
json.level level_to_s(shixun.trainee)
json.challenge_tags shixun.challenge_tags_name
end
json.tags @tags do |tag|
json.tag_id tag.id
json.tag_name tag.name
end
json.shixuns_count @total_count

@ -21,5 +21,5 @@ json.school_name extension&.school&.name
json.department_id extension&.department_id
json.department_name extension&.department&.name
json.base_info_completed user.base_info_completed?
json.base_info_completed user.profile_completed?
json.all_certified user.all_certified?

@ -10,7 +10,7 @@ json.top do
json.new_project_url "#{@old_domain}/projects/new"
json.join_course_url "#{@old_domain}/courses/join_course_multi_role"
json.join_project_url "#{@old_domain}/applied_project/applied_project_info"
json.message_url "#{@user_url}/user_tidings"
json.message_url "#{@old_domain}#{@user_url}/user_tidings"
json.new_message @new_message
json.career_url do

@ -0,0 +1 @@
<%= @contents.html_safe %>

@ -0,0 +1,13 @@
defaults: &defaults
url: http://localhost:9200
development:
<<: *defaults
test:
<<: *defaults
production:
<<: *defaults
url: 'http://elastic:Elas+ucloud123@106.75.27.125:59200/'
# url: 'http://elastic:TEST_elastickibana321@es-cn-0pp174wsj000iubdx.public.elasticsearch.aliyuncs.com'

@ -0,0 +1,2 @@
redis_config = Rails.application.config_for(:elasticsearch)
ENV['ELASTICSEARCH_URL'] = redis_config['url']

@ -58,6 +58,7 @@ Rails.application.routes.draw do
post :unfollow
get :get_user_info
get :attachment_show
get :html_show
get :get_navigation_info
post :reply_message
get :search_user_projects
@ -668,6 +669,14 @@ Rails.application.routes.draw do
end
resources :repertoires, only: [:index]
scope module: :competitions do
resources :competitions, only: [:index, :show] do
resources :competition_modules, only: [:index, :show]
resource :competition_staff
resources :competition_teams, only: [:index, :show]
end
end
end
#git 认证回调

@ -26,5 +26,10 @@ class ModifyMdAttachmentUrlForMdCotents < ActiveRecord::Migration[5.2]
subjects.find_each do |s|
s.update_column(:description, s.description.gsub("![](/attachments/download", "![](/api/attachments")) if s.description.present?
end
plats = PlatformSample.where(samples_type: ['introduction', 'knowledge'])
plats.find_each do |p|
p.update_column(:contents, p.contents.gsub("![](/attachments/download", "![](/api/attachments")) if p.contents.present?
end
end
end

Loading…
Cancel
Save