diff --git a/app/assets/javascripts/admins/auth_schools/index.js b/app/assets/javascripts/admins/auth_schools/index.js new file mode 100644 index 000000000..924a1a73e --- /dev/null +++ b/app/assets/javascripts/admins/auth_schools/index.js @@ -0,0 +1,6 @@ + +function show_add_manager(id) { + $(".auth-schools-user-add").modal("show"); + + $(".auth-schools-user-add").find("#school_id_input").val(id) +} \ No newline at end of file diff --git a/app/assets/javascripts/admins/major_informations/index.js b/app/assets/javascripts/admins/major_informations/index.js new file mode 100644 index 000000000..f0ab9c5f5 --- /dev/null +++ b/app/assets/javascripts/admins/major_informations/index.js @@ -0,0 +1,13 @@ +$(document).on('turbolinks:load', function() { + if ($('body.admins-major-informations-index-page').length > 0) { + var box_contain = $(".major-informations-list-container"); + box_contain.on("click",".collapse-item",function () { + var a_fa = $(this).find("i"); + if(a_fa.hasClass("fa-caret-right")){ + a_fa.removeClass("fa-caret-right").addClass("fa-caret-down"); + }else{ + a_fa.removeClass("fa-caret-down").addClass("fa-caret-right"); + } + }); + } +}); \ No newline at end of file diff --git a/app/assets/javascripts/course_stages.js b/app/assets/javascripts/course_stages.js new file mode 100644 index 000000000..dee720fac --- /dev/null +++ b/app/assets/javascripts/course_stages.js @@ -0,0 +1,2 @@ +// Place all the behaviors and hooks related to the matching controller here. +// All this logic will automatically be available in application.js. diff --git a/app/assets/stylesheets/admin.scss b/app/assets/stylesheets/admin.scss index efa12b32e..c70f7a572 100644 --- a/app/assets/stylesheets/admin.scss +++ b/app/assets/stylesheets/admin.scss @@ -51,3 +51,5 @@ input.form-control { position: absolute; } .position-r{position:relative;} +.color-grey-c{color:#ccc} +.inline-block{display:inline-block;} diff --git a/app/assets/stylesheets/admins/auth_schools.scss b/app/assets/stylesheets/admins/auth_schools.scss new file mode 100644 index 000000000..7106f6d42 --- /dev/null +++ b/app/assets/stylesheets/admins/auth_schools.scss @@ -0,0 +1,66 @@ +.admins-auth-schools-index-page{ + .list-item-title{ + padding-bottom:5px; + padding-left: 33px; + color: #555; + } + .list-item-title-1{ + width: 100px; + display: inline-block; + } + .list-item-title-2{ + width: 200px; + display: inline-block; + } + .collegeManage{ + float: left; + padding: 0px 8px; + border-radius: 6px; + background-color: #f5f5f5; + margin: 3px 0px 3px 10px; + height: 34px; + line-height: 34px; + a{ + color: #05101a; + } + a:hover{ + color: #007bff; + } + } + i:hover{ + color: #333; + } + .add-manager-i{ + float: left; + i{ + padding: 10px 5px; + } + } + .auth-schools-new-add, .auth-schools-user-add{ + .flex-column{ + input{ + height: 38px; + } + } + .search-school{ + margin-left: 15px; + } + + } + .school-search-list{ + background: #F4FAFF; + height: 280px; + overflow-y: scroll; + padding: 10px 0; + } + .school-list-item{ + padding: 2px 10px; + input{ + font-size: 20px; + margin-right: 5px; + } + + } + + +} \ No newline at end of file diff --git a/app/assets/stylesheets/admins/major_informations.scss b/app/assets/stylesheets/admins/major_informations.scss new file mode 100644 index 000000000..b5d4096e7 --- /dev/null +++ b/app/assets/stylesheets/admins/major_informations.scss @@ -0,0 +1,37 @@ +.admins-major-informations-index-page{ + .fr{ + float:right; + } + .panel-default{ + margin-bottom: 10px; + background-color: rgb(245, 245, 245); + .panel-heading{ + i{ + margin-right:15px; + font-size:16px; + color:rgb(204, 204, 204); + } + a{ + padding: 8px 10px; + display: inline-block; + width:100%; + color:rgb(102, 102, 102); + } + } + .panel-collapse{ + padding-top: 10px; + background: #fff; + table{ + text-align:center; + th,td{ + padding: 8px; + } + td{ + color:#888; + } + } + } + + } + +} \ No newline at end of file diff --git a/app/assets/stylesheets/common.scss b/app/assets/stylesheets/common.scss index 3310ec828..06b5c6643 100644 --- a/app/assets/stylesheets/common.scss +++ b/app/assets/stylesheets/common.scss @@ -33,4 +33,8 @@ input.form-control { .font-12 { font-size: 12px !important; } .font-14 { font-size: 14px !important; } .font-16 { font-size: 16px !important; } -.font-18 { font-size: 18px !important; } \ No newline at end of file +.font-18 { font-size: 18px !important; } +.padding10-5 { padding: 10px 5px;} +.width100 { width: 100%;} +.mb10 { margin-bottom: 10px ;} +.mt10 { margin-top: 10px ;} diff --git a/app/assets/stylesheets/course_stages.scss b/app/assets/stylesheets/course_stages.scss new file mode 100644 index 000000000..faa60b4b0 --- /dev/null +++ b/app/assets/stylesheets/course_stages.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the course_stages controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/controllers/admins/auth_schools_controller.rb b/app/controllers/admins/auth_schools_controller.rb new file mode 100644 index 000000000..3534188da --- /dev/null +++ b/app/controllers/admins/auth_schools_controller.rb @@ -0,0 +1,57 @@ +class Admins::AuthSchoolsController < Admins::BaseController + + def index + schools = School.where(ec_auth: 1).includes(:users).order("updated_at desc") + @params_page = params[:page] || 1 + @schools = paginate schools + end + + def destroy + ActiveRecord::Base.transaction do + school = School.where(id: params[:id]).first + school.destroy + end + end + + # 工程认证单位列表搜索学校 + def search_school + @schools = School.where("ec_auth != 1 and name like '%#{params[:name]}%'").limit(10) + end + + # 添加认证学校 + def add_school + all_schools = School.all + all_schools.where(id: params[:school_id]).update_all(ec_auth: 1) + schools = all_schools.where(ec_auth: 1).order("updated_at desc") + @params_page = params[:page] || 1 + @schools = paginate schools + end + + # 搜索用户 + def search_manager + school = School.find_by(id: params[:school_id]) + user_ids = school&.ec_school_users&.pluck(:user_id) + @users = User.where.not(id: user_ids).where("concat(lastname, firstname) like ?", "%#{params[:name].strip.to_s}%").limit(10) + end + + # 添加认证学校管理员 + def add_manager + ActiveRecord::Base.transaction do + user_ids = params[:user_id] + @school_id = params[:school_id] + user_ids.each do |id| + EcSchoolUser.create(user_id: id, school_id: @school_id) + end + @school_users = User.where(id: user_ids) + end + end + + # 删除学校管理员 + def remove_manager + ActiveRecord::Base.transaction do + manager = EcSchoolUser.where(school_id: params[:school_id], user_id: params[:user_id]).first + manager&.destroy + end + end + +end \ No newline at end of file diff --git a/app/controllers/admins/major_informations_controller.rb b/app/controllers/admins/major_informations_controller.rb new file mode 100644 index 000000000..931476c8c --- /dev/null +++ b/app/controllers/admins/major_informations_controller.rb @@ -0,0 +1,8 @@ +class Admins::MajorInformationsController < Admins::BaseController + + def index + disciplines = EcDiscipline.includes(ec_discipline_firsts: {ec_majors: :schools}).order("ec_disciplines.code asc") + @disciplines = paginate disciplines + end + +end \ No newline at end of file diff --git a/app/controllers/course_stages_controller.rb b/app/controllers/course_stages_controller.rb new file mode 100644 index 000000000..92e44a336 --- /dev/null +++ b/app/controllers/course_stages_controller.rb @@ -0,0 +1,105 @@ +class CourseStagesController < ApplicationController + before_action :require_login + before_action :find_course, only: [:create] + before_action :find_course_stage, only: [:update, :destroy, :edit, :up_position, :down_position] + before_action :user_course_identity, :teacher_allowed + + def create + ActiveRecord::Base.transaction do + begin + @stage = CourseStage.new(stage_params) + @stage.course_id = @course.id + @stage.position = @course.course_stages.count + 1 + @stage.save! + unless params[:shixun_id].blank? + shixuns = Shixun.where(id: params[:shixun_id]).order("field(id, #{params[:shixun_id].join(",")})") + shixuns.each do |shixun| + CourseStageShixun.create!(course_stage_id: @stage.id, course_id: @course.id, shixun_id: shixun.id, position: @stage.course_stage_shixuns.count + 1) + end + end + normal_status("创建成功") + rescue Exception => e + uid_logger_error(e.message) + tip_exception(e.message) + raise ActiveRecord::Rollback + end + end + end + + def edit + + end + + def update + ActiveRecord::Base.transaction do + begin + @stage.update_attributes!(stage_params) + @stage.course_stage_shixuns.destroy_all + unless params[:shixun_id].blank? + params[:shixun_id].each do |shixun_id| + shixun = Shixun.where(id: shixun_id).first + @stage.course_stage_shixuns.create!(course_id: @course.id, shixun_id: shixun.id, position: @stage.course_stage_shixuns.count + 1) if shixun.present? + end + end + normal_status("更新成功") + rescue Exception => e + uid_logger_error(e.message) + tip_exception(e.message) + raise ActiveRecord::Rollback + end + end + end + + def destroy + ActiveRecord::Base.transaction do + @course.course_stages.where("position > ?", @stage.position).update_all("position = position - 1") + @stage.destroy! + normal_status("删除成功") + end + end + + def up_position + ActiveRecord::Base.transaction do + begin + position = @stage.position + tip_exception("第一章不能向上移动") if @stage.position == 1 + pre_stage = @course.course_stages.where(position: position - 1).first + pre_stage.update_attributes(position: position) + @stage.update_attributes(position: position - 1) + normal_status("更新成功") + rescue Exception => e + uid_logger("stage up failed: #{e.message}") + raise ActiveRecord::Rollback + end + end + end + + def down_position + ActiveRecord::Base.transaction do + begin + position = @stage.position + rails "最后一章不能向下移动" if @stage.position == @course.course_stages.count + next_stage = @course.course_stages.where(position: position + 1).first + next_stage.update_attributes(position: position) + @stage.update_attributes(position: position + 1) + normal_status("更新成功") + rescue Exception => e + uid_logger("stage up failed: #{e.message}") + raise ActiveRecord::Rollback + end + end + end + + private + + def find_course_stage + @stage = CourseStage.find_by!(id: params[:id]) + @course = @stage.course + end + + def stage_params + tip_exception("章节名称不能为空") if params[:name].blank? + params.permit(:name, :description) + end + +end diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb index f6fae91db..bec53f993 100644 --- a/app/controllers/courses_controller.rb +++ b/app/controllers/courses_controller.rb @@ -167,6 +167,8 @@ class CoursesController < ApplicationController end Inform.create(container: @course, description: @subject.learning_notes, name: "学习须知") + + @course.create_stages @course.subject end course_module_types = params[:course_module_types] @@ -266,9 +268,9 @@ class CoursesController < ApplicationController def online_learning @subject = @course.subject - @stages = @subject&.stages + @stages = @course.course_stages @user = current_user - @start_learning = @user_course_identity == Course::STUDENT && @subject&.learning?(current_user.id) + @start_learning = @user_course_identity == Course::STUDENT && @course.learning?(current_user.id) end def search_course_list @@ -708,6 +710,7 @@ class CoursesController < ApplicationController def students search = params[:search].present? ? params[:search].strip : nil order = params[:order].present? ? params[:order].to_i : 0 + sort = params[:sort].present? ? params[:sort] : "desc" course_group_id = params[:course_group_id].present? ? params[:course_group_id].to_i : nil @students = CourseMember.students(@course) @@ -719,12 +722,12 @@ class CoursesController < ApplicationController if order == 1 # REDO:Extension - @students = @students.includes(user: :user_extension).order("user_extensions.student_id, users.login") + @students = @students.includes(user: :user_extension).order("user_extensions.student_id #{sort}, users.login #{sort}") elsif order == 2 - @students = @students.includes(:course_group).order("course_groups.position, users.login") + @students = @students.includes(:course_group).order("course_groups.position #{sort}, users.login #{sort}") else # REDO:Extension - @students = @students.includes(user: :user_extension).order("user_extensions.student_id, users.login") + @students = @students.includes(user: :user_extension).order("user_extensions.student_id #{sort}, users.login #{sort}") end if course_group_id.present? diff --git a/app/controllers/subjects_controller.rb b/app/controllers/subjects_controller.rb index 7c76748b1..952301053 100644 --- a/app/controllers/subjects_controller.rb +++ b/app/controllers/subjects_controller.rb @@ -442,7 +442,6 @@ class SubjectsController < ApplicationController # 用户进展和获取的标签 def user_subject_progress challenge_ids pass_games = Game.select(:id, :cost_time, :challenge_id).where(status: 2, user_id: current_user.id, challenge_id: challenge_ids) if current_user.logged? - @all_score = Challenge.where(id: challenge_ids).sum(:score) # 如果没有通关的,没必要再继续统计了 if pass_games.blank? @@ -451,6 +450,7 @@ class SubjectsController < ApplicationController @time = 0 @user_tags = [] else + @all_score = Challenge.where(id: challenge_ids).size pass_challenge_ids = pass_games.map(&:challenge_id).uniq # 按道理是不用去重的,但是历史数据与重复 subject_challenge_count = @subject.shixuns.sum(:challenges_count) # 用户通关获得的标签 @@ -460,7 +460,7 @@ class SubjectsController < ApplicationController subject_challenge_count == 0 ? 0 : ((pass_challenge_ids.size.to_f / subject_challenge_count).round(2) * 100).to_i # 用户通关分数 - @my_score = Challenge.where(id: pass_challenge_ids).pluck(:score).sum + @my_score = Challenge.where(id: pass_challenge_ids).size @time = pass_games.map(&:cost_time).sum end diff --git a/app/helpers/admins/base_helper.rb b/app/helpers/admins/base_helper.rb index 0da80f5f6..d79456ac8 100644 --- a/app/helpers/admins/base_helper.rb +++ b/app/helpers/admins/base_helper.rb @@ -103,4 +103,8 @@ module Admins::BaseHelper def unsafe_params params.except(:controller, :action).to_unsafe_h end + + def list_index_no(page,index) + (page - 1) * 20 + index + 1 + end end \ No newline at end of file diff --git a/app/helpers/course_stages_helper.rb b/app/helpers/course_stages_helper.rb new file mode 100644 index 000000000..7ebb68d9a --- /dev/null +++ b/app/helpers/course_stages_helper.rb @@ -0,0 +1,2 @@ +module CourseStagesHelper +end diff --git a/app/helpers/courses_helper.rb b/app/helpers/courses_helper.rb index cdb3225d6..6f6c76d04 100644 --- a/app/helpers/courses_helper.rb +++ b/app/helpers/courses_helper.rb @@ -269,10 +269,10 @@ module CoursesHelper group_info end - def last_subject_shixun user_id, subject - myshixun = Myshixun.where(user_id: user_id, shixun_id: subject&.shixuns).order("updated_at desc").first + def last_subject_shixun user_id, course + myshixun = Myshixun.where(user_id: user_id, shixun_id: course.shixuns).order("updated_at desc").first return "" unless myshixun - stage_shixun = subject&.stage_shixuns.where(shixun_id: myshixun.shixun_id).take - progress = stage_shixun&.stage&.position.to_s + "-" + stage_shixun&.position.to_s + " " + myshixun.shixun&.name + stage_shixun = course.course_stage_shixuns.where(shixun_id: myshixun.shixun_id).take + progress = stage_shixun&.course_stage&.position.to_s + "-" + stage_shixun&.position.to_s + " " + myshixun.shixun&.name end end diff --git a/app/models/course.rb b/app/models/course.rb index 54d897b07..c66c597d4 100644 --- a/app/models/course.rb +++ b/app/models/course.rb @@ -70,6 +70,11 @@ class Course < ApplicationRecord has_many :course_acts, class_name: 'CourseActivity', as: :course_act, dependent: :destroy has_many :tidings, as: :container, dependent: :destroy + # 开放课堂 + has_many :course_stages, -> { order("course_stages.position ASC") }, dependent: :destroy + has_many :course_stage_shixuns, dependent: :destroy + has_many :shixuns, through: :course_stage_shixuns + # 老版的members弃用 现用course_members has_many :members @@ -333,6 +338,28 @@ class Course < ApplicationRecord teacher_power_courses end + def create_stages subject + if subject + subject.stages.each do |stage| + new_stage = CourseStage.create!(course_id: id, name: stage.name, description: stage.description, position: stage.position) + stage.stage_shixuns.each do |stage_shixun| + CourseStageShixun.create!(course_id: id, course_stage_id: new_stage.id, shixun_id: stage_shixun.shixun_id, position: stage_shixun.position) + end + end + end + end + + def learning? user_id + Myshixun.where(user_id: user_id, shixun_id: shixuns).exists? + end + + def my_subject_progress + my_challenge_count = Game.joins(:challenge).where(user_id: User.current.id, status: 2, challenges: {shixun_id: shixuns.published_closed}). + pluck(:challenge_id).uniq.size + course_challeng_count = course.shixuns.pluck(:challenges_count).sum + count = course_challeng_count == 0 ? 0 : ((my_challenge_count.to_f / course_challeng_count).round(2) * 100).to_i + end + private #创建课程后,给该用户发送消息 diff --git a/app/models/course_stage.rb b/app/models/course_stage.rb new file mode 100644 index 000000000..f105e25f6 --- /dev/null +++ b/app/models/course_stage.rb @@ -0,0 +1,9 @@ +class CourseStage < ApplicationRecord + belongs_to :course + + has_many :course_stage_shixuns, -> { order("course_stage_shixuns.position ASC") }, dependent: :destroy + has_many :shixuns, :through => :course_stage_shixuns + + validates :name, length: { maximum: 60 } + validates :description, length: { maximum: 300 } +end diff --git a/app/models/course_stage_shixun.rb b/app/models/course_stage_shixun.rb new file mode 100644 index 000000000..6ab2707a4 --- /dev/null +++ b/app/models/course_stage_shixun.rb @@ -0,0 +1,5 @@ +class CourseStageShixun < ApplicationRecord + belongs_to :course + belongs_to :course_stage, counter_cache: :shixuns_count + belongs_to :shixun +end diff --git a/app/models/ec_discipline.rb b/app/models/ec_discipline.rb new file mode 100644 index 000000000..449098ce1 --- /dev/null +++ b/app/models/ec_discipline.rb @@ -0,0 +1,12 @@ +class EcDiscipline < ActiveRecord::Base + validates_presence_of :code, :name + + has_many :ec_discipline_firsts + + # 专业数目 + def major_count + count = 0 + self.ec_discipline_firsts.map{|f| count += f.ec_majors.count} + count + end +end diff --git a/app/models/ec_discipline_first.rb b/app/models/ec_discipline_first.rb new file mode 100644 index 000000000..7c111d2c9 --- /dev/null +++ b/app/models/ec_discipline_first.rb @@ -0,0 +1,6 @@ +class EcDisciplineFirst < ActiveRecord::Base + validates_presence_of :code, :name + + has_many :ec_majors + belongs_to :ec_discipline +end diff --git a/app/models/ec_major.rb b/app/models/ec_major.rb index 4842f7d70..ae854a4c8 100644 --- a/app/models/ec_major.rb +++ b/app/models/ec_major.rb @@ -1,7 +1,10 @@ class EcMajor < ApplicationRecord # 主页对应的学校,不同学校可以选用同样的专业,而每个专业又各具特色 - has_many :schools, through: :ec_major_schools has_many :ec_major_schools, dependent: :destroy + has_many :schools, through: :ec_major_schools + + # 一级专业 + belongs_to :ec_discipline_first scope :search_name_or_code, -> (keyword) { where('name LIKE :keyword OR code LIKE :keyword', keyword: "%#{keyword.strip}%") } end diff --git a/app/services/users/apply_professional_auth_service.rb b/app/services/users/apply_professional_auth_service.rb index 07afe18ae..3ba9fbafd 100644 --- a/app/services/users/apply_professional_auth_service.rb +++ b/app/services/users/apply_professional_auth_service.rb @@ -38,7 +38,11 @@ class Users::ApplyProfessionalAuthService < ApplicationService move_image_file! unless params[:upload_image].to_s == 'false' - sms_notify_admin + # sms_cache = Rails.cache.read("apply_pro_certification") + # if sms_cache.nil? + # sms_notify_admin + Rails.cache.write("apply_pro_certification", 1) + # end end end diff --git a/app/views/admins/auth_schools/add_manager.js.erb b/app/views/admins/auth_schools/add_manager.js.erb new file mode 100644 index 000000000..d0abab3ac --- /dev/null +++ b/app/views/admins/auth_schools/add_manager.js.erb @@ -0,0 +1,6 @@ +if($(".auth-schools-user-add").length > 0){ + $(".auth-schools-user-add").modal("hide") +} +<% if @school_users.size > 0 %> + $("#table-school-<%= @school_id %>").find(".school_user_list").html("<%= j render partial: "admins/auth_schools/shared/school_user_list", locals: {users: @school_users, school_id: @school_id} %> ") +<% end %> diff --git a/app/views/admins/auth_schools/add_school.js.erb b/app/views/admins/auth_schools/add_school.js.erb new file mode 100644 index 000000000..c4de6e795 --- /dev/null +++ b/app/views/admins/auth_schools/add_school.js.erb @@ -0,0 +1,2 @@ +$(".auth-schools-list-container").html("<%= j render partial: "admins/auth_schools/shared/list", locals: {schools: @schools} %>") +$(".auth-schools-new-add").modal("hide") diff --git a/app/views/admins/auth_schools/destroy.js.erb b/app/views/admins/auth_schools/destroy.js.erb new file mode 100644 index 000000000..9500aacf1 --- /dev/null +++ b/app/views/admins/auth_schools/destroy.js.erb @@ -0,0 +1 @@ +$("#table-school-<%= params[:id] %>").remove() diff --git a/app/views/admins/auth_schools/index.html.erb b/app/views/admins/auth_schools/index.html.erb new file mode 100644 index 000000000..5f0f5e46b --- /dev/null +++ b/app/views/admins/auth_schools/index.html.erb @@ -0,0 +1,14 @@ +<% define_admin_breadcrumbs do %> + <% add_admin_breadcrumb('认证单位列表') %> +<% end %> + +
没有相关的单位
+ <% end %> +没有相关的单位
+ <% end %> +序号 | +学校名称 | +学校管理员 | +操作 | + + + <% if schools.size > 0 %> + <% schools.each_with_index do |school, index| %> +
---|---|---|---|
<%= list_index_no(@params_page.to_i, index) %> | ++ <%= link_to "#{school.name}", "/ecs/department?school_id=#{school.id}", target: "_blank" %> + | +
+
+ <%= link_to "".html_safe, "javascript:void(0)", class: "action", onclick: "show_add_manager('#{school.id}')" %>
+
+
+ <% if school.users.size > 0 %>
+ <%= render partial: "admins/auth_schools/shared/school_user_list", locals: {users: school.users, school_id: school.id} %>
+ <% end %>
+
+ |
+ + <%= link_to "".html_safe, admins_auth_school_path(school), method: :delete, data: {confirm: "确认删除吗?"}, remote: true %> + | +
一级学科代码 | +一级学科名称 | +专业代码 | +专业名称 | +认证学校数量 | + + + <% d.ec_discipline_firsts.each do |f| %> + <% f.ec_majors.each_with_index do |m, index| %> +
---|---|---|---|---|
<%= index == 0 ? f.code : "" %> | +<%= index == 0 ? f.name : "" %> | +<%= m.code %> | +<%= m.name %> | +<%= m.schools.size.to_i %> | +