diff --git a/Gemfile b/Gemfile index 7a37b7c44..55030971d 100644 --- a/Gemfile +++ b/Gemfile @@ -20,6 +20,8 @@ gem 'bootsnap', '>= 1.1.0', require: false gem 'gitlab', path: 'lib/gitlab-cli' +gem 'chinese_pinyin' + gem 'rack-cors' gem 'redis-rails' gem 'roo-xls' @@ -48,7 +50,6 @@ gem 'rqrcode_png' gem 'acts-as-taggable-on', '~> 6.0' group :development, :test do - gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] gem 'rspec-rails', '~> 3.8' end diff --git a/app/assets/javascripts/admins/courses/index.js b/app/assets/javascripts/admins/courses/index.js new file mode 100644 index 000000000..336d8c7c9 --- /dev/null +++ b/app/assets/javascripts/admins/courses/index.js @@ -0,0 +1,57 @@ +$(document).on('turbolinks:load', function() { + if ($('body.admins-courses-index-page').length > 0) { + let searchContainer = $(".course-list-form"); + let searchForm = $("form.search-form",searchContainer); + + searchContainer.on('change', '.course-homepage-show', function(){ + searchForm.find('input[type="submit"]').trigger('click'); + }); + + //导出 + searchContainer.on('click', "#course-export", function () { + window.location.href = "/admins/courses.xlsx?" + searchForm.serialize(); + }); + + $(".course-list-container").on("change", '.course-setting-form', function () { + var s_id = $(this).attr("data-id"); + var s_value = $(this).val(); + var s_name = $(this).attr("name"); + var json = {}; + json[s_name] = s_value; + $.ajax({ + url: "/admins/courses/" + s_id, + type: "PUT", + dataType:'script', + data: json + }); + }); + + // ************** 学校选择 ************* + searchForm.find('.school-select').select2({ + theme: 'bootstrap4', + placeholder: '请选择单位', + minimumInputLength: 1, + ajax: { + delay: 500, + url: '/api/schools/search.json', + dataType: 'json', + data: function (params) { + return {keyword: params.term}; + }, + processResults: function (data) { + return {results: data.schools} + } + }, + templateResult: function (item) { + if (!item.id || item.id === '') return item.text; + return item.name; + }, + templateSelection: function (item) { + if (item.id) { + } + return item.name || item.text; + } + }); + } +}); + diff --git a/app/assets/javascripts/admins/laboratories/index.js b/app/assets/javascripts/admins/laboratories/index.js index 689910446..ec559cb92 100644 --- a/app/assets/javascripts/admins/laboratories/index.js +++ b/app/assets/javascripts/admins/laboratories/index.js @@ -160,5 +160,16 @@ $(document).on('turbolinks:load', function() { $addMemberModal.modal('hide'); } }); + + $(".laboratory-list-container").on("change", '.laboratory-sync-course', function () { + var s_id = $(this).attr("data-id"); + var json = {}; + $.ajax({ + url: "/admins/laboratories/" + s_id + "/update_sync_course", + type: "POST", + dataType:'script', + data: json + }) + }); } }); \ No newline at end of file diff --git a/app/assets/javascripts/admins/modals/admin-merge-course-list-modal.js b/app/assets/javascripts/admins/modals/admin-merge-course-list-modal.js new file mode 100644 index 000000000..e08277024 --- /dev/null +++ b/app/assets/javascripts/admins/modals/admin-merge-course-list-modal.js @@ -0,0 +1,60 @@ +$(document).on('turbolinks:load', function() { + var $modal = $('.modal.admin-merge-course-list-modal'); + if ($modal.length > 0) { + var $form = $modal.find('form.admin-merge-course-list-form'); + var $originCourseListIdInput = $form.find('input[name="origin_course_list_id"]'); + + $form.validate({ + errorElement: 'span', + errorClass: 'danger text-danger', + rules: { + course_list_name: { + required: true + } + }, + messages: { + course_list_name: { + required: '请输入课程名称' + } + } + }); + + // modal ready fire + $modal.on('show.bs.modal', function (event) { + var $link = $(event.relatedTarget); + + var couresListId = $link.data('courseListId'); + var url = $link.data('url'); + + $originCourseListIdInput.val(couresListId); + $form.data('url', url); + }); + + $modal.on('click', '.submit-btn', function(){ + $form.find('.error').html(''); + + if ($form.valid()) { + var url = $form.data('url'); + + $.ajax({ + method: 'POST', + dataType: 'json', + url: url, + data: $form.serialize(), + success: function(){ + $.notify({ message: '操作成功' }); + $modal.modal('hide'); + + setTimeout(function(){ + window.location.reload(); + }, 500); + }, + error: function(res){ + var data = res.responseJSON; + $form.find('.error').html(data.message); + } + }); + } + }); + } +}); \ No newline at end of file diff --git a/app/assets/javascripts/admins/shixun_feedback_messages/index.js b/app/assets/javascripts/admins/shixun_feedback_messages/index.js new file mode 100644 index 000000000..c0b32ba32 --- /dev/null +++ b/app/assets/javascripts/admins/shixun_feedback_messages/index.js @@ -0,0 +1,22 @@ +$(document).on('turbolinks:load', function(){ + if ($('body.admins-shixun-feedback-messages-index-page').length > 0) { + + var baseOptions = { + autoclose: true, + language: 'zh-CN', + format: 'yyyy-mm-dd 00:00:00', + 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'); + } +}) \ No newline at end of file diff --git a/app/assets/javascripts/admins/shixun_settings/index.js b/app/assets/javascripts/admins/shixun_settings/index.js index 8b3eee505..ece7b3233 100644 --- a/app/assets/javascripts/admins/shixun_settings/index.js +++ b/app/assets/javascripts/admins/shixun_settings/index.js @@ -12,6 +12,11 @@ $(document).on('turbolinks:load', function() { window.location.href = "/admins/shixun_settings.xls?" + searchForm.serialize(); }); + // 基础数据导出 + searchContainer.on('click', "#shixun-settings-base-export", function () { + window.location.href = "/admins/shixun_settings.xls?base_data=1" + searchForm.serialize(); + }); + $(".shixun-settings-list-container").on("change", '.shixun-setting-form', function () { var s_id = $(this).attr("data-id"); var s_value = $(this).val(); diff --git a/app/assets/stylesheets/admin.scss b/app/assets/stylesheets/admin.scss index 756a5e241..a401fc379 100644 --- a/app/assets/stylesheets/admin.scss +++ b/app/assets/stylesheets/admin.scss @@ -53,3 +53,8 @@ input.form-control { position: absolute; } +.export-base-absolute{ + right:100px; + position: absolute; +} + diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb index 2d1b39590..f03cbdef8 100644 --- a/app/controllers/accounts_controller.rb +++ b/app/controllers/accounts_controller.rb @@ -60,7 +60,7 @@ class AccountsController < ApplicationController ua = UserAgent.find_by_ip(ip) ua.update_column(:agent_type, UserAgent::USER_REGISTER) if ua successful_authentication(@user) - session[:user_id] = @user.id + # session[:user_id] = @user.id normal_status("注册成功") end rescue Exception => e @@ -94,7 +94,7 @@ class AccountsController < ApplicationController successful_authentication(@user) login_control.clear # 重置每日密码错误次数 - session[:user_id] = @user.id + # session[:user_id] = @user.id end # 忘记密码 @@ -127,7 +127,7 @@ class AccountsController < ApplicationController end end - def successful_authentication(user) + def successful_authentication(user) uid_logger("Successful authentication start: '#{user.login}' from #{request.remote_ip} at #{Time.now.utc}") # Valid user self.logged_user = user @@ -136,6 +136,7 @@ class AccountsController < ApplicationController set_autologin_cookie(user) UserAction.create(:action_id => user.try(:id), :action_type => "Login", :user_id => user.try(:id), :ip => request.remote_ip) user.update_column(:last_login_on, Time.now) + session[:"#{default_yun_session}"] = user.id # 注册完成后有一天的试用申请(先去掉) # UserDayCertification.create(user_id: user.id, status: 1) end @@ -158,7 +159,6 @@ class AccountsController < ApplicationController def logout UserAction.create(action_id: User.current.id, action_type: "Logout", user_id: User.current.id, :ip => request.remote_ip) - session[:user_id] = nil logout_user render :json => {status: 1, message: "退出成功!"} end diff --git a/app/controllers/admins/course_lists_controller.rb b/app/controllers/admins/course_lists_controller.rb new file mode 100644 index 000000000..83ac92c61 --- /dev/null +++ b/app/controllers/admins/course_lists_controller.rb @@ -0,0 +1,35 @@ +class Admins::CourseListsController < Admins::BaseController + + def index + course_lists = Admins::CourseListQuery.call(params) + @course_lists = paginate course_lists.preload(:courses, :user) + @params_page = params[:page] || 1 + respond_to do |format| + format.js + format.html + end + end + + def destroy + CourseList.find(params[:id]).destroy! + + render_delete_success + end + + def merge + origin_course_list = CourseList.find_by!(id: params[:origin_course_list_id]) + o_courselist = CourseList.find_by(name: params[:course_list_name]) + if o_courselist + origin_course_list.courses.each do |course| + course.update!(name: course.name.sub(origin_course_list.name, params[:course_list_name]), course_list_id: o_courselist.id) + end + origin_course_list.destroy + else + origin_course_list.courses.each do |course| + course.update!(name: course.name.sub(origin_course_list.name, params[:course_list_name])) + end + origin_course_list.update!(name: params[:course_list_name]) + end + render_ok + end +end \ No newline at end of file diff --git a/app/controllers/admins/courses_controller.rb b/app/controllers/admins/courses_controller.rb new file mode 100644 index 000000000..80f48fab2 --- /dev/null +++ b/app/controllers/admins/courses_controller.rb @@ -0,0 +1,49 @@ +class Admins::CoursesController < Admins::BaseController + before_action :find_course, except: [:index] + + def index + default_sort('created_at', 'desc') + + courses = Admins::CourseQuery.call(params) + @ended_courses = courses.where(is_end: 1).size + @processed_courses = courses.where(is_end: 0).size + @courses = paginate courses.includes(:school, :students, :attachments, :homework_commons, teacher: :user_extension) + + respond_to do |format| + format.js + format.html + format.xlsx do + @courses = courses.includes(:school, :students, :attachments, :homework_commons, :course_acts, teacher: :user_extension) + filename = "课堂列表_#{Time.current.strftime('%Y%m%d%H%M%S')}.xlsx" + render xlsx: 'index', filename: filename + end + end + end + + def destroy + if @course.is_delete == 0 + @course.delete! + Tiding.create!(user_id: current_user.id, trigger_user_id: current_user.id, container_id: @course.id, + container_type: 'DeleteCourse', tiding_type: 'System', belong_container: @course, extra: @course.name) + end + end + + def update + if @course.update_attributes(setting_params) + render_ok + else + redirect_to admins_courses_path + flash[:danger] = "更新失败" + end + end + + private + + def find_course + @course = Course.find_by!(id: params[:id]) + end + + def setting_params + params.permit(:homepage_show, :email_notify) + end +end \ No newline at end of file diff --git a/app/controllers/admins/laboratories_controller.rb b/app/controllers/admins/laboratories_controller.rb index 716275468..6bd068a66 100644 --- a/app/controllers/admins/laboratories_controller.rb +++ b/app/controllers/admins/laboratories_controller.rb @@ -50,6 +50,17 @@ class Admins::LaboratoriesController < Admins::BaseController @subjects = paginate(subjects.includes(:user)) end + def synchronize_user + school = current_laboratory.school + users = User.joins(:user_extension).where(user_extensions: {school_id: school.id}) + users.update_all(laboratory_id: current_laboratory.id) + end + + def update_sync_course + current_laboratory.update!(sync_course: !current_laboratory.sync_course) + @laboratory = current_laboratory + end + private def current_laboratory diff --git a/app/controllers/admins/laboratory_subjects_controller.rb b/app/controllers/admins/laboratory_subjects_controller.rb index 866a20a76..827645839 100644 --- a/app/controllers/admins/laboratory_subjects_controller.rb +++ b/app/controllers/admins/laboratory_subjects_controller.rb @@ -17,9 +17,15 @@ class Admins::LaboratorySubjectsController < Admins::BaseController def destroy return render_js_error('不能删除自建课程', type: :notify) if current_laboratory_subject.ownership? - current_laboratory_subject.destroy! - - render_delete_success + ActiveRecord::Base.transaction do + current_subject = current_laboratory_subject.subject + # 实训软删除,并解除与子站的关联 + current_laboratory.laboratory_shixuns.where(shixun_id: current_subject.shixuns).destroy_all + current_subject.shixuns.update_all(status: -1) + current_subject.destroy! + + render_delete_success + end end diff --git a/app/controllers/admins/projects_controller.rb b/app/controllers/admins/projects_controller.rb new file mode 100644 index 000000000..53d94fd9b --- /dev/null +++ b/app/controllers/admins/projects_controller.rb @@ -0,0 +1,25 @@ +class Admins::ProjectsController < Admins::BaseController + + def index + default_sort('created_at', 'desc') + + search = params[:search].to_s.strip + projects = Project.where("name like ?", "%#{search}%") + @projects = paginate projects.includes(:owner, :members, :issues, :versions, :attachments, :project_score) + end + + def destroy + project = Project.find_by!(id: params[:id]) + ActiveRecord::Base.transaction do + g = Gitlab.client + g.delete_project(project.gpid) + # 删除Trustie版本库记录 + repoisitory = Repository.where(project_id: project.id, type: "Repository::Gitlab").first + repoisitory.destroy! + Tiding.where(container_id: project.id, container_type: ["JoinProject", "DealProject", "ReporterJoinProject", "ManagerJoinProject"]).destroy_all + project.destroy! + render_delete_success + end + end + +end \ No newline at end of file diff --git a/app/controllers/admins/schools_controller.rb b/app/controllers/admins/schools_controller.rb index 8c4f1d59e..7e1626d98 100644 --- a/app/controllers/admins/schools_controller.rb +++ b/app/controllers/admins/schools_controller.rb @@ -5,7 +5,7 @@ class Admins::SchoolsController < Admins::BaseController schools = Admins::SchoolQuery.call(params) - @schools = paginate schools + @schools = paginate schools.includes(:user_extensions) school_ids = @schools.map(&:id) @department_count = Department.where(school_id: school_ids).group(:school_id).count diff --git a/app/controllers/admins/shixun_feedback_messages_controller.rb b/app/controllers/admins/shixun_feedback_messages_controller.rb new file mode 100644 index 000000000..09aa465bd --- /dev/null +++ b/app/controllers/admins/shixun_feedback_messages_controller.rb @@ -0,0 +1,22 @@ +class Admins::ShixunFeedbackMessagesController < Admins::BaseController + + def index + @params_page = params[:page] || 1 + if params[:keyword].present? + discusses = Discuss.joins("LEFT JOIN shixuns ON discusses.dis_id = shixuns.id AND dis_type = 'Shixun'") + .where("shixuns.name like ?", "%#{params[:keyword]}%") + else + discusses = Discuss.where(:dis_type => 'Shixun').includes(:user, :dis) + end + + if params[:begin_date].present? + discusses = discusses.where("discusses.created_at > ?", params[:begin_date]) + end + + if params[:end_date].present? + discusses = discusses.where("discusses.created_at < ?", params[:end_date]) + end + + @discusses = paginate discusses.order("created_at desc") + end +end \ No newline at end of file diff --git a/app/controllers/admins/shixun_recycles_controller.rb b/app/controllers/admins/shixun_recycles_controller.rb new file mode 100644 index 000000000..5a0582d4e --- /dev/null +++ b/app/controllers/admins/shixun_recycles_controller.rb @@ -0,0 +1,22 @@ +class Admins::ShixunRecyclesController < Admins::BaseController + + def index + sort_by = params[:sort_by].presence || 'created_at' + sort_direction = params[:sort_direction].presence || 'desc' + search = params[:search].to_s.strip + shixuns = Shixun.where(status: -1).where("name like ?", "%#{search}%").order("#{sort_by} #{sort_direction}") + @shixuns = paginate shixuns.preload(:user, :laboratory) + end + + def destroy + Shixun.find(params[:id]).destroy! + + render_delete_success + end + + def resume + Shixun.find(params[:id]).update!(status: 0) + render_delete_success + end + +end diff --git a/app/controllers/admins/shixun_settings_controller.rb b/app/controllers/admins/shixun_settings_controller.rb index d635ae8df..bd54018cd 100644 --- a/app/controllers/admins/shixun_settings_controller.rb +++ b/app/controllers/admins/shixun_settings_controller.rb @@ -28,7 +28,13 @@ class Admins::ShixunSettingsController < Admins::BaseController format.html format.xls{ filename = "实训详情_#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}.xls" - send_data(shixun_list_xls(shixun_settings), :type => 'application/octet-stream', :filename => filename_for_content_disposition(filename)) + export_url = + if params[:base_data].present? + shixun_base_list_xls(shixun_settings) + else + shixun_list_xls(shixun_settings) + end + send_data(export_url, :type => 'application/octet-stream', :filename => filename_for_content_disposition(filename)) } end @@ -65,19 +71,20 @@ class Admins::ShixunSettingsController < Admins::BaseController sheet1.row(0).default_format = blue sheet1.row(0).concat(["实训ID","实训名称","技术平台", "Fork源", "实践任务","选择题任务","挑战人数", "通关人数", "状态","创建者", "单位", "职业", "关卡序号","关卡名称","技能标签"]) count_row = 1 - shixuns.find_each do |shixun| + shixuns.includes(:fork_shixuns, :myshixuns, :mirror_repositories, challenges: [:challenge_tags], user: [user_extension: :school]).find_each do |shixun| sheet1[count_row, 0] = shixun.identifier sheet1[count_row, 1] = shixun.name - sheet1[count_row, 2] = shixun.shixun_main_name + sheet1[count_row, 2] = shixun.mirror_repositories.select{|mr| mr.main_type == "1"}.first&.type_name + sheet1[count_row, 3] = shixun.fork_identifier - sheet1[count_row, 4] = shixun.challenges.practice_type.count - sheet1[count_row, 5] = shixun.challenges.choose_type.count - sheet1[count_row, 6] = shixun.myshixuns.count - sheet1[count_row, 7] = shixun.myshixuns.finished.count + sheet1[count_row, 4] = shixun.challenges.select{|c| c.st == 0}.size + sheet1[count_row, 5] = shixun.challenges.select{|c| c.st == 1}.size + sheet1[count_row, 6] = shixun.myshixuns_count + sheet1[count_row, 7] = shixun.myshixuns.select{|m| m.status == 1}.size sheet1[count_row, 8] = shixun.shixun_status - sheet1[count_row, 9] = shixun.owner.show_real_name - sheet1[count_row, 10] = shixun.owner.school_name - sheet1[count_row, 11] = shixun.owner.identity + sheet1[count_row, 9] = shixun.user.show_real_name + sheet1[count_row, 10] = shixun.user.school_name + sheet1[count_row, 11] = shixun.user.identity shixun.challenges.each do |challenge| sheet1[count_row, 12] = "第#{challenge.position}关" sheet1[count_row, 13] = challenge.subject @@ -90,6 +97,34 @@ class Admins::ShixunSettingsController < Admins::BaseController xls_report.string end + def shixun_base_list_xls shixuns + xls_report = StringIO.new + book = Spreadsheet::Workbook.new + sheet1 = book.create_worksheet :name => "sheet" + blue = Spreadsheet::Format.new :color => :blue, :weight => :bold, :size => 10 + sheet1.row(0).default_format = blue + sheet1.row(0).concat(["实训ID","实训名称","技术平台", "Fork源", "状态","创建者", "单位", "职业", "关卡序号","关卡名称"]) + count_row = 1 + shixuns.includes(:mirror_repositories, :challenges, user: [user_extension: :school]).find_each do |shixun| + sheet1[count_row, 0] = shixun.identifier + sheet1[count_row, 1] = shixun.name + sheet1[count_row, 2] = shixun.mirror_repositories.select{|mr| mr.main_type == "1"}.first&.type_name + sheet1[count_row, 3] = shixun.fork_from + sheet1[count_row, 4] = shixun.shixun_status + sheet1[count_row, 5] = shixun.user.show_real_name + sheet1[count_row, 6] = shixun.user.school_name + sheet1[count_row, 7] = shixun.user.identity + shixun.challenges.each do |challenge| + sheet1[count_row, 8] = "第#{challenge.position}关" + sheet1[count_row, 9] = challenge.subject + count_row += 1 + end + count_row += 1 + end + book.write xls_report + xls_report.string + end + def setting_params params.permit(:use_scope,:excute_time,:close,:status,:can_copy,:webssh,:hidden,:homepage_show,:task_pass,:code_hidden,:page_no, :id,tag_repertoires:[]) end diff --git a/app/controllers/admins/shixuns_controller.rb b/app/controllers/admins/shixuns_controller.rb index a4aa8a044..e2d2830ad 100644 --- a/app/controllers/admins/shixuns_controller.rb +++ b/app/controllers/admins/shixuns_controller.rb @@ -1,7 +1,7 @@ class Admins::ShixunsController < Admins::BaseController def index - params[:sort_by] = params[:sort_by].presence || 'created_on' + params[:sort_by] = params[:sort_by].presence || 'created_at' params[:sort_direction] = params[:sort_direction].presence || 'desc' shixuns = Admins::ShixunQuery.call(params) @editing_shixuns = shixuns.where(status:0).size @@ -23,7 +23,7 @@ class Admins::ShixunsController < Admins::BaseController end def destroy - Shixun.find(params[:id]).destroy! + Shixun.find(params[:id]).update!(status: -1) render_delete_success end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 1bc2bad7d..3ec8ad0f7 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -45,6 +45,13 @@ class ApplicationController < ActionController::Base check_account tip_exception(@course.excellent ? 410 : 409, "您没有权限进入") end + if @user_course_identity > Course::CREATOR && @user_course_identity <= Course::STUDENT + # 实名认证和职业认证的身份判断 + tip_exception(411, "你的实名认证和职业认证审核未通过") if @course.authentication && + @course.professional_certification && (!current_user.authentication && !current_user.professional_certification) + tip_exception(411, "你的实名认证审核未通过") if @course.authentication && !current_user.authentication + tip_exception(411, "你的职业认证审核未通过") if @course.professional_certification && !current_user.professional_certification + end uid_logger("###############user_course_identity:#{@user_course_identity}") end @@ -292,9 +299,11 @@ class ApplicationController < ActionController::Base # and starts a session if needed def find_current_user uid_logger("user setup start: session[:user_id] is #{session[:user_id]}") - if session[:user_id] + uid_logger("0000000000000user setup start: default_yun_session is #{default_yun_session}, session[:current_user_id] is #{session[:"#{default_yun_session}"]}") + current_domain_session = session[:"#{default_yun_session}"] + if current_domain_session # existing session - (User.active.find(session[:user_id]) rescue nil) + (User.active.find(current_domain_session) rescue nil) elsif autologin_user = try_to_autologin autologin_user elsif params[:format] == 'atom' && params[:key] && request.get? && accept_rss_auth? @@ -306,10 +315,10 @@ class ApplicationController < ActionController::Base def try_to_autologin if cookies[autologin_cookie_name] # auto-login feature starts a new session - user = User.try_to_autologin(cookies[autologin_cookie_name]) - if user - start_user_session(user) - end + user = nil + Rails.logger.info("111111111111111111#{default_yun_session}, session is #{session[:"#{default_yun_session}"]} ") + user = User.try_to_autologin(cookies[autologin_cookie_name]) if session[:"#{default_yun_session}"] + start_user_session(user) if user user end end @@ -395,25 +404,6 @@ class ApplicationController < ActionController::Base end end - # 处理返回非0就报错的请求 - def interface_post(uri, params, status, message) - begin - uid_logger_dubug("--uri_exec: params is #{params}, url is #{uri}") - uri = URI.parse(URI.encode(uri.strip)) - res = Net::HTTP.post_form(uri, params).body - uid_logger_dubug("--uri_exec: .....res is #{res}") - res = JSON.parse(res) - if (res && res['code'] != 0) - tip_exception(status, message) - else - res - end - rescue Exception => e - uid_logger("--uri_exec: exception #{e.message}") - raise Educoder::TipException.new("实训平台繁忙(繁忙等级:84)") - end - end - # json格式请求 def interface_json_post(uri, params, status, message) begin diff --git a/app/controllers/attachments_controller.rb b/app/controllers/attachments_controller.rb index da6e99418..0c9c49621 100644 --- a/app/controllers/attachments_controller.rb +++ b/app/controllers/attachments_controller.rb @@ -125,7 +125,7 @@ class AttachmentsController < ApplicationController end digest = md5_file(temp_file) - digest = "#{digest}_#{Time.now.to_i}" + digest = "#{digest}_#{(Time.now.to_f * 1000).to_i}" local_file_path = File.join(save_path, digest) + ext save_temp_file(temp_file, local_file_path) diff --git a/app/controllers/challenges_controller.rb b/app/controllers/challenges_controller.rb index c21a493e0..0b5140743 100644 --- a/app/controllers/challenges_controller.rb +++ b/app/controllers/challenges_controller.rb @@ -308,6 +308,7 @@ class ChallengesController < ApplicationController end def challenge_params + tip_exception("评测时间不能超过300秒") if params[:challenge][:exec_time].to_i > 300 params.require(:challenge).permit(:subject, :task_pass, :difficulty, :score, :st, :modify_time, :test_set_average, :path, :exec_path, :show_type, :original_picture_path, :test_set_score, :expect_picture_path, :picture_path, :web_route, :answer, :exec_time) diff --git a/app/controllers/competitions/competitions_controller.rb b/app/controllers/competitions/competitions_controller.rb index 72f53d1e2..5719f8f8b 100644 --- a/app/controllers/competitions/competitions_controller.rb +++ b/app/controllers/competitions/competitions_controller.rb @@ -125,7 +125,7 @@ class Competitions::CompetitionsController < Competitions::BaseController end @all_records = @competition.competition_teams.joins(:competition_scores).where(competition_scores: {competition_stage_id: @stage&.id.to_i}) - .select("competition_teams.*, score, cost_time").order("score desc, cost_time desc") + .select("competition_teams.*, score, cost_time").order("score desc, cost_time asc") current_team_ids = @competition.team_members.where(user_id: current_user.id).pluck(:competition_team_id).uniq @user_ranks = @all_records.select{|com_team| current_team_ids.include?(com_team.id)} @@ -213,7 +213,7 @@ class Competitions::CompetitionsController < Competitions::BaseController if personal row_cells_column << record_user.real_name row_cells_column << record_user.school_name - row_cells_column << record_user.student_id.present? ? (record_user.student_id.to_s + "\t") : "--" + row_cells_column << (record_user.student_id.present? ? (record_user.student_id.to_s + "\t") : "--") else row_cells_column << record.name row_cells_column << record.teachers_name diff --git a/app/controllers/concerns/laboratory_helper.rb b/app/controllers/concerns/laboratory_helper.rb index 870a1d90e..e03273d68 100644 --- a/app/controllers/concerns/laboratory_helper.rb +++ b/app/controllers/concerns/laboratory_helper.rb @@ -6,6 +6,7 @@ module LaboratoryHelper helper_method :current_laboratory helper_method :default_setting + helper_method :default_yun_session end def current_laboratory @@ -23,4 +24,9 @@ module LaboratoryHelper def setup_laboratory Laboratory.current = current_laboratory end + + def default_yun_session + laboratory ||= (Laboratory.find_by_subdomain(request.subdomain) || Laboratory.find(1)) + @_default_yun_session = "#{laboratory.try(:identifier).split('.').first}_user_id" + end end \ No newline at end of file diff --git a/app/controllers/concerns/login_helper.rb b/app/controllers/concerns/login_helper.rb index e94cf8a21..ede7ff071 100644 --- a/app/controllers/concerns/login_helper.rb +++ b/app/controllers/concerns/login_helper.rb @@ -29,7 +29,7 @@ module LoginHelper Rails.logger.info("id: #{user&.id} Successful authentication start: '#{user.login}' from #{request.remote_ip} at #{Time.now.utc}") # Valid user self.logged_user = user - + session[:"#{default_yun_session}"] = user.id # generate a key and set cookie if autologin set_autologin_cookie(user) @@ -47,12 +47,16 @@ module LoginHelper User.current.delete_session_token(session[:tk]) self.logged_user = nil end - session[:user_id] = nil + # 云上实验室退出清理当前session + laboratory ||= (Laboratory.find_by_subdomain(request.subdomain) || Laboratory.find(1)) + default_yun_session = "#{laboratory.try(:identifier).split('.').first}_user_id" + # end + session[:"#{default_yun_session}"] = nil end # Sets the logged in user def logged_user=(user) - reset_session + # reset_session if user && user.is_a?(User) User.current = user start_user_session(user) @@ -62,7 +66,19 @@ module LoginHelper end def start_user_session(user) - session[:user_id] = user.id + # re_subdomain = "#{request.subdomain.split('.').first}_user_id" + # session[:"#{request.subdomain}_user_id"] = user.id + # Rails.logger.info("domain_user_id session is: 3333332222111#{session[:"#{request.subdomain}_user_id"]}") + # Rails.logger.info("user_id session is: 3333332222111#{session[:"#{request.subdomain}_user_id"]}") + # + # # if current_laboratory.main_site? + # # session[:user_id] = user.id + # # else + # # session[:"#{request.subdomain}_user_id"] = user.id + # # end + + # session[:user_id] = user.id + session[:"#{default_yun_session}"] = user.id session[:ctime] = Time.now.utc.to_i session[:atime] = Time.now.utc.to_i end diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb index 7e2432fc4..de24f7a8e 100644 --- a/app/controllers/courses_controller.rb +++ b/app/controllers/courses_controller.rb @@ -61,7 +61,7 @@ class CoursesController < ApplicationController @user = current_user # 根据分类查询课堂(全部,我的,最新,最热) @order = params[:order].present? ? params[:order] : "all" - @courses = current_laboratory.courses.not_deleted + @courses = current_laboratory.all_courses.not_deleted if @order == "visits" order_str = "courses.id = 1309 DESC, courses.visits DESC" @courses = @courses.where(is_hidden: 0) @@ -635,7 +635,7 @@ class CoursesController < ApplicationController teacher_member = CourseMember.create!(course_id: @course.id, user_id: params[:user_id], role: params[:roles].include?("PROFESSOR") ? 2 : 3) # 如果有未审批的申请教师/助教的记录,则修改状态为已审批 apply_teacher = CourseMessage.where(course_id: @course.id, course_message_id: params[:user_id], status: 0).last - apply_teacher.update!(status: 1, apply_user_id: current_user.id) + apply_teacher.update!(status: 1, apply_user_id: current_user.id) if apply_teacher.present? elsif course_members.exists?(role: %i[PROFESSOR ASSISTANT_PROFESSOR]) teacher_member = course_members.where(role: %i[PROFESSOR ASSISTANT_PROFESSOR]).take if params[:roles].include?("PROFESSOR") || params[:roles].include?("ASSISTANT_PROFESSOR") diff --git a/app/controllers/exercises_controller.rb b/app/controllers/exercises_controller.rb index fff320323..48554111c 100644 --- a/app/controllers/exercises_controller.rb +++ b/app/controllers/exercises_controller.rb @@ -610,7 +610,7 @@ class ExercisesController < ApplicationController # 对未提交的用户进行调分 def adjust_score exercise_user = @exercise.exercise_users.find_by!(user_id: params[:user_id]) - tip_exception("已提交的作品请去评阅页进行调分") if exercise_user.commit_status == 1 + tip_exception("已提交的作品请去评阅页进行调分") if exercise_user.commit_status == 1 && exercise_user.commit_method != 5 if @exercise.subjective_score > 0 tip_exception("主观题成绩不能为空") if params[:subjective_score].blank? tip_exception("主观题成绩不能小于零") if params[:subjective_score].to_f < 0 @@ -628,8 +628,13 @@ class ExercisesController < ApplicationController subjective_score = @exercise.subjective_score > 0 ? params[:subjective_score].to_f.round(2) : 0 objective_score = @exercise.objective_score > 0 ? params[:objective_score].to_f.round(2) : 0 score = subjective_score + objective_score - exercise_user.update_attributes!(start_at: start_at_time, end_at: Time.now, status: 1, commit_status: 1, score: score, - subjective_score: subjective_score, objective_score: objective_score, commit_method: 5) + if exercise_user.commit_status == 1 + exercise_user.update_attributes!(score: score, subjective_score: subjective_score, objective_score: objective_score) + else + exercise_user.update_attributes!(start_at: start_at_time, end_at: Time.now, status: 1, commit_status: 1, score: score, + subjective_score: subjective_score, objective_score: objective_score, commit_method: 5) + end + ExerciseUserScore.create!(exercise_id: @exercise.id, exercise_user_id: exercise_user.id, subjective_score: subjective_score, objective_score: objective_score) normal_status("操作成功") @@ -1760,19 +1765,12 @@ class ExercisesController < ApplicationController else ques_number = q.question_number end + ques_status = 0 if q.question_type != Exercise::PRACTICAL ques_vote = q.exercise_answers.select{|answer| answer.user_id == user_id} - else - ques_vote = q.exercise_shixun_answers.select{|answer| answer.user_id == user_id} - end - ques_status = 0 - if ques_vote.present? - if q.question_type == Exercise::PRACTICAL - if ques_vote.pluck(:exercise_shixun_challenge_id).sort == q.exercise_shixun_challenges.pluck(:id).sort #用户的总得分等于问题的分数 - ques_status = 1 #全部回答了,才算已答 - question_answered += 1 - end - else #其他题目,需回答的有内容,才会为已答,否则如内容为空,视为未答 + + if ques_vote.present? + #其他题目,需回答的有内容,才会为已答,否则如内容为空,视为未答 vote_answer_id = ques_vote.pluck(:exercise_choice_id).reject(&:blank?) vote_text_count = ques_vote.pluck(:answer_text).reject(&:blank?).size if q.question_type <= Exercise::JUDGMENT #选择题和判断题的时候,需要有选项,才算回答 @@ -1780,11 +1778,6 @@ class ExercisesController < ApplicationController ques_status = 1 question_answered += 1 end - elsif q.question_type == Exercise::COMPLETION #填空题的时候,需要有选项和内容,才算回答 - if vote_answer_id.uniq.sort == q.exercise_standard_answers.pluck(:exercise_choice_id).uniq.sort - ques_status = 1 - question_answered += 1 - end else if vote_text_count > 0 #主观题,必选有内容,才算回答 ques_status = 1 @@ -1792,6 +1785,11 @@ class ExercisesController < ApplicationController end end end + else + if Myshixun.exists?(user_id: user_id, shixun_id: q.shixun_id) + ques_status = 1 + question_answered += 1 + end end question_status = { :ques_id => q.id, diff --git a/app/controllers/files_controller.rb b/app/controllers/files_controller.rb index 117475894..0299fdf7d 100644 --- a/app/controllers/files_controller.rb +++ b/app/controllers/files_controller.rb @@ -24,26 +24,53 @@ class FilesController < ApplicationController get_category(@course, @course_second_category_id) @total_count = @attachments.size - @publish_count = @attachments.published.size - @unpublish_count = @total_count - @publish_count - @attachments = @attachments.by_keywords(params[:search]) - @attachments = - case @user.course_identity(@course) - when 5 - @attachments.published - when 6, 7 - @attachments.publiced.published + if @user.course_identity(@course) == 5 + member = @course.course_members.find_by(user_id: current_user.id, is_active: 1) + if member.try(:course_group_id).to_i == 0 + @attachments = @attachments.published.unified_setting else - @attachments + not_atta_ids = @course.attachment_group_settings.none_published.where("course_group_id = #{member.try(:course_group_id)}").pluck(:attachment_id) + + @attachments = @attachments.where.not(id: not_atta_ids).published end + elsif @user.course_identity(@course) > 5 + @attachments = @attachments.publiced.published + end + + @publish_count = @attachments.published.size + @unpublish_count = @total_count - @publish_count + @attachments = @attachments.by_keywords(params[:search]) @attachments = @attachments.page(@page).per(@page_size) end def bulk_publish return normal_status(403, "您没有权限进行操作") if current_user.course_identity(@course) >= 5 - @course.attachments.by_ids(@attachment_ids).unpublish.update_all(is_publish: 1, publish_time: Time.now) + tip_exception("请至少选择一个分班") if params[:group_ids].blank? && @course.course_groups.size != 0 + + attachments = @course.attachments.by_ids(@attachment_ids) + + ActiveRecord::Base.transaction do + # 有分班设置时 + if @course.course_group_module? && @course.course_groups_count != 0 && params[:group_ids] + group_ids = params[:group_ids]&.reject(&:blank?) + charge_group_ids = @course.charge_group_ids(current_user) + publish_groups = charge_group_ids & group_ids if group_ids + + attachments.each do |atta| + if atta.published? && !atta.unified_setting || !atta.published? + create_atta_group_settings atta + atta.update_all(unified_setting: 0) if atta.unified_setting + none_publish_settings = atta.attachment_group_settings.where(course_group_id: publish_groups).none_published + none_publish_settings.update_all(publish_time: Time.now) + end + end + end + + # 未发布的资源更新状态 + attachments.where(is_publish: 0).update_all(is_publish: 1, publish_time: Time.now) + end render_ok end @@ -153,6 +180,10 @@ class FilesController < ApplicationController attachment.is_publish = @atta_is_publish attachment.delay_publish = @atta_delay_publish attachment.publish_time = @atta_publish_time + attachment.unified_setting = @unified_setting + if @unified_setting == 0 + attachment_group_setting attachment, params[:group_settings] + end # attachment.set_publish_time(publish_time) if is_unified_setting # attachment.set_course_group_publish_time(@course, course_group_publish_times) if @course.course_groups.size > 0 && !is_unified_setting && publish_time.blank? attachment.save! @@ -195,6 +226,10 @@ class FilesController < ApplicationController attach_copied_obj.is_publish = @atta_is_publish attach_copied_obj.delay_publish = @atta_delay_publish attach_copied_obj.publish_time = @atta_publish_time + attach_copied_obj.unified_setting = @unified_setting + if @unified_setting == 0 + attachment_group_setting attach_copied_obj, params[:group_settings] + end attach_copied_obj.course_second_category_id = course_second_category_id attach_copied_obj.copy_from = ori.copy_from.nil? ? ori.id : ori.copy_from if attach_copied_obj.attachtype == nil @@ -234,6 +269,12 @@ class FilesController < ApplicationController @old_attachment.is_publish = @atta_is_publish @old_attachment.delay_publish = @atta_delay_publish @old_attachment.publish_time = @atta_publish_time + @old_attachment.unified_setting = @unified_setting + if @unified_setting == 0 + attachment_group_setting @old_attachment, params[:group_settings] + else + @old_attachment.attachment_group_settings.destroy_all + end if params[:description] && !params[:description].strip.blank? && params[:description] != @old_attachment.description @old_attachment.description = params[:description] @@ -319,9 +360,40 @@ class FilesController < ApplicationController def publish_params tip_exception("缺少发布参数") if params[:delay_publish].blank? - tip_exception("缺少延期发布的时间参数") if params[:delay_publish].to_i == 1 && params[:publish_time].blank? - @atta_is_publish = params[:delay_publish].to_i == 1 && params[:publish_time].to_time > Time.now ? 0 : 1 + @unified_setting = 1 + if params[:delay_publish].to_i == 1 && @course.course_group_module? && @course.course_groups_count != 0 + tip_exception("分班发布设置不能为空") if params[:group_settings].blank? + min_publish_time = params[:group_settings].pluck(:publish_time).reject(&:blank?).min + max_publish_time = params[:group_settings].pluck(:publish_time).reject(&:blank?).max + tip_exception("分班发布设置不能为空") if min_publish_time.blank? + + # 分班设置中的时间一样且包含所有分班 则按统一设置处理,否则是非统一设置 + @unified_setting = 0 unless min_publish_time == max_publish_time && params[:group_settings].pluck(:group_id).flatten.sort == @course.course_groups.pluck(:id).sort + elsif params[:delay_publish].to_i == 1 + tip_exception("缺少延期发布的时间参数") if params[:publish_time].blank? + min_publish_time = params[:publish_time] + end + @atta_is_publish = params[:delay_publish].to_i == 1 && min_publish_time.to_time > Time.now ? 0 : 1 @atta_delay_publish = params[:delay_publish].to_i - @atta_publish_time = params[:delay_publish].to_i == 1 && params[:publish_time] ? params[:publish_time] : Time.now + @atta_publish_time = params[:delay_publish].to_i == 1 ? min_publish_time : Time.now + end + + def create_atta_group_settings atta + if atta.attachment_group_settings.size != @course.course_groups.size + @course.course_groups.where.not(id: atta.attachment_group_settings.pluck(:course_group_id)).each do |group| + atta.attachment_group_settings << AttachmentGroupSetting.new(course_group_id: group.id, course_id: @course.id, + publish_time: atta.publish_time) + end + end + end + + def attachment_group_setting attachment, group_setting + create_atta_group_settings attachment + group_setting.each do |setting| + tip_exception("分班id不能为空") if setting[:group_id].length == 0 + tip_exception("发布时间不能为空") if setting[:publish_time].blank? + AttachmentGroupSetting.where(attachment_id: attachment.id, course_group_id: setting[:group_id]). + update_all(publish_time: setting[:publish_time]) + end end end diff --git a/app/controllers/games_controller.rb b/app/controllers/games_controller.rb index 1457cafcc..3f7a451fd 100644 --- a/app/controllers/games_controller.rb +++ b/app/controllers/games_controller.rb @@ -767,7 +767,8 @@ class GamesController < ApplicationController # 记录实训花费的时间 # REDO:需要添加详细的说明 def cost_time - cost_time = params[:time].to_i + #return if @game.status >= 2 + cost_time = params[:time].to_i < @game.cost_time.to_i ? (@game.cost_time.to_i + params[:time].to_i) : params[:time].to_i @game.update_attribute(:cost_time, cost_time) end diff --git a/app/controllers/gits_controller.rb b/app/controllers/gits_controller.rb index b3ab4c13f..bbb0e293e 100644 --- a/app/controllers/gits_controller.rb +++ b/app/controllers/gits_controller.rb @@ -38,7 +38,6 @@ class GitsController < ApplicationController else # 用户是否对对象拥有权限 system_user = User.find_by_login(input_username) || User.find_by_mail(input_username) || User.find_by_phone(input_username) - # 如果用户名密码错误 if system_user && !system_user.check_password?(input_password) uid_logger_error("git start: password is wrong") @@ -49,7 +48,13 @@ class GitsController < ApplicationController shixunname = git_url.split("/")[1].split(".")[0] repo_name = username + "/" + shixunname uid_logger("git start: repo_name is #{repo_name}") - shixun = Shixun.select([:id, :user_id, :repo_name, :identifier]).where(repo_name: repo_name, laboratory_id: nil).first + shixun = Shixun.select([:id, :user_id, :repo_name, :identifier]).where(repo_name: repo_name).first + if shixun.blank? + shixun_id = ShixunSecretRepository.where(repo_name: repo_name).pluck(:shixun_id).first + logger.info("####repo_name:#{repo_name}") + logger.info("####shixun_id:#{shixun_id}") + shixun = Shixun.select([:id, :user_id, :repo_name, :identifier]).find_by(id: shixun_id) + end uid_logger("git start auth: shixun identifier is #{shixun.try(:identifier)}") uid_logger("git start auth: systemuser is #{system_user.try(:login)}") diff --git a/app/controllers/hack_user_lastest_codes_controller.rb b/app/controllers/hack_user_lastest_codes_controller.rb index 56cda57d7..37102a166 100644 --- a/app/controllers/hack_user_lastest_codes_controller.rb +++ b/app/controllers/hack_user_lastest_codes_controller.rb @@ -1,9 +1,9 @@ class HackUserLastestCodesController < ApplicationController before_action :require_login, except: [:listen_result] before_action :find_my_hack, only: [:show, :code_debug, :code_submit, :update_code, - :listen_result, :result, :submit_records] + :listen_result, :result, :submit_records, :restore_initial_code] before_action :update_user_hack_status, only: [:code_debug, :code_submit] - before_action :require_auth_identity, only: [:update_code] + before_action :require_auth_identity, only: [:update_code, :restore_initial_code] before_action :require_manager_identity, only: [:update_code] def show @@ -12,6 +12,13 @@ class HackUserLastestCodesController < ApplicationController def update_code @my_hack.update_attribute(:code, params[:code]) + render_ok + end + + # 回复初始代码 + def restore_initial_code + @my_hack.update_attribute(:code, @hack.code) + render_ok end # 调试代码 @@ -35,7 +42,7 @@ class HackUserLastestCodesController < ApplicationController # 提交结果显示 def result if @my_hack.submit_status == 1 - render json: {status:0, message: "正在评测中"} + render json: {status: 1, message: "正在评测中"} else @mode = params[:mode] @result = @@ -103,9 +110,9 @@ class HackUserLastestCodesController < ApplicationController if exec_mode == "submit" @hack.hack_sets.map{|set| {input: set.input, output: set.output, caseId: set.id}} else - {input: params[:input]} + [{input: params[:input]}] end - testCases = Base64.urlsafe_encode64(test_sets.to_json) + testCases = Base64.encode64(test_sets.to_json) #codeFileContent = Base64.urlsafe_encode64(@my_hack.code) debug_params = {execMode: exec_mode, tpiID: @my_hack.identifier, @@ -121,6 +128,7 @@ class HackUserLastestCodesController < ApplicationController # 正则错误行数 def regular_match_error_line content, language + content = Base64.decode64(content).force_encoding("utf-8") case language when 'Java' content.scan(/.java.\d+/).map{|s| s.match(/\d+/)[0].to_i}.min @@ -136,7 +144,9 @@ class HackUserLastestCodesController < ApplicationController if @my_hack.hack_user_debug.present? @my_hack.hack_user_debug.update_attributes!(debug_params) else - @my_hack.hack_user_debug.create!(debug_params) + debug = HackUserDebug.new(debug_params) + debug.hack_user_lastest_code_id = @my_hack.id + debug.save! end end diff --git a/app/controllers/hacks_controller.rb b/app/controllers/hacks_controller.rb index 9fa8e26e3..993cba4e6 100644 --- a/app/controllers/hacks_controller.rb +++ b/app/controllers/hacks_controller.rb @@ -1,8 +1,9 @@ class HacksController < ApplicationController before_action :require_login, except: [:index] - before_action :require_teacher_identity, only: [:create, :edit, :update] - before_action :require_auth_identity, only: [:update, :edit, :publish] - before_action :find_hack, only: [:edit, :update, :publish, :start] + before_action :find_hack, only: [:edit, :update, :publish, :start, :update_set, :delete_set] + before_action :require_teacher_identity, only: [:create, :update_set] + before_action :require_auth_identity, only: [:update, :edit, :publish, :update_set, :delete_set] + # 开启编程,如果第一次开启,创建一条记录,如果已经开启过的话,直接返回标识即可 def start @@ -19,7 +20,7 @@ class HacksController < ApplicationController @hack.hack_user_lastest_codes.create!(user_code) user_identifier end - render_ok(data: {identifier: identifier}) + render_ok(identifier: identifier) end # 首页 @@ -27,7 +28,7 @@ class HacksController < ApplicationController # 筛选过滤与排序 params_filter_or_order # 我解决的编程题数 - user_codes = HackUserLastestCode.mine(current_user).passed.joins(:hack) + user_codes = HackUserLastestCode.joins(:hack).mine_hack(current_user).passed @simple_count = user_codes.where(hacks: {difficult: 1}).count @medium_count = user_codes.where(hacks: {difficult: 2}).count @diff_count = user_codes.where(hacks: {difficult: 3}).count @@ -46,6 +47,8 @@ class HacksController < ApplicationController hack.identifier = generate_identifier Hack, 8 hack.save! # 创建测试集与代码 + logger.info("hack_sets_params:#{hack_sets_params}") + logger.info("hack_code_params:#{hack_code_params}") hack.hack_sets.create!(hack_sets_params) hack.hack_codes.create!(hack_code_params) end @@ -75,6 +78,20 @@ class HacksController < ApplicationController end end + # 更新测试集接口 + def update_set + set = @hack.hack_sets.find_by(id: params[:id]) + set.update_attributes!(hack_set_params) + render_ok + end + + # 单独删除测试集 + def delete_set + set = @hack.hack_sets.find_by(id: params[:id]) + set.destroy! + render_ok + end + # 发布功能 def publish @hack.update_attribute(:status, 1) @@ -119,6 +136,10 @@ class HacksController < ApplicationController params.permit(hack_sets: [:input, :output, :position])[:hack_sets] end + def hack_set_params + params.require(:hack_set).permit(:id, :input, :output, :position) + end + def hack_code_params params.require(:hack_codes).permit(:code, :language) end @@ -144,7 +165,8 @@ class HacksController < ApplicationController if params[:come_from] hacks = Hack.select(select_sql).mine(current_user.id) else - hacks = Hack.select(select_sql).published.opening + # 全部包括已经发布的,和我的未发布的 + hacks = Hack.select(select_sql).published.opening.or(Hack.select(select_sql).unpublish.mine(current_user.id)) end # 搜索 if params[:search] @@ -162,9 +184,14 @@ class HacksController < ApplicationController hacks = hacks.where.not(id: user_hacks.pluck(:hack_id)) end else - hacks = hacks.joins(:hack_user_lastest_code).where(hack_user_lastest_code: {status: params[:status]}) + hacks = hacks.joins(:hack_user_lastest_codes).where(hack_user_lastest_codes: {status: params[:status]}) end end + # 分类 + if params[:category] + hacks = hacks.where(category: params[:category]) + end + # 排序 sort_by = params[:sort_by] || "hack_user_lastest_codes_count" sort_direction = params[:sort_direction] || "desc" diff --git a/app/controllers/helps_controller.rb b/app/controllers/helps_controller.rb index 9aefb5129..8d58663f6 100644 --- a/app/controllers/helps_controller.rb +++ b/app/controllers/helps_controller.rb @@ -25,7 +25,16 @@ class HelpsController < ApplicationController end def feedback - content = "
[#{params[:question_kind]}]
问题页面网址:#{params[:url]}
#{params[:description]}" + if params[:url].blank? + content = "[#{params[:question_kind]}]
#{params[:description]}" + if params[:attachment_ids] + params[:attachment_ids].each do |attachment_id| + content += "↵" + end + end + else + content = "[#{params[:question_kind]}]
问题页面网址:#{params[:url]}
#{params[:description]}" + end ActiveRecord::Base.transaction do attr = { sender_id: User.current.id, receiver_id: 1, content: content, send_time: Time.now } diff --git a/app/controllers/home_controller.rb b/app/controllers/home_controller.rb index 65a1d345a..e31c77499 100644 --- a/app/controllers/home_controller.rb +++ b/app/controllers/home_controller.rb @@ -30,10 +30,10 @@ class HomeController < ApplicationController @main_shixuns = Shixun.where(homepage_show: true).includes(:tag_repertoires, :challenges).limit(8) @main_subjects = Subject.where(homepage_show: true).includes(:shixuns, :repertoire).limit(8) - if current_laboratory.main_site? - @tea_users = User.where(homepage_teacher: 1).includes(:user_extension).limit(10).order("experience desc") - @stu_users = User.where(is_test: 0).includes(:user_extension).where(user_extensions: {identity: 1}).limit(10).order("experience desc") - end + # if current_laboratory.main_site? + # @tea_users = User.where(homepage_teacher: 1).includes(:user_extension).limit(10).order("experience desc") + # @stu_users = User.where(is_test: 0).includes(:user_extension).where(user_extensions: {identity: 1}).limit(10).order("experience desc") + # end end def search diff --git a/app/controllers/homework_commons_controller.rb b/app/controllers/homework_commons_controller.rb index 94ced56fd..a94eed83f 100644 --- a/app/controllers/homework_commons_controller.rb +++ b/app/controllers/homework_commons_controller.rb @@ -13,7 +13,8 @@ class HomeworkCommonsController < ApplicationController :reference_answer, :publish_groups, :end_groups, :alter_name, :update_explanation, :update_score, :update_student_score] before_action :user_course_identity - before_action :homework_publish, only: [:show, :works_list, :code_review_results, :show_comment, :settings, :reference_answer, :update_student_score] + before_action :homework_publish, only: [:show, :works_list, :code_review_results, :show_comment, :settings, :reference_answer, + :update_student_score] before_action :teacher_allowed, only: [:new, :edit, :create, :update, :shixuns, :subjects, :create_shixun_homework, :publish_homework, :end_homework, :set_public, :choose_category, :move_to_category, :choose_category, :create_subject_homework, :multi_destroy, :group_list, :homework_code_repeat, @@ -64,21 +65,25 @@ class HomeworkCommonsController < ApplicationController end unless order.blank? - case order - when '1' - sql_str = %Q(homework_detail_manuals.comment_status = #{order} and homework_commons.end_time > '#{Time.now}') - when '2' - sql_str = %Q(allow_late = 1 and homework_commons.end_time < '#{Time.now}' and (late_time is null or late_time > '#{Time.now}')) - when '3' - sql_str = %Q(homework_detail_manuals.comment_status = #{order} and homework_detail_manuals.evaluation_end > '#{Time.now}') - when '4' - sql_str = %Q((homework_detail_manuals.comment_status = #{order} and homework_detail_manuals.appeal_time > '#{Time.now}')) - when '5' - sql_str = %Q((homework_detail_manuals.comment_status = #{order} or (anonymous_comment = 0 and homework_commons.end_time <= '#{Time.now}'))) + if @course.is_end + @homework_commons = @homework_commons.none else - sql_str = %Q(homework_detail_manuals.comment_status = #{order}) + case order + when '1' + sql_str = %Q(homework_detail_manuals.comment_status = #{order} and homework_commons.end_time > '#{Time.now}') + when '2' + sql_str = %Q(allow_late = 1 and homework_commons.end_time < '#{Time.now}' and (late_time is null or late_time > '#{Time.now}')) + when '3' + sql_str = %Q(homework_detail_manuals.comment_status = #{order} and homework_detail_manuals.evaluation_end > '#{Time.now}') + when '4' + sql_str = %Q((homework_detail_manuals.comment_status = #{order} and homework_detail_manuals.appeal_time > '#{Time.now}')) + when '5' + sql_str = %Q((homework_detail_manuals.comment_status = #{order} or (anonymous_comment = 0 and homework_commons.end_time <= '#{Time.now}'))) + else + sql_str = %Q(homework_detail_manuals.comment_status = #{order}) + end + @homework_commons = @homework_commons.joins(:homework_detail_manual).where(sql_str) end - @homework_commons = @homework_commons.joins(:homework_detail_manual).where(sql_str) end @task_count = @homework_commons.size @@ -577,8 +582,8 @@ class HomeworkCommonsController < ApplicationController tip_exception("缺少answer_open_evaluation参数") if params[:answer_open_evaluation].nil? tip_exception("缺少work_efficiency参数") if params[:work_efficiency].nil? tip_exception("缺少eff_score参数") if params[:work_efficiency] && params[:eff_score].blank? - tip_exception("效率分不能小于等于0") if params[:eff_score] && params[:eff_score].to_i <= 0 - tip_exception("效率分不能大于总分值") if params[:eff_score] && params[:eff_score].to_i > params[:total_score].to_i + tip_exception("效率分不能小于等于0") if params[:eff_score] && params[:eff_score].to_f <= 0 + tip_exception("效率分不能大于总分值") if params[:eff_score] && params[:eff_score].to_f.round(2) > params[:total_score].to_f.round(2) tip_exception("缺少shixun_evaluation参数") if params[:shixun_evaluation].blank? tip_exception("缺少challenge_settings参数") if params[:challenge_settings].blank? # tip_exception("缺少challenge_id参数") if params[:challenge_settings][:challenge_id].blank? @@ -586,12 +591,12 @@ class HomeworkCommonsController < ApplicationController # tip_exception("challenge_id参数的长度与challenge_score参数的长度不匹配") if # params[:challenge_settings][:challenge_score].length != params[:challenge_settings][:challenge_id].length - current_eff_score = @homework.eff_score + current_eff_score = @homework.eff_score.to_f.round(2) @homework.total_score = params[:total_score] @homework.work_efficiency = params[:work_efficiency] - @homework.eff_score = params[:work_efficiency] ? params[:eff_score].to_i : 0 + @homework.eff_score = params[:work_efficiency] ? params[:eff_score].to_f.round(2) : 0 - update_eff_score = current_eff_score != @homework.eff_score + update_eff_score = current_eff_score.round(2) != @homework.eff_score.round(2) if @homework_detail_manual.answer_open_evaluation != params[:answer_open_evaluation] @homework_detail_manual.answer_open_evaluation = params[:answer_open_evaluation] @@ -625,14 +630,10 @@ class HomeworkCommonsController < ApplicationController @homework.score_open = params[:score_open] @homework.save! - # if score_change - # @homework.student_works.has_committed.each do |student_work| - # HomeworksService.new.set_shixun_final_score student_work - # end - # end - - # 更新所有学生的效率分(作业允许补交且补交已截止 或者 作业不允许补交且提交已截止) - if update_eff_score && @homework.end_or_late_none_group + if score_change && @homework.end_or_late_none_group + UpdateShixunWorkScoreJob.perform_now(@homework.id) + elsif update_eff_score && (@homework.end_or_late_none_group || @homework.max_efficiency > 0) + # 更新所有学生的效率分(作业允许补交且补交已截止 或者 作业不允许补交且提交已截止 或者作业已计算过效率分) HomeworksService.new.update_student_eff_score HomeworkCommon.find_by(id: @homework.id) end diff --git a/app/controllers/oauth/base_controller.rb b/app/controllers/oauth/base_controller.rb index e4068fbda..11ac69d71 100644 --- a/app/controllers/oauth/base_controller.rb +++ b/app/controllers/oauth/base_controller.rb @@ -2,6 +2,7 @@ class Oauth::BaseController < ActionController::Base include RenderHelper include LoginHelper include ControllerRescueHandler + include LaboratoryHelper skip_before_action :verify_authenticity_token @@ -12,7 +13,8 @@ class Oauth::BaseController < ActionController::Base private def session_user_id - session[:user_id] + # session[:user_id] + session[:"#{default_yun_session}"] end def current_user @@ -23,4 +25,9 @@ class Oauth::BaseController < ActionController::Base Rails.logger.info("[OAuth2] omniauth.auth -> #{request.env['omniauth.auth'].inspect}") request.env['omniauth.auth'] end + + def default_yun_session + @_default_yun_session = "#{request.subdomain.split('.').first}_user_id" + # @_default_yun_session = "#{current_laboratory.try(:identifier).split('.').first}_user_id" + end end \ No newline at end of file diff --git a/app/controllers/poll_questions_controller.rb b/app/controllers/poll_questions_controller.rb index 6a0b9ea47..411961e96 100644 --- a/app/controllers/poll_questions_controller.rb +++ b/app/controllers/poll_questions_controller.rb @@ -235,9 +235,9 @@ class PollQuestionsController < ApplicationController end def validates_params - normal_status(-1, "问题标题不能为空!") if params[:question_title].blank? + normal_status(-1, "题目不能为空!") if params[:question_title].blank? normal_status(-1, "是否要求必答的值不能为空!") if params[:is_necessary].blank? - normal_status(-1, "问题类型不能为空!") if params[:question_type].blank? + normal_status(-1, "题目类型不能为空!") if params[:question_type].blank? if params[:min_choices].present? && params[:max_choices].present? && (params[:min_choices].to_i > params[:max_choices].to_i) normal_status(-1, "最小可选不能大于最大可选!") elsif params[:question_answers].present? && (params[:max_choices].to_i > params[:question_answers].count) @@ -247,9 +247,9 @@ class PollQuestionsController < ApplicationController elsif params[:question_type] == 3 && (params[:question_answers] || params[:question_other_answer]) normal_status(-1, "主观问题不需要可选答案!") elsif params[:question_type] != 3 - if params[:question_answers].present? && params[:question_answers].include?("") - normal_status(-1, "选择题不能有空值!") - elsif params[:question_other_answer].present? && params[:question_other_answer].length > 0 + if params[:question_answers].present? && params[:question_answers].select{|answer| answer.blank?}.count > 0 + normal_status(-1, "选项不能有空值!") + elsif params[:question_other_answer].present? && !params[:question_other_answer].blank? normal_status(-1, "其他选项不能有值!") elsif params[:question_type] == 1 && params[:question_answers].count < 2 normal_status(-1, "单选题选项不能小于2!") diff --git a/app/controllers/polls_controller.rb b/app/controllers/polls_controller.rb index 5a3fda7a4..068a0dafd 100644 --- a/app/controllers/polls_controller.rb +++ b/app/controllers/polls_controller.rb @@ -198,14 +198,14 @@ class PollsController < ApplicationController def common_header ActiveRecord::Base.transaction do begin + @poll_status = @poll.get_poll_status(current_user) if @user_course_identity > Course::ASSISTANT_PROFESSOR @is_teacher_or = 0 - @user_poll_answer = @poll.check_user_votes_status(current_user) + @user_poll_answer = @poll.check_user_votes_status(current_user, @poll_status) else @is_teacher_or = 1 @user_poll_answer = 3 #教师页面 end - @poll_status = @poll.get_poll_status(current_user) poll_id_array = [@poll.id] @poll_publish_count = get_user_permission_course(poll_id_array,2).count #是否存在已发布的 @poll_unpublish_count = get_user_permission_course(poll_id_array,1).count #是否存在未发布的 diff --git a/app/controllers/shixuns_controller.rb b/app/controllers/shixuns_controller.rb index 30f6d1bd3..a321beb25 100644 --- a/app/controllers/shixuns_controller.rb +++ b/app/controllers/shixuns_controller.rb @@ -10,11 +10,11 @@ class ShixunsController < ApplicationController before_action :find_shixun, except: [:index, :new, :create, :menus, :get_recommend_shixuns, :propaedeutics, :departments, :apply_shixun_mirror, - :get_mirror_script, :download_file, :shixun_list] + :get_mirror_script, :download_file, :shixun_list, :batch_send_to_course] before_action :shixun_access_allowed, except: [:index, :new, :create, :menus, :get_recommend_shixuns, :propaedeutics, :departments, :apply_shixun_mirror, - :get_mirror_script, :download_file, :shixun_list, :review_shixuns] + :get_mirror_script, :download_file, :shixun_list, :batch_send_to_course] before_action :find_repo_name, only: [:repository, :commits, :file_content, :update_file, :shixun_exec, :copy, :add_file] before_action :allowed, only: [:update, :close, :update_propaedeutics, :settings, :publish, @@ -515,7 +515,7 @@ class ShixunsController < ApplicationController end # 添加第二仓库 if params[:is_secret_repository] - add_secret_repository + add_secret_repository if @shixun.shixun_secret_repository.blank? else # 如果有仓库,就要删 if @shixun.shixun_secret_repository&.repo_name @@ -977,9 +977,7 @@ class ShixunsController < ApplicationController @courses = Course.where(:id => course_ids) ## 云上实验室过滤 - unless current_laboratory.main_site? - @courses = @courses.where(laboratory_id: current_laboratory.id ) - end + @courses = @courses.where(id: current_laboratory.all_courses) @course_count = @courses.count @courses = @courses.page(page).per(limit) @@ -992,6 +990,16 @@ class ShixunsController < ApplicationController CreateStudentWorkJob.perform_later(homework.id) end + # 批量发送 + def batch_send_to_course + @course = Course.find_by!(id: params[:course_id]) + shixuns = Shixun.where(id: params[:shixun_ids]).unhidden + shixuns.each do |shixun| + homework = HomeworksService.new.create_homework shixun, @course, nil, current_user + CreateStudentWorkJob.perform_later(homework.id) + end + end + # 二维码扫描下载 def download_file file_path = params[:file_name] diff --git a/app/controllers/subjects_controller.rb b/app/controllers/subjects_controller.rb index d4f1281a2..096a0fe52 100644 --- a/app/controllers/subjects_controller.rb +++ b/app/controllers/subjects_controller.rb @@ -2,7 +2,7 @@ class SubjectsController < ApplicationController before_action :require_login, :check_auth, except: [:index, :show, :right_banner] # before_action :check_auth, except: [:index] before_action :check_account, except: [:index, :show, :right_banner] - before_action :find_subject, except: [:index, :create, :new, :append_to_stage] + before_action :find_subject, except: [:index, :create, :new, :append_to_stage, :add_shixun_to_stage] before_action :allowed, only: [:update, :edit, :destroy, :publish, :cancel_publish, :cancel_has_publish, :search_members, :add_subject_members, :statistics, :shixun_report, :school_report, :up_member_position, :down_member_position, :update_team_title] @@ -10,6 +10,7 @@ class SubjectsController < ApplicationController include ApplicationHelper include SubjectsHelper + include GitCommon def index @tech_system = current_laboratory.subject_repertoires @@ -212,15 +213,36 @@ class SubjectsController < ApplicationController @shixuns = Shixun.where(id: params[:shixun_id]).order("id desc") end + # 添加实训项目 + def add_shixun_to_stage + identifier = generate_identifier Shixun, 8 + ActiveRecord::Base.transaction do + @shixun = Shixun.create!(name: params[:name], user_id: current_user.id, identifier: identifier) + # 添加合作者 + @shixun.shixun_members.create!(user_id: current_user.id, role: 1) + # 创建长字段 + ShixunInfo.create!(shixun_id: @shixun.id, description: "请在此处添加实训描述") + # 创建版本库 + repo_path = repo_namespace(current_user.login, identifier) + GitService.add_repository(repo_path: repo_path) + # todo: 为什么保存的时候要去除后面的.git呢?? + @shixun.update_column(:repo_name, repo_path.split(".")[0]) + mirror_id = MirrorRepository.find_by(type_name: 'Python3.6')&.id + if mirror_id + ShixunMirrorRepository.create!(:shixun_id => @shixun.id, :mirror_repository_id => mirror_id) + @shixun.shixun_service_configs.create!(:shixun_id => @shixun.id, :mirror_repository_id => mirror_id) + end + end + end + def choose_course course_ids = Course.find_by_sql("SELECT c.id FROM courses c, course_members m WHERE m.course_id = c.id AND m.role in (1,2,3) AND m.user_id=#{current_user.id} AND c.is_delete = 0 AND c.is_end = 0").map(&:id) @courses = Course.where(id: course_ids) ## 云上实验室过滤 - unless current_laboratory.main_site? - @courses = @courses.where(laboratory_id: current_laboratory.id ) - end + @courses = @courses.where(id: current_laboratory.all_courses) + @none_shixun_ids = ShixunSchool.where("school_id != #{current_user.user_extension.try(:school_id).to_i}").pluck(:shixun_id) end diff --git a/app/controllers/tidings_controller.rb b/app/controllers/tidings_controller.rb index 9324b2755..5acffcb16 100644 --- a/app/controllers/tidings_controller.rb +++ b/app/controllers/tidings_controller.rb @@ -6,6 +6,7 @@ class TidingsController < ApplicationController def index tidings = current_user.tidings + @onclick_time = current_user.click_time tiding_types = case params[:type] @@ -18,11 +19,13 @@ class TidingsController < ApplicationController end tidings = tidings.where(tiding_type: tiding_types) if tiding_types.present? + tidings = tidings.where(container_type: 'JoinCourse') if params[:type] == 'course_apply' + @course_apply_count = tidings.where("created_at > '#{@onclick_time}'").where(container_type: 'JoinCourse').count + tidings = tidings.where(container_type: 'ProjectPackage') if params[:type] == 'project_package' @count = tidings.count @tidings = paginate(tidings.order(created_at: :desc), per_page: 10) - @onclick_time = current_user.click_time end private diff --git a/app/controllers/users/courses_controller.rb b/app/controllers/users/courses_controller.rb index 4198e17ba..95a006392 100644 --- a/app/controllers/users/courses_controller.rb +++ b/app/controllers/users/courses_controller.rb @@ -2,7 +2,7 @@ class Users::CoursesController < Users::BaseController def index courses = Users::CourseService.new(observed_user, query_params).call - courses = courses.where(laboratory_id: current_laboratory.id) + courses = courses.where(id: current_laboratory.all_courses) @count = courses.count @courses = paginate(courses.includes(teacher: { user_extension: :school }), special: observed_user.is_teacher?) diff --git a/app/controllers/weapps/code_sessions_controller.rb b/app/controllers/weapps/code_sessions_controller.rb index 887e97eed..2dbd08e82 100644 --- a/app/controllers/weapps/code_sessions_controller.rb +++ b/app/controllers/weapps/code_sessions_controller.rb @@ -15,6 +15,8 @@ class Weapps::CodeSessionsController < Weapps::BaseController logged = true else # 根据 code没拿到 unionid + Rails.logger.info("[Weapp] session_key: #{result['session_key']}") + Rails.logger.info("[Weapp] code: #{params[:code]}") user_info = Wechat::Weapp.decrypt(result['session_key'], params[:encrypted_data], params[:iv]) # 老用户,已绑定 diff --git a/app/controllers/weapps/courses_controller.rb b/app/controllers/weapps/courses_controller.rb index a81446cea..c2335998e 100644 --- a/app/controllers/weapps/courses_controller.rb +++ b/app/controllers/weapps/courses_controller.rb @@ -1,6 +1,8 @@ class Weapps::CoursesController < Weapps::BaseController before_action :require_login - before_action :teacher_allowed, except: [:create, :show, :shixun_homework_category] + before_action :set_course, :user_course_identity, except: [:create] + before_action :teacher_allowed, only: [:edit, :update] + before_action :teacher_or_admin_allowed, only: [:change_member_roles, :delete_course_teachers] def create return render_error("只有老师身份才能创建课堂") unless current_user.is_teacher? @@ -30,6 +32,140 @@ class Weapps::CoursesController < Weapps::BaseController @categories = current_course.shixun_course_modules.first&.course_second_categories end + # 教师列表 + def teachers + @course = current_course + @page = (params[:page] || 1).to_i + @limit = (params[:limit] || 20).to_i + search = params[:search].present? ? params[:search].strip : "" + if @course.try(:id) != 1309 || current_user.admin? || current_user.try(:id) == 15582 + @teacher_list = @course.course_members.joins(:user).where("course_members.role in (1, 2, 3)") + else + @teacher_list = @course.course_members.joins(:user).where("(course_members.role in (1, 3) or (course_members.user_id = #{current_user.id} + and course_members.role = 2))") + end + + if search.present? + @teacher_list = @teacher_list.joins(:user).where("LOWER(CONCAT(users.lastname, users.firstname)) like ?", "%#{search}%") + end + + @teacher_list_size = @teacher_list.size + + @applications_size = CourseMessage.unhandled_join_course_requests_by_course(@course).size + + @teacher_list = @teacher_list.includes(user: [user_extension: :school]) + # 中英文混合排序(忽略大小写) + @teacher_list = @teacher_list.sort {|x, y| Pinyin.t(x.user&.real_name, splitter: '').upcase <=> Pinyin.t(y.user&.real_name, splitter: '').upcase} + @teacher_list = @teacher_list[(@page-1)*@limit ... @page*@limit] + end + + # 批量删除教师或助教 + def delete_course_teachers + begin + @course = current_course + @page = (params[:page] || 1).to_i + @limit = (params[:limit] || 20).to_i + course_members = @course.course_members.where(id: params[:course_member_ids], role: %i[PROFESSOR ASSISTANT_PROFESSOR]) + user_ids = course_members.pluck(:user_id) + course_members.destroy_all + CourseDeleteStudentNotifyJob.perform_later(@course.id, user_ids, current_user.id) + @course.students.where(user_id: user_ids).update_all(is_active: 1) + normal_status(0, "删除成功") + rescue => e + uid_logger_error(e.message) + tip_exception("删除失败") + end + end + + def students + @course = current_course + @page = (params[:page] || 1).to_i + @limit = (params[:limit] || 20).to_i + search = params[:search].present? ? params[:search].strip : nil + course_group_id = params[:course_group_id].present? ? params[:course_group_id].to_i : nil + + @students = CourseMember.students(@course) + + if search.present? + @students = @students.joins(user: :user_extension).where("LOWER(CONCAT(users.lastname, users.firstname)) like ? or + user_extensions.student_id like ?", "%#{search}%", "%#{search}%") + end + + if course_group_id.present? + course_group = CourseGroup.find(course_group_id) if course_group_id != 0 + @students = @students.where(course_group_id: course_group&.id.to_i) + end + + @students_count = @students.size + @students = @students.includes(user: :user_extension) + # 中英文混合排序(忽略大小写) + @students = @students.sort {|x, y| Pinyin.t(x.user&.real_name, splitter: '').upcase <=> Pinyin.t(y.user&.real_name, splitter: '').upcase} + @students = @students[(@page-1)*@limit ... @page*@limit] + end + + # 批量修改角色 + def change_member_roles + @course = current_course + tip_exception("请至少选择一个角色") if params[:roles].blank? + tip_exception("不能具有老师、助教两种角色") if params[:roles].include?("PROFESSOR") && params[:roles].include?("ASSISTANT_PROFESSOR") + + params[:user_ids].each do |user_id| + course_members = @course.course_members.where(user_id: user_id) + tip_exception("非课堂成员不能修改角色") if course_members.blank? + + ActiveRecord::Base.transaction do + # 第一次修改为教师或助教身份时直接创建数据 + if params[:roles].include?("CREATOR") + teacher_member = course_members.where(role: %i[CREATOR]).take + elsif (params[:roles].include?("PROFESSOR") || params[:roles].include?("ASSISTANT_PROFESSOR")) && !course_members.exists?(role: %i[CREATOR PROFESSOR ASSISTANT_PROFESSOR]) + teacher_member = CourseMember.create!(course_id: @course.id, user_id: user_id, role: params[:roles].include?("PROFESSOR") ? 2 : 3) + # 如果有未审批的申请教师/助教的记录,则修改状态为已审批 + apply_teacher = CourseMessage.where(course_id: @course.id, course_message_id: user_id, status: 0).last + apply_teacher.update!(status: 1, apply_user_id: current_user.id) if apply_teacher + elsif course_members.exists?(role: %i[PROFESSOR ASSISTANT_PROFESSOR]) + teacher_member = course_members.where(role: %i[PROFESSOR ASSISTANT_PROFESSOR]).take + if params[:roles].include?("PROFESSOR") || params[:roles].include?("ASSISTANT_PROFESSOR") + # 如果之前有老师身份且老师身份要调整时,只需要修改role字段 + if !params[:roles].include?(teacher_member.role) && params[:roles].include?("PROFESSOR") + teacher_member.PROFESSOR! + elsif !params[:roles].include?(teacher_member.role) && params[:roles].include?("ASSISTANT_PROFESSOR") + teacher_member.ASSISTANT_PROFESSOR! + end + teacher_member.save! + else + # 不含教师的参数时删除记录 + teacher_member.destroy! + # CourseDeleteStudentNotifyJob.perform_later(@course.id, [teacher_member.user_id], current_user.id) + end + end + + # 学生身份的处理 + student_member = course_members.where(role: %i[STUDENT]).take + + # 不存在则创建学生身份 + if params[:roles].include?("STUDENT") && student_member.blank? + correspond_teacher_exist = CourseMember.exists?(user_id: user_id, is_active: 1, course_id: @course.id, role: %i[CREATOR PROFESSOR ASSISTANT_PROFESSOR]) + new_student = CourseMember.new(user_id: user_id, course_id: @course.id, role: 4) + new_student.is_active = 0 if correspond_teacher_exist + new_student.save! + + CourseAddStudentCreateWorksJob.perform_later(@course.id, user_id) + # StudentJoinCourseNotifyJob.perform_later(current_user.id, course.id) + elsif !params[:roles].include?("STUDENT") && student_member.present? + # 删除学生身份时激活老师身份 + teacher_member.update_attributes!(is_active: 1) if student_member.is_active && teacher_member.present? + student_member.destroy! + CourseDeleteStudentDeleteWorksJob.perform_later(@course.id, user_id) + # CourseDeleteStudentNotifyJob.perform_later(@course.id, [params[:user_id]], current_user.id) + elsif params[:roles].include?("STUDENT") && student_member.present? && !params[:roles].include?("PROFESSOR") && !params[:roles].include?("ASSISTANT_PROFESSOR") + # 学生身份存在且学生没有教师身份时更新is_active + student_member.update_attributes!(is_active: 1) + end + end + end + normal_status(0, "修改成功") + end + private def course_params @@ -45,6 +181,18 @@ class Weapps::CoursesController < Weapps::BaseController end def teacher_allowed - return render_forbidden unless current_user.course_identity(current_course) < Course::STUDENT + return render_forbidden unless @user_course_identity < Course::STUDENT + end + + # 课堂教师,课堂管理员以及超级管理员的权限判断 + def teacher_or_admin_allowed + unless @user_course_identity < Course::ASSISTANT_PROFESSOR + tip_exception(403, "..") + end + end + + def set_course + @course = Course.find_by!(id: params[:id]) + tip_exception(404, "") if @course.is_delete == 1 && !current_user.admin? end end \ No newline at end of file diff --git a/app/controllers/weapps/registers_controller.rb b/app/controllers/weapps/registers_controller.rb index 0cbab7fd4..de48ebd54 100644 --- a/app/controllers/weapps/registers_controller.rb +++ b/app/controllers/weapps/registers_controller.rb @@ -48,9 +48,10 @@ class Weapps::RegistersController < Weapps::BaseController ) end successful_authentication(@user) - session[:user_id] = @user.id + # session[:user_id] = @user.id + session[:"#{default_yun_session}"] = @user.id - render_ok + # render_ok(user_id: @user.id) end private diff --git a/app/helpers/polls_helper.rb b/app/helpers/polls_helper.rb index 866d28254..7ae4470e2 100644 --- a/app/helpers/polls_helper.rb +++ b/app/helpers/polls_helper.rb @@ -77,7 +77,7 @@ module PollsHelper ex_pb_time = poll.get_poll_times(user.id,false) poll_publish_time = ex_pb_time[:publish_time] poll_end_time = ex_pb_time[:end_time] - current_status = poll.check_user_votes_status(user) + current_status = poll.check_user_votes_status(user, poll_status) lock_icon = 0 #不显示锁图标 else poll_users_list = poll.get_poll_exercise_users diff --git a/app/helpers/weapps/courses_helper.rb b/app/helpers/weapps/courses_helper.rb new file mode 100644 index 000000000..32de8f253 --- /dev/null +++ b/app/helpers/weapps/courses_helper.rb @@ -0,0 +1,67 @@ +module Weapps::CoursesHelper + require 'chinese_pinyin' + + def teacher_list teachers + data = [] + teachers.each do |teacher| + if teacher.user.present? + teacher_user = teacher.user + name = teacher_user.real_name + role = teacher.role == "CREATOR" ? "管理员" : teacher.role == "PROFESSOR" ? "教师" : "助教" + item = {name: name, course_member_id: teacher.id, login: teacher_user.login, user_id: teacher.user_id, role: role, + school: teacher_user.school_name, image_url: url_to_avatar(teacher_user)} + pinyin = Pinyin.t(name.strip, splitter: '') + first_char = pinyin[0] + letter = first_letter first_char + if data.pluck(:letter).include?(letter) + data.select{|a|a[:letter]==letter}.first[:items] << item + else + data << {letter: letter, items: [item]} + end + end + end + # data = data.sort do |a, b| + # [a[:letter]] <=> [b[:letter]] + # end + # data.push(data.shift) if data.select{|a|a[:letter]=='#'}.first.present? # '#'排在最后 + return data + end + + + def student_list students, excellent + data = [] + students.each do |student| + if student.user.present? + student_user = student.user + name = student_user.real_name + phone = excellent ? "" : student_user.hidden_phone + item = {name: name, course_member_id: student.id, login: student_user.login, user_id: student.user_id, + student_id: student_user.student_id, image_url: url_to_avatar(student_user), phone: phone} + pinyin = Pinyin.t(name.strip, splitter: '') + first_char = pinyin[0] + letter = first_letter first_char + if data.pluck(:letter).include?(letter) + data.select{|a|a[:letter]==letter}.first[:items] << item + else + data << {letter: letter, items: [item]} + end + end + end + # data = data.sort do |a, b| + # [a[:letter]] <=> [b[:letter]] + # end + # data.push(data.shift) if data.select{|a|a[:letter]=='#'}.first.present? # '#'排在最后 + return data + end + + def first_letter char + if char.ord >= 97 && char.ord <= 122 + letter = (char.ord - 32).chr.to_s + elsif char.ord >= 65 && char.ord <= 90 + letter = char + else + letter = '#' + end + letter + end +end \ No newline at end of file diff --git a/app/jobs/update_shixun_work_score_job.rb b/app/jobs/update_shixun_work_score_job.rb new file mode 100644 index 000000000..1701915c9 --- /dev/null +++ b/app/jobs/update_shixun_work_score_job.rb @@ -0,0 +1,10 @@ +class UpdateShixunWorkScoreJob < ApplicationJob + queue_as :default + + def perform(homework_id) + homework = HomeworkCommon.find_by(id: homework_id) + return if homework.blank? + + homework.update_homework_work_score + end +end diff --git a/app/libs/wechat/weapp.rb b/app/libs/wechat/weapp.rb index 9684206cd..ca356b28d 100644 --- a/app/libs/wechat/weapp.rb +++ b/app/libs/wechat/weapp.rb @@ -31,7 +31,9 @@ class Wechat::Weapp cipher.padding = 0 cipher.key = session_key cipher.iv = iv + Rails.logger.info("[Weapp] encrypted_data: #{encrypted_data}") data = cipher.update(encrypted_data) << cipher.final + Rails.logger.info("[Weapp] data: #{data}") result = JSON.parse(data[0...-data.last.ord]) raise Wechat::Error.new(-1, '解密错误') if result.dig('watermark', 'appid') != appid diff --git a/app/models/attachment.rb b/app/models/attachment.rb index 8b7034ab9..37884e40b 100644 --- a/app/models/attachment.rb +++ b/app/models/attachment.rb @@ -23,6 +23,7 @@ class Attachment < ApplicationRecord scope :mine, -> (author_id) { where(author_id: author_id) } scope :simple_columns, -> { select(:id, :filename, :filesize, :created_on, :cloud_url, :author_id, :content_type) } scope :search_by_container, -> (ids) {where(container_id: ids)} + scope :unified_setting, -> {where("unified_setting = ? ", 1)} validates_length_of :description, maximum: 100 diff --git a/app/models/attachment_group_setting.rb b/app/models/attachment_group_setting.rb index 67240d88f..3fefe5ceb 100644 --- a/app/models/attachment_group_setting.rb +++ b/app/models/attachment_group_setting.rb @@ -3,4 +3,6 @@ class AttachmentGroupSetting < ActiveRecord::Base belongs_to :course_group belongs_to :course + scope :none_published, -> {where("attachment_group_settings.publish_time IS NULL OR attachment_group_settings.publish_time > ?", Time.now)} + end diff --git a/app/models/course.rb b/app/models/course.rb index 9e252b02f..2f561bba7 100644 --- a/app/models/course.rb +++ b/app/models/course.rb @@ -31,6 +31,7 @@ class Course < ApplicationRecord has_many :graduation_groups, dependent: :destroy has_many :course_members, dependent: :destroy + has_many :students, -> { course_students }, class_name: 'CourseMember' has_many :teacher_course_members, -> { teachers_and_admin }, class_name: 'CourseMember' has_many :teacher_users, through: :teacher_course_members, source: :user has_many :course_messages, dependent: :destroy @@ -114,6 +115,10 @@ class Course < ApplicationRecord course_members.where(user_id: user_id, role: role).exists? end + def course_group_module? + course_modules.exists?(module_type: "course_group", hidden: 0) + end + # 作业对应的子目录/父目录名称 def category_info type course_module = course_modules.find_by(module_type: type) @@ -234,11 +239,6 @@ class Course < ApplicationRecord course_members.where(role: %i[CREATOR PROFESSOR]) end - # 课堂学生 - def students - course_members.where(role: %i[STUDENT]) - end - # 更新课程的访问人数 def update_visits(new_visits) update_attributes(visits: new_visits) @@ -367,6 +367,23 @@ class Course < ApplicationRecord count = course_challeng_count == 0 ? 0 : ((my_challenge_count.to_f / course_challeng_count).round(2) * 100).to_i end + # 课堂实训作业的评测次数 + def evaluate_count + course_user_ids = students.pluck(:user_id) + shixun_ids = homework_commons.joins(:homework_commons_shixun).where(homework_type: 4).pluck(:shixun_id) + return 0 if shixun_ids.blank? + Game.joins(:challenge).where(challenges: {shixun_id: shixun_ids}, games: {user_id: course_user_ids}).sum(:evaluate_count) + end + + def max_activity_time + course_acts.pluck(:updated_at).max + end + + # 课堂作业数 + def course_homework_count type + homework_commons.select{|homework| homework.homework_type == type}.size + end + private #创建课程后,给该用户发送消息 diff --git a/app/models/course_list.rb b/app/models/course_list.rb index 080c05ae2..cd622f20a 100644 --- a/app/models/course_list.rb +++ b/app/models/course_list.rb @@ -5,4 +5,5 @@ class CourseList < ApplicationRecord has_many :exercise_banks has_many :gtask_banks has_many :gtopic_banks + belongs_to :user end diff --git a/app/models/game.rb b/app/models/game.rb index 7aa2e7264..d82392a59 100644 --- a/app/models/game.rb +++ b/app/models/game.rb @@ -3,7 +3,7 @@ # modify_time: 与challenges表的modify_time联合使用,2个字段一致,则标识测试集未修改,反之,被修改 # answer_open: 查看查看答案的深度, 0: 未查看过答案, 其他数值与challenge_answer的level值相关 # answer_deduction: 查看答案扣分的百分比;如 查看答案 扣除70% -# +#play_sign 与play_time: sign记录浏览器是否正常关闭, 0表示正常,1表示非正常; play_time:表示游玩时间 class Game < ApplicationRecord default_scope { order("games.created_at desc") } diff --git a/app/models/hack.rb b/app/models/hack.rb index adc6bba8c..80724d3d4 100644 --- a/app/models/hack.rb +++ b/app/models/hack.rb @@ -12,6 +12,7 @@ class Hack < ApplicationRecord belongs_to :user scope :published, -> { where(status: 1) } + scope :unpublish, -> { where(status: 0) } scope :opening, -> {where(open_or_not: 1)} scope :mine, -> (author_id){ where(user_id: author_id) } @@ -25,9 +26,11 @@ class Hack < ApplicationRecord def code if hack_codes.count == 1 - tran_base64_decode64(hack_codes.first.code) + #tran_base64_decode64(hack_codes.first.code) + hack_codes.first.code else - tran_base64_decode64(hack_codes.pluck(:code)) + #tran_base64_decode64(hack_codes.pluck(:code)) + hack_codes.pluck(:code) end end diff --git a/app/models/hack_set.rb b/app/models/hack_set.rb index d0518a5b4..5dab862b5 100644 --- a/app/models/hack_set.rb +++ b/app/models/hack_set.rb @@ -1,4 +1,6 @@ class HackSet < ApplicationRecord + validates :input, presence: { message: "测试集输入不能为空" } + validates :output, presence: { message: "测试集输出不能为空" } # 编程题测试集 belongs_to :hack end diff --git a/app/models/hack_user_lastest_code.rb b/app/models/hack_user_lastest_code.rb index 1d3e20f87..b4a707603 100644 --- a/app/models/hack_user_lastest_code.rb +++ b/app/models/hack_user_lastest_code.rb @@ -9,6 +9,7 @@ class HackUserLastestCode < ApplicationRecord has_many :hack_user_codes, dependent: :destroy has_one :hack_user_debug scope :mine, ->(author_id){ find_by(user_id: author_id) } + scope :mine_hack, ->(author_id){ where(user_id: author_id) } scope :passed, -> {where(status: 1)} end diff --git a/app/models/laboratory.rb b/app/models/laboratory.rb index 466e6d4d8..102e964b1 100644 --- a/app/models/laboratory.rb +++ b/app/models/laboratory.rb @@ -54,6 +54,10 @@ class Laboratory < ApplicationRecord main_site? ? Subject.all : Subject.joins(:laboratory_subjects).where(laboratory_subjects: { laboratory_id: id }) end + def all_courses + main_site? || !sync_course ? courses : courses.or(Course.where(school_id: school_id)) + end + def shixun_repertoires where_sql = ShixunTagRepertoire.where("shixun_tag_repertoires.tag_repertoire_id = tag_repertoires.id") diff --git a/app/models/poll.rb b/app/models/poll.rb index 9cb860f61..5c1a9a64c 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -128,7 +128,7 @@ class Poll < ApplicationRecord en_time = end_time else poll_group_setting = poll_group_settings - user_group = course.course_members.where(user_id: user_id).select(:course_group_id) + user_group = course.students.where(user_id: user_id).select(:course_group_id) if user_group.exists? user_group_id = user_group.first&.course_group_id user_p_group_setting = poll_group_setting.where(course_group_id: user_group_id).select(:publish_time,:end_time) @@ -146,12 +146,22 @@ class Poll < ApplicationRecord end #判断当前用户的答题状态 - def check_user_votes_status(user) + def check_user_votes_status(user, poll_status) poll_answer_user = poll_users.where(user_id: user.id).select(:start_at,:end_at,:commit_status) user_status = 2 if poll_answer_user.exists? && (poll_answer_user.first&.start_at.present? || poll_answer_user.first&.end_at.present?) #学生有过答题的,或者立即截止,但学生未做试卷的 user_status = poll_answer_user.first.commit_status end + # 问卷已截止时学生的答题状态需要考虑问卷的状态 + if poll_status > 2 + # 问卷如果还是继续答题状态则自动提交 + if user_status == 0 + poll_end_time = get_poll_times(user.id,false)[:end_time] + poll_answer_user.first.update_attributes!(:commit_status => 1, :end_at => poll_end_time) + user_status = 1 + end + user_status = user_status == 1 ? 1 : 4 + end user_status end diff --git a/app/models/project.rb b/app/models/project.rb index 2e0a8be64..af59f58de 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -7,6 +7,9 @@ class Project < ApplicationRecord has_many :issues has_many :user_grades, dependent: :destroy + has_many :attachments, as: :container, dependent: :destroy + has_one :project_score, dependent: :destroy + has_many :versions, -> { order("versions.effective_date DESC, versions.name DESC") }, dependent: :destroy after_create do SyncTrustieJob.perform_later("project", 1) if allow_sync_to_trustie? diff --git a/app/models/searchable/shixun.rb b/app/models/searchable/shixun.rb index 3229f278f..c574ecb1d 100644 --- a/app/models/searchable/shixun.rb +++ b/app/models/searchable/shixun.rb @@ -39,7 +39,7 @@ module Searchable::Shixun end def should_index? - [0, 1, 2].include?(status) # published + !hidden? && [0, 1, 2].include?(status) # published end def to_searchable_json diff --git a/app/models/shixun.rb b/app/models/shixun.rb index a0f88260b..0f9842739 100644 --- a/app/models/shixun.rb +++ b/app/models/shixun.rb @@ -28,6 +28,7 @@ class Shixun < ApplicationRecord has_one :first_tag_repertoire, through: :first_shixun_tag_repertoire, source: :tag_repertoire has_many :homework_commons_shixuns, class_name: 'HomeworkCommonsShixun' + has_many :fork_shixuns, foreign_key: "fork_from", class_name: 'Shixun' #实训的关卡 has_many :exercise_shixun_challenges, :dependent => :destroy @@ -52,6 +53,7 @@ class Shixun < ApplicationRecord has_many :shixun_reviews, -> {order("shixun_reviews.created_at desc")}, :dependent => :destroy has_many :laboratory_shixuns, dependent: :destroy + belongs_to :laboratory, optional: true scope :search_by_name, ->(keyword) { where("name like ? or description like ? ", "%#{keyword}%", "%#{keyword}%") } @@ -97,7 +99,7 @@ class Shixun < ApplicationRecord end def fork_identifier - self.fork_from.nil? ? "--" : Shixun.where(id: self.fork_from).first.try(:identifier) + self.fork_from.nil? ? "--" : fork_shixuns.first&.identifier end def shixun_status @@ -171,7 +173,7 @@ class Shixun < ApplicationRecord end def owner - User.find(self.user_id) + User.find_by_id(self.user_id) end def shixun_main_name diff --git a/app/models/shixun_tag_repertoire.rb b/app/models/shixun_tag_repertoire.rb index 6cb311f7a..afd956350 100644 --- a/app/models/shixun_tag_repertoire.rb +++ b/app/models/shixun_tag_repertoire.rb @@ -3,5 +3,5 @@ class ShixunTagRepertoire < ApplicationRecord belongs_to :tag_repertoire has_many :memos, :through => :memo_tag_repertoires - has_many :memo_tag_repertoires, :dependent => :destroy + # has_many :memo_tag_repertoires, :dependent => :destroy end diff --git a/app/models/student_work.rb b/app/models/student_work.rb index 8477da774..d4f372823 100644 --- a/app/models/student_work.rb +++ b/app/models/student_work.rb @@ -111,14 +111,14 @@ class StudentWork < ApplicationRecord # 作品总体评价 def overall_appraisal - case self.work_score.to_i - when (90..100) + case (self.work_score.to_f / homework_common.total_score).round(2) + when (0.90..1.00) '优秀' - when (70...90) + when (0.70...0.90) '良好' - when (60...70) + when (0.60...0.70) '及格' - when (0...60) + when (0.00...0.60) '不及格' end end diff --git a/app/models/user.rb b/app/models/user.rb index 74d9b11d2..27c9e03ae 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -329,7 +329,7 @@ class User < ApplicationRecord # 实训路径:合作者、admin def manager_of_subject?(subject) - subject.subject_members.exists?(user_id: id, role: [1,2]) || admin? + subject.subject_members.exists?(user_id: id, role: [1,2]) || admin? || business? end # 实训管理员:实训合作者、admin @@ -699,6 +699,10 @@ class User < ApplicationRecord LimitForbidControl::UserLogin.new(self).clear end + def from_sub_site? + laboratory_id.present? && laboratory_id != 1 + end + protected def validate_password_length # 管理员的初始密码是5位 diff --git a/app/models/version.rb b/app/models/version.rb new file mode 100644 index 000000000..c278ff0a9 --- /dev/null +++ b/app/models/version.rb @@ -0,0 +1,3 @@ +class Version < ApplicationRecord + belongs_to :project +end diff --git a/app/queries/admins/course_list_query.rb b/app/queries/admins/course_list_query.rb new file mode 100644 index 000000000..24eedaf1b --- /dev/null +++ b/app/queries/admins/course_list_query.rb @@ -0,0 +1,30 @@ +class Admins::CourseListQuery < ApplicationQuery + include CustomSortable + + attr_reader :params + + sort_columns :created_at, default_by: :created_at, default_direction: :desc + + def initialize(params) + @params = params + end + + def call + course_lists = CourseList.all + + # 关键字模糊查询 + keyword = params[:keyword].to_s.strip + if keyword.present? + search_type = params[:search_type] || "0" + case search_type + when "0" + course_lists = course_lists.joins(:user) + .where('CONCAT(lastname, firstname) like :keyword', keyword: "%#{keyword}%") + when "1" + course_lists = course_lists.where('name like :keyword', keyword: "%#{keyword}%") + end + end + + custom_sort(course_lists, params[:sort_by], params[:sort_direction]) + end +end \ No newline at end of file diff --git a/app/queries/admins/course_query.rb b/app/queries/admins/course_query.rb new file mode 100644 index 000000000..e883650d0 --- /dev/null +++ b/app/queries/admins/course_query.rb @@ -0,0 +1,44 @@ +class Admins::CourseQuery < ApplicationQuery + include CustomSortable + + attr_reader :params + + sort_columns :created_at, default_by: :created_at, default_direction: :desc, default_table: 'courses' + + def initialize(params) + @params = params + end + + def call + courses = Course.all + + courses = courses.where(id: params[:id]) if params[:id].present? + + # 状态过滤 + status = + case params[:status].to_s.strip + when 'processing' then 0 + when 'ended' then 1 + end + courses = courses.where(is_end: status) if status + + # 单位 + if params[:school_id].present? + courses = courses.where(school_id: params[:school_id]) + end + + # 首页展示 + if params[:homepage_show].present? && params[:homepage_show].to_s == 'true' + courses = courses.where(homepage_show: true) + end + + # 关键字 + keyword = params[:keyword].to_s.strip + if keyword + sql = 'CONCAT(lastname, firstname) LIKE :keyword OR courses.name LIKE :keyword OR course_lists.name LIKE :keyword' + courses = courses.joins(:teacher, :course_list).where(sql, keyword: "%#{keyword}%") + end + + custom_sort(courses, params[:sort_by], params[:sort_direction]) + end +end \ No newline at end of file diff --git a/app/queries/admins/school_query.rb b/app/queries/admins/school_query.rb index 7361588c4..888cded97 100644 --- a/app/queries/admins/school_query.rb +++ b/app/queries/admins/school_query.rb @@ -13,11 +13,10 @@ class Admins::SchoolQuery < ApplicationQuery schools = School.all keyword = strip_param(:keyword) - schools = schools.where('schools.name LIKE ?', "%#{keyword}%") if keyword - - schools = schools.joins(:user_extensions).group(:id) - schools = schools.select('schools.*, COUNT(*) AS users_count') - + Rails.logger.info("###########{keyword}") + if keyword + schools = schools.where('schools.name LIKE ?', "%#{keyword}%") + end custom_sort schools, params[:sort_by], params[:sort_direction] end end \ No newline at end of file diff --git a/app/services/admins/identity_auths/refuse_apply_service.rb b/app/services/admins/identity_auths/refuse_apply_service.rb index 7ac2e6c38..dfc9168a9 100644 --- a/app/services/admins/identity_auths/refuse_apply_service.rb +++ b/app/services/admins/identity_auths/refuse_apply_service.rb @@ -10,6 +10,7 @@ class Admins::IdentityAuths::RefuseApplyService < ApplicationService def call ActiveRecord::Base.transaction do apply.update!(status: 2, remarks: reason) + user.update!(authentication: false) deal_tiding! apply.attachment&.destroy diff --git a/app/services/admins/professional_auths/refuse_apply_service.rb b/app/services/admins/professional_auths/refuse_apply_service.rb index a055488c3..014fbab0b 100644 --- a/app/services/admins/professional_auths/refuse_apply_service.rb +++ b/app/services/admins/professional_auths/refuse_apply_service.rb @@ -10,6 +10,7 @@ class Admins::ProfessionalAuths::RefuseApplyService < ApplicationService def call ActiveRecord::Base.transaction do apply.update!(status: 2, remarks: reason) + user.update!(professional_certification: false) deal_tiding! apply.attachment&.destroy diff --git a/app/services/application_service.rb b/app/services/application_service.rb index 1be6896eb..81c48de95 100644 --- a/app/services/application_service.rb +++ b/app/services/application_service.rb @@ -3,6 +3,12 @@ class ApplicationService Error = Class.new(StandardError) + def regix_emoji content + " " if content.blank? + regex = /[^a-zA-Z0-9\u4E00-\u9FFF]/ + content.gsub(regex, '') + end + private def strip(str) diff --git a/app/services/oauth/create_or_find_qq_account_service.rb b/app/services/oauth/create_or_find_qq_account_service.rb index 92966634c..dafcc3f88 100644 --- a/app/services/oauth/create_or_find_qq_account_service.rb +++ b/app/services/oauth/create_or_find_qq_account_service.rb @@ -17,7 +17,8 @@ class Oauth::CreateOrFindQqAccountService < ApplicationService new_user = true # 新用户 login = User.generate_login('Q') - @user = User.new(login: login, nickname: params.dig('info', 'nickname'), type: 'User', status: User::STATUS_ACTIVE) + #nickname = regix_emoji params.dig('info', 'nickname') + @user = User.new(login: login, type: 'User', status: User::STATUS_ACTIVE) end ActiveRecord::Base.transaction do @@ -31,7 +32,7 @@ class Oauth::CreateOrFindQqAccountService < ApplicationService Util.download_file(params.dig('info', 'image'), avatar_path) end - new_open_user = OpenUsers::QQ.create!(user: user, uid: params['uid'], extra: params.dig('extra', 'raw_info')) + new_open_user = OpenUsers::QQ.create!(user: user, uid: params['uid']) Rails.cache.write(new_open_user.can_bind_cache_key, 1, expires_in: 1.hours) if new_user # 方便后面进行账号绑定 end diff --git a/app/services/oauth/create_or_find_wechat_account_service.rb b/app/services/oauth/create_or_find_wechat_account_service.rb index 372e55900..75091a5c3 100644 --- a/app/services/oauth/create_or_find_wechat_account_service.rb +++ b/app/services/oauth/create_or_find_wechat_account_service.rb @@ -24,7 +24,10 @@ class Oauth::CreateOrFindWechatAccountService < ApplicationService new_user = true # 新用户 login = User.generate_login('w') - @user = User.new(login: login, nickname: result['nickname'], type: 'User', status: User::STATUS_ACTIVE) + # result['nickname'] = regix_emoji(result['nickname']) + @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) + end ActiveRecord::Base.transaction do @@ -39,7 +42,7 @@ class Oauth::CreateOrFindWechatAccountService < ApplicationService Util.download_file(result['headimgurl'], avatar_path) end - new_open_user= OpenUsers::Wechat.create!(user: user, uid: result['unionid'], extra: result) + new_open_user= OpenUsers::Wechat.create!(user: user, uid: result['unionid']) Rails.cache.write(new_open_user.can_bind_cache_key, 1, expires_in: 1.hours) if new_user # 方便后面进行账号绑定 end diff --git a/app/services/subjects/copy_subject_service.rb b/app/services/subjects/copy_subject_service.rb index 5f8481cae..94157dc7b 100644 --- a/app/services/subjects/copy_subject_service.rb +++ b/app/services/subjects/copy_subject_service.rb @@ -5,7 +5,8 @@ class Subjects::CopySubjectService < ApplicationService @subject = subject @user = user @laboratory = laboratory - subject_params = subject.attributes.dup.except('id', 'copy_subject_id', 'user_id', 'homepage_show') + subject_params = subject.attributes.dup.except('id', 'copy_subject_id', 'user_id', 'homepage_show', + 'stages_count', 'shixuns_count', 'stage_shixuns_count') @to_subject = Subject.new(subject_params) end @@ -59,7 +60,7 @@ class Subjects::CopySubjectService < ApplicationService shixun = stage_shixun.shixun to_shixun = Shixun.new to_shixun.attributes = shixun.attributes.dup.except('id', 'user_id', 'identifier', 'homepage_show', - 'use_scope', 'averge_star', 'myshixuns_count') + 'use_scope', 'averge_star', 'myshixuns_count', 'challenges_count') to_shixun.identifier = Util::UUID.generate_identifier(Shixun, 8) to_shixun.user_id = user.id if laboratory diff --git a/app/services/users/apply_authentication_service.rb b/app/services/users/apply_authentication_service.rb index 1b9b02c91..a6b02f431 100644 --- a/app/services/users/apply_authentication_service.rb +++ b/app/services/users/apply_authentication_service.rb @@ -10,7 +10,7 @@ class Users::ApplyAuthenticationService < ApplicationService raise Error, '请先完善基本信息' unless user.profile_completed? Users::ApplyAuthenticationForm.new(params).validate! - raise Error, '您已经申请过实名认证了' if ApplyUserAuthentication.real_name_auth.processing.exists?(user_id: user.id) + # raise Error, '您已经申请过实名认证了' if ApplyUserAuthentication.real_name_auth.processing.exists?(user_id: user.id) user.lastname = params[:name].to_s.strip user.firstname = '' @@ -18,7 +18,9 @@ class Users::ApplyAuthenticationService < ApplicationService user.show_realname = params[:show_realname].to_s == 'true' if params[:show_realname].to_s.present? ActiveRecord::Base.transaction do - user.authentication = false + ApplyUserAuthentication.real_name_auth.processing.where(user_id: user.id).destroy_all + + user.authentication = true user.save! user.user_extension.update!(gender: params[:gender].to_i) if params[:gender].present? diff --git a/app/services/users/apply_professional_auth_service.rb b/app/services/users/apply_professional_auth_service.rb index 81cd11a4c..c94481890 100644 --- a/app/services/users/apply_professional_auth_service.rb +++ b/app/services/users/apply_professional_auth_service.rb @@ -12,15 +12,15 @@ class Users::ApplyProfessionalAuthService < ApplicationService raise Error, '请先完善基本信息' unless user.profile_completed? Users::ApplyProfessionalAuthForm.new(params).validate! - raise Error, '您已经申请过职业认证了' if ApplyUserAuthentication.professional_auth.processing.exists?(user_id: user.id) - - user.professional_certification = false + # raise Error, '您已经申请过职业认证了' if ApplyUserAuthentication.professional_auth.processing.exists?(user_id: user.id) extension = user.user_extension extension.school_id = params[:school_id] extension.department_id = params[:department_id] extension.identity = params[:identity] + user.professional_certification = params[:identity] != "teacher" + extra = params[:extra].to_s.strip.presence if extension.identity.to_s == 'student' extension.technical_title = nil @@ -31,6 +31,7 @@ class Users::ApplyProfessionalAuthService < ApplicationService end ActiveRecord::Base.transaction do + ApplyUserAuthentication.professional_auth.processing.where(user_id: user.id).destroy_all user.save! extension.save! diff --git a/app/views/admins/competition_prize_users/index.xlsx.axlsx b/app/views/admins/competition_prize_users/index.xlsx.axlsx index 63e23a214..0284484dc 100644 --- a/app/views/admins/competition_prize_users/index.xlsx.axlsx +++ b/app/views/admins/competition_prize_users/index.xlsx.axlsx @@ -3,7 +3,7 @@ wb = xlsx_package.workbook wb.styles do |s| blue_cell = s.add_style :bg_color => "FAEBDC", :sz => 10,:height => 25,:b => true, :border => { :style => :thin, :color =>"000000" },:alignment => {wrap_text: true,:horizontal => :center,:vertical => :center} wb.add_worksheet(name: "#{@competition.name}证书审批列表") do |sheet| - sheet.add_row %w(序号 排名 奖项 战队ID 战队名称 姓名 职业 学号 学校名称 学院名称 地区 实名认证 职业认证 手机号码 队长 签领/开户行及银行卡号 审批时间 审批人), :height => 25,:style => blue_cell + sheet.add_row %w(序号 排名 奖项 战队ID 战队名称 姓名 性别 职业 学号 学校名称 学院名称 地区 实名认证 职业认证 手机号码 队长 身份证号 签领/开户行及银行卡号 审批时间 审批人), :height => 25,:style => blue_cell @all_prize_users.each_with_index do |prize_user, index| user = prize_user.user @@ -14,15 +14,17 @@ wb.styles do |s| prize_user.competition_team_id, prize_user.competition_team.name, user.real_name, + user.gender == 1 ? "女" : "男", user.identity, - user.student_id, + user.student_id.present? ? (user.student_id.to_s + "\t") : "--", user.school_name, user.department_name, user.location, user.auth_status, user.pro_status, - user.phone, + user.phone.present? ? (user.phone.to_s + "\t") : "--", prize_user.leader? ? "是" : "-", + user.ID_number.present? ? (user.ID_number.to_s + "\t") : "--", [prize_user.extra&.[]('bank'), prize_user.extra&.[]('second_bank'), prize_user.extra&.[]('card_no')].compact.join('/'), prize_user.approved_at&.strftime('%Y-%m-%d %H:%M'), prize_user.approver&.real_name diff --git a/app/views/admins/course_lists/index.html.erb b/app/views/admins/course_lists/index.html.erb new file mode 100644 index 000000000..cd814ed8a --- /dev/null +++ b/app/views/admins/course_lists/index.html.erb @@ -0,0 +1,22 @@ +<% define_admin_breadcrumbs do %> + <% add_admin_breadcrumb('课程列表') %> +<% end %> + +序号 | +ID | +课程名称 | +课堂数 | +创建者 | +<%= sort_tag('创建时间', name: 'created_at', path: admins_course_lists_path) %> | +操作 | + + + <% if courses.present? %> + <% courses.each_with_index do |course_list,index| %> +
---|---|---|---|---|---|---|
<%= list_index_no(@params_page.to_i, index) %> | +<%= course_list.id %> | +<%= course_list.name %> | + <% course_count = course_list.courses.size %> +<%= course_count %> | +<%= link_to course_list.user.try(:real_name),"/users/#{course_list.user.try(:login)}",target:'_blank' %> | +<%= format_time course_list.created_at %> | ++ <% if course_count == 0 %> + <%= delete_link '删除', admins_course_list_path(course_list, element: ".course-list-item-#{course_list.id}"), class: 'delete-department-action' %> + <% end %> + <%= javascript_void_link '修改', class: 'action', data: { course_list_id: course_list.id, + toggle: 'modal', target: '.admin-merge-course-list-modal', url: merge_admins_course_lists_path } %> + | +
ID | +课堂名称 | +成员 | +资源 | +普通作业 | +分组作业 | +实训作业 | +试卷 | +评测次数 | +私有 | +状态 | +单位 | +创建者 | +<%= sort_tag('创建时间', name: 'created_at', path: admins_courses_path) %> | +首页 | +邮件通知 | +操作 | +
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
<%= course.id %> | ++ <%= link_to(course.name, "/courses/#{course.id}", target: '_blank') %> + | +<%= course.course_members_count %> | +<%= get_attachment_count(course, 0) %> | +<%= course.course_homework_count(1) %> | +<%= course.course_homework_count(3) %> | +<%= course.course_homework_count(4) %> | +<%= course.exercises_count %> | +<%= course.evaluate_count %> | +<%= course.is_public == 1 ? "--" : "√" %> | +<%= course.is_end ? "已结束" : "正在进行" %> | +<%= course.school&.name %> | +<%= course.teacher&.real_name %> | +<%= course.created_at&.strftime('%Y-%m-%d %H:%M') %> | ++ <%= check_box_tag :homepage_show,!course.homepage_show,course.homepage_show,remote:true,data:{id:course.id},class:"course-setting-form" %> + | ++ <%= check_box_tag :email_notify,!course.email_notify,course.email_notify,remote:true,data:{id:course.id},class:"course-setting-form" %> + | ++ <% if course.is_delete == 0 %> + <%= delete_link '删除', admins_course_path(course, element: ".course-item-#{course.id}"), class: 'delete-course-action' %> + <% end %> + | +