diff --git a/Gemfile b/Gemfile index 6cf60e0e..d89f9a24 100644 --- a/Gemfile +++ b/Gemfile @@ -67,6 +67,9 @@ gem 'oauth2' gem 'axlsx', '3.0.0.pre' gem 'axlsx_rails', '0.3.0' +# state machine +gem 'aasm' + #Ruby 2.2+ has removed test/unit from the core library. if RUBY_VERSION>='2.2' gem 'test-unit', '~> 3.0' diff --git a/app/controllers/competition_teams_controller.rb b/app/controllers/competition_teams_controller.rb index 5cac9ef0..0d78fb58 100644 --- a/app/controllers/competition_teams_controller.rb +++ b/app/controllers/competition_teams_controller.rb @@ -38,32 +38,34 @@ class CompetitionTeamsController < ApplicationController end def create - if params[:name] - # 判断用户是否已创建过战队 - if @competition.competition_teams.where(:user_id => User.current.id).count > 0 && !User.current.is_teacher - @status = 1 - else - invite_code = generate_team_code - teacher_id = User.current.user_extensions.identity == 0 ? User.current.id : params[:teacher] - - new_team = CompetitionTeam.create(:competition_id => @competition.id, :name => params[:name], - :invite_code => invite_code, :user_id => User.current.id, :teacher_id => teacher_id) - new_team.team_members << TeamMember.new(:user_id => User.current.id, :role => 1, :competition_id => @competition.id, :is_teacher => User.current.user_extensions.identity == 0 ? 1 : 0) - if params[:member_ids] - params[:member_ids].each do |user_id| - new_team.team_members << TeamMember.new(:user_id => user_id, :role => 2, :competition_id => @competition.id) - end - end - if params[:teacher] && params[:teacher].strip != "" - new_team.team_members << TeamMember.new(:user_id => params[:teacher], :role => 2, :competition_id => @competition.id, :is_teacher => 1) - # 创建成功且配置了指导老师 - @status = 0 - elsif User.current.user_extensions.identity != 0 - # 创建成功未配置指导老师 - @status = 2 - elsif User.current.user_extensions.identity == 0 - @status = 0 - end + # 判断用户是否已创建过战队 + if @competition.competition_teams.where(:user_id => User.current.id).count > 0 && !User.current.is_teacher + @status, @message = -1, '您已创建过战队,不能重复创建' + return + end + + if params[:name].blank? + @status, @message = -1, '战队名称不能为空' + return + end + + is_teacher = User.current.user_extensions.identity == 0 + return unless member_and_teacher_count_valid?(is_teacher) + + ActiveRecord::Base.transaction do + invite_code = generate_team_code + new_team = CompetitionTeam.create(:competition_id => @competition.id, :name => params[:name], + :invite_code => invite_code, :user_id => User.current.id) + new_team.team_members.create!(user_id: User.current.id, role: 1, competition_id: @competition.id, is_teacher: User.current.user_extensions.identity == 0 ? 1 : 0) + + params[:member_ids].try(:each) do |user_id| + next if user_id.to_i == User.current.id + new_team.team_members.create!(user_id: user_id, role: 2, competition_id: @competition.id) + end + + params[:teacher_ids].try(:each) do |user_id| + next if user_id.to_i == User.current.id + new_team.team_members.create!(user_id: user_id, role: 3, competition_id: @competition.id, is_teacher: 1) end end end @@ -89,79 +91,80 @@ class CompetitionTeamsController < ApplicationController end def update - unless @competition.enroll_end_time.present? && @competition.enroll_end_time < Time.now - if params[:name] - teacher_id = User.current.user_extensions.identity == 0 ? User.current.id : params[:teacher] - - @team.update_attributes(:name => params[:name], :teacher_id => teacher_id) - @team.team_members.update_all(:is_teacher => 0) - if @team.user.user_extensions.identity == 0 - @team.team_members.where(:user_id => @team.user_id).update_all(:is_teacher => 1) - end + is_teacher = @team.user.user_extensions.identity == 0 + return unless member_and_teacher_count_valid?(is_teacher) + + ActiveRecord::Base.transaction do + unless @competition.enroll_end_time.present? && @competition.enroll_end_time < Time.now + @team.update_attributes(name: params[:name]) if params[:name].present? - team_member_ids = @team.team_members.where(:role => 2, :is_teacher => 0).map(&:user_id) - new_member_ids = (params[:member_ids] || []).collect(&:to_i) + team_member_ids = @team.team_members.where(role: 2, is_teacher: 0).pluck(:user_id) + new_member_ids = (params[:member_ids].presence || []).map(&:to_i) + new_member_ids << @team.user_id unless is_teacher # 删除的成员 delete_member_ids = team_member_ids - new_member_ids - @team.team_members.where(:role => 2, :user_id => delete_member_ids).destroy_all + @team.team_members.where(role: 2, user_id: delete_member_ids).delete_all # 新增加的成员 (new_member_ids - team_member_ids).each do |user_id| - @team.team_members << TeamMember.new(:user_id => user_id, :role => 2, :competition_id => @competition.id) + next if user_id.to_i == @team.user_id + @team.team_members.create!(user_id: user_id, role: 2, competition_id: @competition.id) end end - end - # 判断之前是否已存在指导老师,不存在则创建 否则更新 - if params[:teacher] && params[:teacher].strip != "" - o_teacher = @team.team_members.where(:is_teacher => 1).first - unless o_teacher.present? && o_teacher.user_id == params[:teacher].to_i - if o_teacher.present? - o_teacher.update_attributes(:user_id => params[:teacher]) - else - teacher = @team.team_members.where(:user_id => params[:teacher]).first - if teacher.present? - teacher.update_column("is_teacher", 1) - else - @team.team_members << TeamMember.new(:user_id => params[:teacher], :role => 2, :competition_id => @competition.id, :is_teacher => 1) - end - end + teacher_ids = @team.teachers.pluck(:user_id) + new_teacher_ids = (params[:teacher_ids].presence || []).map(&:to_i) + new_teacher_ids << @team.user_id if is_teacher + # 删除的老师 + delete_teacher_ids = teacher_ids - new_teacher_ids + @team.team_members.where(role: 3, user_id: delete_teacher_ids).delete_all + # 新增加的老师 + (new_teacher_ids - teacher_ids).each do |user_id| + next if user_id.to_i == @team.user_id + @team.team_members.create!(user_id: user_id, role: 3, competition_id: @competition.id, is_teacher: true) end - @team.update_attributes(:teacher_id => params[:teacher]) - elsif @team.user.user_extensions.identity != 0 - @team.update_attributes(:teacher_id => nil) - @team.team_members.where(:is_teacher => 1).destroy_all end end # @status:提示语标志(0:加入成功;1:邀请码错误;2:已经加入了其他队, 3:超过人数限制,4:已有指导老师,5:只有学生和老师身份的用户才能加入战队) def join_team - team = @competition.competition_teams.where(:invite_code => params[:code]).first - if team.present? - if TeamMember.where(:user_id => User.current.id, :competition_team_id => @competition.competition_teams.map(&:id), :is_teacher => 0).count > 0 - @status = 2 - else - # 老师身份加入战队判断是否已有指导老师 - if User.current.user_extensions.identity == 0 - if team.teacher_id.present? - @status = 4 - else - @status = 0 - team.update_attributes(:teacher_id => User.current.id) - team.team_members << TeamMember.new(:user_id => User.current.id, :role => 2, :competition_id => @competition.id, :is_teacher => 1) - end - elsif User.current.user_extensions.identity == 1 - if team.team_members.count < @competition.max_num.to_i - team.team_members << TeamMember.new(:user_id => User.current.id, :role => 2, :competition_id => @competition.id) - @status = 0 - else - @status = 3 - end - else - @status = 5 - end + team = @competition.competition_teams.where(invite_code: params[:code]).first + if team.blank? + @status, @message = -1, '战队邀请码错误' + return + end + + if TeamMember.where(:user_id => User.current.id, :competition_team_id => @competition.competition_teams.map(&:id), :is_teacher => 0).count > 0 + @status, @message = -1, '您已加入战队,不能重复加' + return + end + + if team.team_members.where(user_id: User.current.id).exists? + @status, @message = -1, '您已加入该战队' + return + end + + # 老师身份加入战队 + if User.current.user_extensions.identity == 0 + teacher_staff = @competition.where(category: 'teacher').first + + if teacher_staff.blank? + @status, @message = -1, '该竞赛不能配备导师' + return end + + if team.teachers.count + 1 > teacher_staff.maximum + @status, @message = -1, '该战队导师人数已满' + return + end + team.team_members.create!(user_id: User.current.id, role: 3, competition_id: @competition.id, is_teacher: true) else - @status = 1 + max_member_count = @competition.where('category != "teacher"').sum(:maximum) + if team.members.count + 1 > max_member_count + @status, @message = -1, '该战队成员人数已满' + return + end + + team.team_members.create!(user_id: User.current.id, role: 2, competition_id: @competition.id) end end @@ -169,9 +172,6 @@ class CompetitionTeamsController < ApplicationController def exit_team team_member = @team.team_members.where(:user_id => User.current.id).first if team_member.present? - if team_member.is_teacher - @team.update_attributes(:teacher_id => nil) - end if team_member.user_id != @team.user_id team_member.destroy @status = 1 @@ -214,4 +214,33 @@ class CompetitionTeamsController < ApplicationController rescue ActiveRecord::RecordNotFound render_404 end + + def member_and_teacher_count_valid?(is_teacher) + teacher_staff = @competition.competition_staffs.where(category: 'teacher').first + teacher_count = params[:teacher_ids].try(:size) || 0 + teacher_count += 1 if is_teacher + # 检查老师数量 + if teacher_staff.blank? && teacher_count > 0 + @status, @message = -1, '该竞赛不能配备导师' + return false + elsif teacher_staff.present? && (teacher_staff.minimum > teacher_count || teacher_staff.maximum < teacher_count) + @status = -1 + @message = teacher_staff.maximum == teacher_staff.maximum ? "导师数量应为#{teacher_staff.minimum}人" : "导师数量应为#{teacher_staff.minimum}-#{teacher_staff.maximum}人" + return false + end + + member_relations = @competition.competition_staffs.where('category != "teacher"') + min_member_count = member_relations.sum(:minimum) + max_member_count = member_relations.sum(:maximum) + member_count = params[:member_ids].try(:size) || 0 + member_count += 1 unless is_teacher + # 检查成员数据 + if min_member_count > member_count || member_count > max_member_count + @status = -1 + @message = min_member_count == max_member_count ? "成员数量应为#{max_member_count}人" : "成员数量应为#{min_member_count}-#{max_member_count}人" + return false + end + + true + end end diff --git a/app/controllers/competitions_controller.rb b/app/controllers/competitions_controller.rb index 384bf4df..b43bb5c8 100644 --- a/app/controllers/competitions_controller.rb +++ b/app/controllers/competitions_controller.rb @@ -110,8 +110,12 @@ class CompetitionsController < ApplicationController @team_members_count = TeamMember.where(:competition_team_id => @teams.pluck(:id)).count @is_enroll = CompetitionTeam.where(:id => TeamMember.where(:user_id => @user, :competition_team_id => @competition.competition_teams.map(&:id)).pluck(:competition_team_id)).reorder("created_at desc") - @show_notice = (@competition.identifier == "gcc-dev-2018" || @competition.identifier == "gcc-annotation-2018") && @competition.competition_teams.where(:user_id => User.current.id, :teacher_id => nil).count > 0 - @teams = paginateHelper @teams, 50 + @show_notice = (@competition.identifier == "gcc-dev-2018" || @competition.identifier == "gcc-annotation-2018") && + @competition.competition_teams.joins(:team_members).where(:user_id => User.current.id).group('competition_teams.id').sum('IF(team_members.is_teacher=1, 1, 0)').values.any?(&:zero?) + @teams = paginateHelper @teams.includes(:user, teachers: :user, members: :user), 50 + + @minimum_staff = @competition.competition_staffs.sum(:minimum) + @maximum_staff = @competition.competition_staffs.sum(:maximum) respond_to do |format| format.js format.html @@ -458,41 +462,51 @@ class CompetitionsController < ApplicationController def competition_setting # @competition = Competition.find params[:id] - if params[:md_name] - md_modules = @competition.competition_modules.where(:md_edit => true) - md_modules.destroy_all if md_modules - params[:md_name].each_with_index do |name, index| - hidden = params[:md_checked][index].to_i == 0 ? 1 : 0 - cm = CompetitionModule.create(:competition_id => @competition.id,:name => name, :position => params[:md_position][index], :hidden => hidden, :md_edit => true) - # 创建md_contents - CompetitionModuleMdContent.create(:competition_module_id => cm.id) + ActiveRecord::Base.transaction do + if params[:md_name] + md_modules = @competition.competition_modules.where(:md_edit => true) + md_modules.destroy_all if md_modules + params[:md_name].each_with_index do |name, index| + hidden = params[:md_checked][index].to_i == 0 ? 1 : 0 + cm = CompetitionModule.create(:competition_id => @competition.id,:name => name, :position => params[:md_position][index], :hidden => hidden, :md_edit => true) + # 创建md_contents + CompetitionModuleMdContent.create(:competition_module_id => cm.id) + end end - end - if params[:competition_module] - @competition.competition_modules.where(:id => params[:competition_module], :md_edit => false).update_all(:hidden => 0) - none_modules = @competition.competition_modules.where("name != '首页' and md_edit = false").map(&:id).join(",").split(",") - params[:competition_module] - @competition.competition_modules.where(:id => none_modules).update_all(:hidden => 1) - end - if params[:name] - @competition.competition_modules.where("name not in ('首页', '报名', '通知公告', '排行榜', '资料下载') and md_edit = false").each_with_index do |mod, index| - mod.update_attribute("name", params[:name][index]) + if params[:competition_module] + @competition.competition_modules.where(:id => params[:competition_module], :md_edit => false).update_all(:hidden => 0) + none_modules = @competition.competition_modules.where("name != '首页' and md_edit = false").map(&:id).join(",").split(",") - params[:competition_module] + @competition.competition_modules.where(:id => none_modules).update_all(:hidden => 1) end - end - if params[:url] - @competition.competition_modules.where("name not in ('首页', '报名', '通知公告', '排行榜') and md_edit = false").each_with_index do |mod, index| - mod.update_attribute("url", params[:url][index]) + if params[:name] + @competition.competition_modules.where("name not in ('首页', '报名', '通知公告', '排行榜', '资料下载') and md_edit = false").each_with_index do |mod, index| + mod.update_attribute("name", params[:name][index]) + end end - end - if params[:position] - @competition.competition_modules.where(:md_edit => false).each_with_index do |mod, index| - mod.update_attribute("position", params[:position][index]) + if params[:url] + @competition.competition_modules.where("name not in ('首页', '报名', '通知公告', '排行榜') and md_edit = false").each_with_index do |mod, index| + mod.update_attribute("url", params[:url][index]) + end end - end - @competition.update_attributes(:identifier => params[:identifier], :min_num => params[:min_num], :max_num => params[:max_num], :enroll_end_time => params[:enroll_end_time]) - if params[:new_name] - params[:new_name].each_with_index do |new_module, index| - @competition.competition_modules << CompetitionModule.new(:name => new_module, :position => params[:new_position][index], :hidden => 0, :url => params[:new_url][index]) + if params[:position] + @competition.competition_modules.where(:md_edit => false).each_with_index do |mod, index| + mod.update_attribute("position", params[:position][index]) + end + end + @competition.update_attributes(:identifier => params[:identifier], :enroll_end_time => params[:enroll_end_time]) + + if params[:competition_staffs].present? + @competition.competition_staffs.delete_all + params[:competition_staffs].each_with_index do |staff_params, index| + @competition.competition_staffs.create(staff_params.merge(position: index + 1)) + end + end + + if params[:new_name] + params[:new_name].each_with_index do |new_module, index| + @competition.competition_modules << CompetitionModule.new(:name => new_module, :position => params[:new_position][index], :hidden => 0, :url => params[:new_url][index]) + end end end end diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb index 669cc58f..10332752 100644 --- a/app/controllers/courses_controller.rb +++ b/app/controllers/courses_controller.rb @@ -1194,12 +1194,14 @@ class CoursesController < ApplicationController @exercises = @course.exercises.where("publish_time <= '#{Time.now}'").order("publish_time asc, created_at asc") @tasks = @course.graduation_tasks.where("publish_time <= '#{Time.now}'").order("publish_time asc, created_at asc") +=begin @homeworks.where(:homework_type => 4).each do |homework| items = homework.student_works.where("work_status != 0") if items.count == 0 && homework.publish_time < Time.now && !@course.is_end update_shixun_work_status homework end end +=end respond_to do |format| format.xls { @@ -2383,12 +2385,13 @@ class CoursesController < ApplicationController blue = Spreadsheet::Format.new :color => :blue, :weight => :bold, :size => 10 #sheet1.row(0).default_format = blue #sheet1.row(0).concat([l(:excel_user_id),l(:excel_user_name),l(:excel_nickname),l(:excel_student_id),l(:excel_mail),l(:excel_class),l(:excel_f_score),l(:excel_commit_time)]) + teacher_co = (searchTeacherAndAssistant course).map{|member| member.user.show_real_name}.join('、') sheet1[0,0] = "课程编号" sheet1[0,1] = course.id sheet1[1,0] = "课程名称" sheet1[1,1] = course.name sheet1[2,0] = "教师团队" - sheet1[2,1] = (searchTeacherAndAssistant course).map{|member| member.user.show_real_name}.join('、') + sheet1[2,1] = teacher_co sheet1[3,0] = "主讲教师" sheet1[3,1] = course.teacher.show_real_name sheet1[4,0] = "排名" @@ -2401,16 +2404,16 @@ class CoursesController < ApplicationController homeworks.where(:homework_type => 4).each do |homework| sheet1[4,current_col+=1] = "#{homework.name}" end - for i in 0 ... homeworks.where(:homework_type => 1).count + for i in 0 ... homeworks.where(:homework_type => 1).size sheet1[4,current_col+=1] = "普通作业第"+(i+1).to_s+"次" end - for i in 0 ... homeworks.where(:homework_type => 3).count + for i in 0 ... homeworks.where(:homework_type => 3).size sheet1[4,current_col+=1] = "分组作业第"+(i+1).to_s+"次" end - for i in 0 ... exercises.count + for i in 0 ... exercises.size sheet1[4,current_col+=1] = "试卷第"+(i+1).to_s+"次" end - for i in 0 ... tasks.count + for i in 0 ... tasks.size sheet1[4,current_col+=1] = "毕设任务第"+(i+1).to_s+"次" end @@ -2511,15 +2514,15 @@ class CoursesController < ApplicationController sheet = book.create_worksheet :name => "分班信息" sheet.row(0).concat(["课程编号", course.id]) sheet.row(1).concat(["课程名称", course.name]) - sheet.row(2).concat(["教师团队", (searchTeacherAndAssistant course).map{|member| member.user.show_real_name}.join('、')]) + sheet.row(2).concat(["教师团队", teacher_co]) sheet.row(3).concat(["主讲教师", course.teacher.show_real_name]) sheet.row(4).concat(["序号", "分班名称", "邀请码", "学生数量"]) current_row = 5 - course.course_groups.each do |course_group| + course.course_groups.includes(:members).each do |course_group| sheet[current_row,0]= current_row - 4 sheet[current_row,1]= course_group.name sheet[current_row,2]= course_group.invite_code - sheet[current_row,3]= course_group.members.count + sheet[current_row,3]= course_group.members.size current_row += 1 end end @@ -2530,7 +2533,7 @@ class CoursesController < ApplicationController sheet2[1,0] = "课程名称" sheet2[1,1] = course.name sheet2[2,0] = "教师团队" - sheet2[2,1] = (searchTeacherAndAssistant course).map{|member| member.user.show_real_name}.join('、') + sheet2[2,1] = teacher_co sheet2[3,0] = "主讲教师" sheet2[3,1] = course.teacher.show_real_name sheet2.row(4).concat(["排名","学生姓名","昵称","学号","分班","作业完成数(*10)","试卷完成数(*10)","问卷完成数(*7)","资源发布数(*5)","帖子发布数(*2)","帖子回复数(*1)","作业回复数(*1)","活跃度"]) @@ -2559,14 +2562,14 @@ class CoursesController < ApplicationController count_row += 1 end - homeworks.where(:homework_type => 4).includes(:student_works).each_with_index do |home, i| + homeworks.where(:homework_type => 4).includes(:score_student_works).each_with_index do |home, i| sheet = book.create_worksheet :name => "#{home.name}" sheet[0,0] = "课程编号" sheet[0,1] = course.id sheet[1,0] = "课程名称" sheet[1,1] = course.name sheet[2,0] = "教师团队" - sheet[2,1] = (searchTeacherAndAssistant course).map{|member| member.user.show_real_name}.join('、') + sheet[2,1] = teacher_co sheet[3,0] = "主讲教师" sheet[3,1] = course.teacher.show_real_name sheet[3,0] = "作业批次" @@ -2575,11 +2578,11 @@ class CoursesController < ApplicationController sheet[3,1] = home.name sheet.row(4).concat([l(:excel_rank),l(:excel_user_name),l(:excel_nickname),l(:excel_student_id),l(:excel_homework_des),l(:excel_l_penalty),l(:excel_f_score),l(:excel_commit_time)]) count_row = 5 - items = home.student_works.where("work_status != 0").order("work_score desc") - if items.count == 0 && home.publish_time < Time.now && !course.is_end - update_shixun_work_status home - items = StudentWork.where("work_status != 0 and homework_common_id = #{home.id}").order("work_score desc") - end + items = home.score_student_works + # if items.count == 0 && home.publish_time < Time.now && !course.is_end + # update_shixun_work_status home + # items = StudentWork.where("work_status != 0 and homework_common_id = #{home.id}").order("work_score desc") + # end items.each_with_index do |stu, j| sheet[count_row,0]= j + 1 sheet[count_row,1] = stu.user.show_real_name @@ -2593,14 +2596,14 @@ class CoursesController < ApplicationController end end - homeworks.where(:homework_type => 1).includes(:student_works).each_with_index do |home, i| + homeworks.where(:homework_type => 1).includes(:score_student_works).each_with_index do |home, i| sheet = book.create_worksheet :name => "普通作业第#{i+1}次" sheet[0,0] = "课程编号" sheet[0,1] = course.id sheet[1,0] = "课程名称" sheet[1,1] = course.name sheet[2,0] = "教师团队" - sheet[2,1] = (searchTeacherAndAssistant course).map{|member| member.user.show_real_name}.join('、') + sheet[2,1] = teacher_co sheet[3,0] = "主讲教师" sheet[3,1] = course.teacher.show_real_name sheet[3,0] = "作业批次" @@ -2615,7 +2618,7 @@ class CoursesController < ApplicationController l(:excel_t_score),l(:excel_ta_score),l(:excel_l_penalty),l(:excel_f_score),l(:excel_commit_time)]) end count_row = 5 - items = home.student_works.where("work_status != 0").order("work_score desc") + items = home.score_student_works items.each_with_index do |stu, j| sheet[count_row,0]= j + 1 sheet[count_row,1] = stu.user.show_real_name @@ -2640,14 +2643,14 @@ class CoursesController < ApplicationController end - homeworks.where(:homework_type => 3).includes(:student_works).each_with_index do |home, i| + homeworks.where(:homework_type => 3).includes(:score_student_works).each_with_index do |home, i| sheet = book.create_worksheet :name => "分组作业第#{i+1}次" sheet[0,0] = "课程编号" sheet[0,1] = course.id sheet[1,0] = "课程名称" sheet[1,1] = course.name sheet[2,0] = "教师团队" - sheet[2,1] = (searchTeacherAndAssistant course).map{|member| member.user.show_real_name}.join('、') + sheet[2,1] = teacher_co sheet[3,0] = "主讲教师" sheet[3,1] = course.teacher.show_real_name sheet[3,0] = "作业批次" @@ -2663,7 +2666,7 @@ class CoursesController < ApplicationController l(:excel_t_score),l(:excel_ta_score),l(:excel_l_penalty),l(:excel_f_score),l(:excel_commit_time)]) end count_row = 5 - items = home.student_works.where("work_status != 0").order("work_score desc") + items = home.score_student_works items.each_with_index do |stu, j| sheet[count_row,0] = j + 1 sheet[count_row,1] = stu.user.show_real_name @@ -2688,14 +2691,14 @@ class CoursesController < ApplicationController end end - exercises.each_with_index do |exercise, i| + exercises.includes(:score_exercise_users).each_with_index do |exercise, i| sheet = book.create_worksheet :name => "试卷第#{i+1}次" sheet[0,0] = "课程编号" sheet[0,1] = course.id sheet[1,0] = "课程名称" sheet[1,1] = course.name sheet[3,0] = "教师团队" - sheet[3,1] = (searchTeacherAndAssistant course).map{|member| member.user.show_real_name}.join('、') + sheet[3,1] = teacher_co sheet[3,0] = "主讲教师" sheet[3,1] = course.teacher.show_real_name sheet[3,0] = "试卷批次" @@ -2705,7 +2708,7 @@ class CoursesController < ApplicationController sheet.row(4).concat([l(:excel_rank),l(:excel_user_name),l(:excel_nickname),l(:excel_student_id),l(:excel_objective_score),l(:excel_subjective_score),l(:excel_f_score),l(:excel_answer_time)]) count_row = 5 - items = exercise.exercise_users.where("commit_status != 0").order("score desc") + items = exercise.score_exercise_users items.each_with_index do |stu, j| sheet[count_row,0] = j + 1 sheet[count_row,1] = stu.user.show_real_name @@ -2726,7 +2729,7 @@ class CoursesController < ApplicationController sheet[1,0] = "课程名称" sheet[1,1] = course.name sheet[2,0] = "教师团队" - sheet[2,1] = (searchTeacherAndAssistant course).map{|member| member.user.show_real_name}.join('、') + sheet[2,1] = teacher_co sheet[3,0] = "主讲教师" sheet[3,1] = course.teacher.show_real_name sheet[3,0] = "作业批次" diff --git a/app/controllers/exercise_controller.rb b/app/controllers/exercise_controller.rb index ee5705fb..9a13bc43 100644 --- a/app/controllers/exercise_controller.rb +++ b/app/controllers/exercise_controller.rb @@ -879,7 +879,7 @@ class ExerciseController < ApplicationController if @order == "student_id" @exercise_users_list = @exercise_users_list.includes(:user => {:user_extensions => []}).order("user_extensions.student_id #{@b_sort}") else - @exercise_users_list = @exercise_users_list.includes(:user => {:user_extensions => []}).order("#{@order} #{@b_sort}") + @exercise_users_list = @exercise_users_list.includes(:user => {:user_extensions => []}).order("#{@order} #{@b_sort}, id desc") end end diff --git a/app/controllers/libraries_controller.rb b/app/controllers/libraries_controller.rb new file mode 100644 index 00000000..8d1eeb06 --- /dev/null +++ b/app/controllers/libraries_controller.rb @@ -0,0 +1,105 @@ +class LibrariesController < ApplicationController + layout 'base_library' + + before_filter :require_login + + def index + libraries = Library.where(nil) + + libraries = + if params[:type] == 'mine' + libraries.where(user_id: current_user.id).order('created_at desc') + else + libraries.where(status: :published).order('visited_count desc') + end + + search = params[:search].to_s.strip + libraries = libraries.where('title LIKE :search OR uuid LIKE :search', search: "%#{search}%") if search.present? + + per_page = params[:per_page].to_i <= 0 ? 20 : params[:per_page].to_i + @libraries = paginateHelper libraries.includes(user: :user_extensions), per_page + end + + def show + @library = Library.find(params[:id]) + return redirect_to libraries_path unless admin_or_self? + + @library_applies = @library.library_applies.where(status: :refused).order('created_at desc') + @library.increment_visited_count! + end + + def new + @library = current_user.libraries.new + end + + def create + @library = current_user.libraries.new + Libraries::SaveService.new(@library, current_user, form_params).call + if with_publish? + Libraries::SubmitService.new(@library).call + redirect_to publish_success_libraries_path + else + flash[:message] = '保存成功' + render 'new' + end + rescue ActiveRecord::RecordInvalid => _ + render 'new' + rescue Libraries::SubmitService::Error => ex + flash[:message] = ex.message + render 'new' + end + + def edit + @library = current_library + redirect_to library_path(id: @library.id) unless @library.editable? + end + + def update + @library = current_library + Libraries::SaveService.new(@library, current_user, form_params).call + if with_publish? + Libraries::SubmitService.new(@library).call + redirect_to publish_success_libraries_path + else + flash[:message] = '保存成功' + render 'edit' + end + rescue ActiveRecord::RecordInvalid => _ + render 'edit' + rescue Libraries::SubmitService::Error => ex + flash[:message] = ex.message + render 'edit' + end + + def publish + Libraries::SubmitService.new(current_library).call + render json: { status: 0 } + rescue Libraries::SubmitService::Error => ex + render json: { status: 0, message: ex.message } + end + + def publish_success + end + + private + + def current_library + @_current_library ||= current_user.libraries.find(params[:id]) + end + + def form_params + @_form_params ||= begin + hash = params[:library].presence || {} + hash[:attachment_ids] = (params[:attachments].presence || []).values.map{|h| h[:attachment_id]} + hash + end + end + + def with_publish? + params[:apply_publish].to_s == 'true' + end + + def admin_or_self? + @library.user_id == current_user.id || current_user.admin? + end +end \ No newline at end of file diff --git a/app/controllers/managements/library_applies_controller.rb b/app/controllers/managements/library_applies_controller.rb new file mode 100644 index 00000000..512f47b4 --- /dev/null +++ b/app/controllers/managements/library_applies_controller.rb @@ -0,0 +1,47 @@ +class Managements::LibraryAppliesController < Managements::BaseController + before_filter :set_menu_type + + def index + applies = LibraryApply.order('library_applies.updated_at desc') + + search = params[:search].to_s.strip + if search.present? + applies = applies.joins(:library) + .where('libraries.uuid like :search or libraries.title like :search', search: "%#{search}%") + end + + applies = applies.where(status: params[:status].presence || :pending) + + @library_applies = paginateHelper applies.includes(library: { user: :user_extensions }) + + respond_to do |format| + format.js + format.html + end + end + + def agree + Libraries::AgreeApplyService.new(current_library_apply, current_user).call + render json: { status: 0 } + rescue Libraries::AgreeApplyService::Error => e + render json: { status: -1, message: e.message } + end + + def refuse + Libraries::RefuseApplyService.new(current_library_apply, current_user, reason: params[:reason]).call + render json: { status: 0 } + rescue Libraries::RefuseApplyService::Error => e + render json: { status: -1, message: e.message } + end + + private + + def current_library_apply + @_current_library_apply ||= LibraryApply.find(params[:id]) + end + + def set_menu_type + @menu_type = 10 + @sub_type = 8 + end +end \ No newline at end of file diff --git a/app/controllers/shixuns_controller.rb b/app/controllers/shixuns_controller.rb index 744dd683..965f15f3 100644 --- a/app/controllers/shixuns_controller.rb +++ b/app/controllers/shixuns_controller.rb @@ -749,6 +749,7 @@ class ShixunsController < ApplicationController @main_type = MirrorRepository.published_main_mirror @small_type = MirrorRepository.published_small_mirror + respond_to do |format| format.html{render :layout => 'base_edu'} format.json @@ -817,7 +818,7 @@ class ShixunsController < ApplicationController ShixunServiceConfig.create!(:shixun_id => @shixun.id, :mirror_repository_id => mirror) end end - # 自动构建版本库 + #自动构建版本库 repository = Repository.new repository.shixun = @shixun repository.type = 'Repository::Gitlab' @@ -877,6 +878,16 @@ class ShixunsController < ApplicationController ShixunTagRepertoire.create!(:tag_repertoire_id => str.tag_repertoire_id, :shixun_id => new_shixun.id) end + # 同步配置 + @shixun.shixun_service_configs.each do |config| + ShixunServiceConfig.create!(:shixun_id => new_shixun.id, + :cpu_limit => config.cpu_limit, + :lower_cpu_limit => config.lower_cpu_limit, + :memory_limit => config.memory_limit, + :request_limit => config.request_limit, + :mirror_repository_id => config.mirror_repository_id) + end + # 同步复制版本库,先fork再修改版本库名 # eduforge用户作为版本库的创建者 repository = Repository.new @@ -1050,6 +1061,7 @@ class ShixunsController < ApplicationController mirror_ids = (@shixun.shixun_mirror_repositories.blank? ? [] : @shixun.shixun_mirror_repositories.map(&:id)) update_miiror_id = [] @shixun.shixun_mirror_repositories.destroy_all + if params[:main_type].present? update_miiror_id << params[:main_type].to_i ShixunMirrorRepository.create(:shixun_id => @shixun.id, :mirror_repository_id => params[:main_type]) @@ -1061,21 +1073,18 @@ class ShixunsController < ApplicationController ShixunMirrorRepository.create(:shixun_id => @shixun.id, :mirror_repository_id => mirror) end end - # 超级管理员才能保存 中间层服务器pod信息的配置 - if User.current.admin? || User.current.business? - @shixun.shixun_service_configs.each_with_index do |config, index| - config.update_attributes(:cpu_limit => params[:cpu_limit][index], - :lower_cpu_limit => params[:lower_cpu_limit][index], - :memory_limit => params[:memory_limit][index], - # :resource_limit => params[:resource_limit][index], - :request_limit => params[:request_limit][index], - :mirror_repository_id => params[:mirror_id][index]) - end + @shixun.shixun_service_configs.destroy_all + params[:mirror_id].each_with_index do |mirror_id, index| + ShixunServiceConfig.create!(:shixun_id => @shixun.id, + :cpu_limit => params[:cpu_limit][index], + :lower_cpu_limit => params[:lower_cpu_limit][index], + :memory_limit => params[:memory_limit][index], + # :resource_limit => params[:resource_limit][index], + :request_limit => params[:request_limit][index], + :mirror_repository_id => mirror_id) end - - ActiveRecord::Base.transaction do begin @shixun.save! @@ -1160,6 +1169,8 @@ class ShixunsController < ApplicationController @small_type = MirrorRepository.published_small_mirror @shixun_main_mirror = @shixun.mirror_repositories.published_main_mirror.first # 权限 + logger.info("###########{User.current.admin?}") + logger.info("#########business:##{User.current.business?}") @power = (@shixun.status < 2 ? true : ( User.current.admin? ? true : false)) # unless @repository.nil? # gitlab_address = Redmine::Configuration['gitlab_address'] diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index cc93b840..74ecd8c4 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -277,7 +277,7 @@ module ApplicationHelper :cpuLimit => config.cpu_limit, :cpuRequest => config.lower_cpu_limit, :memoryLimit => "#{config.memory_limit}M", - :memoryRequest => "#{config.request_limit}", + :memoryRequest => "#{config.request_limit}M", :resourceLimit => "#{config.resource_limit}K", :type => mirror.try(:main_type) == "1" ? "main" : "sub"} end @@ -745,16 +745,17 @@ module ApplicationHelper when 9 sub_type == 1 ? "实训留言列表" : "" when 10 - sub_type == 1 ? "实名认证" : - (sub_type == 2 ? "试用授权" : - (sub_type == 3 ? "部门审批" : - (sub_type == 4 ? "单位审批" : - (sub_type == 5 ? "实训发布" : - (sub_type == 6 ? "实训课程发布" : "职业认证") - ) - ) - ) - ) + case sub_type + when 1 then '实名认证' + when 2 then '试用授权' + when 3 then '部门审批' + when 4 then '单位审批' + when 5 then '实训发布' + when 6 then '实训课程发布' + when 7 then '职业认证' + when 8 then '文库发布' + else '职业认证' + end when 11 "工程认证+" when 12 @@ -3079,7 +3080,7 @@ module ApplicationHelper elsif @syllabus title << (@syllabus.title.nil? ? "课堂" : @syllabus.title) else - title << (User.current.id == 2 ? "未登录" : User.current.show_name) + title << (User.current.anonymous? ? "Educoder实践教学" : User.current.show_name) end # if first_page.nil? || first_page.web_title.nil? # title << Setting.app_title unless Setting.app_title == title.last @@ -6610,12 +6611,14 @@ def update_shixun_work_status homework compelete_status = 1 end end - if setting_time.end_time > Time.now - work.update_attributes(:work_status => 1, :late_penalty => 0, :commit_time => myshixun.updated_at, :update_time => myshixun.updated_at, :myshixun_id => myshixun.id, :compelete_status => compelete_status) - else - work.update_attributes(:work_status => ((myshixun.is_complete? && (myshixun.done_time < setting_time.end_time)) ? 1 : 2), :late_penalty => (myshixun.is_complete? && (myshixun.done_time < setting_time.end_time) ? 0 : homework.late_penalty), :commit_time => myshixun.updated_at, :update_time => myshixun.updated_at, :myshixun_id => myshixun.id, :compelete_status => compelete_status) + if setting.publish_time && setting.publish_time < Time.now && setting_time.end_time + if setting_time.end_time > Time.now + work.update_attributes(:work_status => 1, :late_penalty => 0, :commit_time => myshixun.updated_at, :update_time => myshixun.updated_at, :myshixun_id => myshixun.id, :compelete_status => compelete_status) + else + work.update_attributes(:work_status => ((myshixun.is_complete? && (myshixun.done_time < setting_time.end_time)) ? 1 : 2), :late_penalty => (myshixun.is_complete? && (myshixun.done_time < setting_time.end_time) ? 0 : homework.late_penalty), :commit_time => myshixun.updated_at, :update_time => myshixun.updated_at, :myshixun_id => myshixun.id, :compelete_status => compelete_status) + end + set_shixun_final_score work, homework.homework_detail_manual.answer_open_evaluation, homework_challenge_settings end - set_shixun_final_score work, homework.homework_detail_manual.answer_open_evaluation, homework_challenge_settings end # 更新所有学生的效率分 update_student_eff_score HomeworkCommon.where(:id => homework.id).first @@ -7448,6 +7451,8 @@ def tiding_url tiding project_pull_requests_path(tiding.parent_container_id) when 'Department' my_account_path + when 'Library' + tiding.tiding_type == 'Apply' ? library_applies_path : library_path(tiding.container_id) end end diff --git a/app/libs/util.rb b/app/libs/util.rb new file mode 100644 index 00000000..e72029ae --- /dev/null +++ b/app/libs/util.rb @@ -0,0 +1,7 @@ +module Util + module_function + + def generate_time_uuid + "#{Time.zone.now.strftime('%Y%m%d%H%M%S')}#{Random.rand(10**8).to_i}" + end +end \ No newline at end of file diff --git a/app/models/competition.rb b/app/models/competition.rb index 9b421ed9..9506b724 100644 --- a/app/models/competition.rb +++ b/app/models/competition.rb @@ -13,6 +13,7 @@ class Competition < ActiveRecord::Base has_many :chart_rules, :dependent => :destroy has_many :competition_scores, :dependent => :destroy has_many :competition_text_configs, :dependent => :destroy + has_many :competition_staffs, dependent: :destroy acts_as_attachable after_create :create_competition_modules diff --git a/app/models/competition_staff.rb b/app/models/competition_staff.rb new file mode 100644 index 00000000..bfa1daba --- /dev/null +++ b/app/models/competition_staff.rb @@ -0,0 +1,22 @@ +class CompetitionStaff < ActiveRecord::Base + default_scope order: 'position asc' + + attr_accessible :minimum, :maximum, :category, :position + + belongs_to :competition + + validates :position, numericality: { only_integer: true } + validates :minimum, numericality: { only_integer: true, greater_than: 0 } + validates :maximum, numericality: { only_integer: true, greater_than_or_equal_to: lambda { |obj| obj.minimum } } + validates :category, presence: true, inclusion: { in: %w(all teacher student profession) } + + def category_text + I18n.t("competition_staff.category.#{category}", locale: 'zh') + end + + def self.category_options + %w(all teacher student profession).map do |category| + [I18n.t("competition_staff.category.#{category}", locale: 'zh'), category] + end + end +end \ No newline at end of file diff --git a/app/models/competition_team.rb b/app/models/competition_team.rb index 804854f4..84dcac81 100644 --- a/app/models/competition_team.rb +++ b/app/models/competition_team.rb @@ -2,7 +2,10 @@ class CompetitionTeam < ActiveRecord::Base belongs_to :user belongs_to :competition + has_many :team_members, :dependent => :destroy + has_many :members, conditions: 'is_teacher = 0', class_name: 'TeamMember' + has_many :teachers, conditions: 'is_teacher = 1', class_name: 'TeamMember' has_many :competition_scores, :dependent => :destroy # team_type 0:组队 1:个人 # attr_accessible :invite_code, :name, :team_type diff --git a/app/models/exercise.rb b/app/models/exercise.rb index 47993cf9..f82b6047 100644 --- a/app/models/exercise.rb +++ b/app/models/exercise.rb @@ -7,6 +7,7 @@ class Exercise < ActiveRecord::Base has_many :exercise_group_settings, :dependent => :destroy has_many :exercise_questions, :dependent => :destroy,:order => "#{ExerciseQuestion.table_name}.question_number" has_many :exercise_users, :dependent => :destroy, :conditions => "exercise_users.is_delete = 0" + has_many :score_exercise_users, :conditions => "exercise_users.is_delete = 0 and commit_status != 0", :order => "exercise_users.score desc" has_many :users, :through => :exercise_users #该测试被哪些用户提交答案过 has_many :course_acts, :class_name => 'CourseActivity',:as =>:course_act ,:dependent => :destroy # 课程消息 diff --git a/app/models/homework_common.rb b/app/models/homework_common.rb index af466de3..b0482450 100644 --- a/app/models/homework_common.rb +++ b/app/models/homework_common.rb @@ -28,6 +28,7 @@ class HomeworkCommon < ActiveRecord::Base # has_many :homework_tests, :dependent => :destroy # has_many :homework_samples, :dependent => :destroy has_many :student_works, :conditions => "student_works.is_test=0 and student_works.is_delete != 1" + has_many :score_student_works, :class_name => "StudentWork", :conditions => "student_works.is_test=0 and student_works.is_delete != 1 and work_status != 0", :order => "work_score desc" has_many :student_works_evaluation_distributions, :through => :student_works #一个作业的分配的匿评列表 has_many :journals_for_messages, :as => :jour, :dependent => :destroy has_many :apply_homeworks diff --git a/app/models/library.rb b/app/models/library.rb new file mode 100644 index 00000000..78bc7fc5 --- /dev/null +++ b/app/models/library.rb @@ -0,0 +1,52 @@ +class Library < ActiveRecord::Base + include AASM + + belongs_to :user + + has_many :library_applies, dependent: :delete_all + has_many :attachments, as: :container + + attr_accessible :title, :content + + validates :title, presence: true + validates :content, presence: true + validates :uuid, presence: true, uniqueness: true + + acts_as_attachable + + aasm(:status) do + state :pending, initiali: true + state :processing + state :refused + state :published + + event :submit do + transitions from: [:pending, :refused], to: :processing + end + + event :refuse do + transitions from: :processing, to: :refused + end + + event :publish do + transitions from: :processing, to: :published + end + end + + def generate_uuid + uuid = Util.generate_time_uuid + while Library.exists?(uuid: uuid) + uuid = Util.generate_time_uuid + end + + self.uuid = uuid + end + + def increment_visited_count! + Library.connection.execute("update libraries set visited_count = COALESCE(visited_count, 0) + 1 where id = #{id}") + end + + def editable? + pending? || refused? + end +end \ No newline at end of file diff --git a/app/models/library_apply.rb b/app/models/library_apply.rb new file mode 100644 index 00000000..9c1e183a --- /dev/null +++ b/app/models/library_apply.rb @@ -0,0 +1,19 @@ +class LibraryApply < ActiveRecord::Base + include AASM + + belongs_to :library + + aasm(:status) do + state :pending, initiali: true + state :refused + state :agreed + + event :refuse do + transitions from: :pending, to: :refused + end + + event :agree do + transitions from: :pending, to: :agreed + end + end +end \ No newline at end of file diff --git a/app/models/shixun.rb b/app/models/shixun.rb index e7682a74..fe9a00b1 100644 --- a/app/models/shixun.rb +++ b/app/models/shixun.rb @@ -273,6 +273,10 @@ class Shixun < ActiveRecord::Base return name end + def child_mirror_ids + self.mirror_repositories.where(:main_type => 0).pluck(:id) + end + def mirror_name self.mirror_repositories.map(&:type_name).blank? ? "" : self.mirror_repositories.map(&:type_name) end diff --git a/app/models/team_member.rb b/app/models/team_member.rb index d722f7c8..aef358da 100644 --- a/app/models/team_member.rb +++ b/app/models/team_member.rb @@ -3,5 +3,5 @@ class TeamMember < ActiveRecord::Base belongs_to :competition belongs_to :user # role 1:创建者 2:成员 3:指导老师 - # attr_accessible :role + attr_accessible :role, :user_id, :competition_id, :is_teacher end diff --git a/app/models/tiding.rb b/app/models/tiding.rb index ec8c68d8..91bcf0b9 100644 --- a/app/models/tiding.rb +++ b/app/models/tiding.rb @@ -358,6 +358,14 @@ class Tiding < ActiveRecord::Base " " when 'Department' "你选填的二级单位:#{self.container.try(:name)}(#{self.container.try(:school).name})因不符合规范,已被系统删除.请重新选择" + when 'Library' + library = Library.find_by_id(container_id) + if tiding_type == 'Apply' + "申请发布文库:#{library.try(:title)}" + elsif tiding_type == 'System' + text = status == 1 ? "审核已通过" : "审核未通过,
原因:#{extra}" + "你提交的发布文库申请:#{library.try(:title)},#{text}" + end else logger.error "error type: 1" end diff --git a/app/models/user.rb b/app/models/user.rb index db1ff58a..c206d51e 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -250,6 +250,7 @@ class User < Principal has_many :ec_course_users + has_many :libraries, dependent: :destroy ##### scope :logged, lambda { where("#{User.table_name}.status <> #{STATUS_ANONYMOUS}") } diff --git a/app/services/libraries/agree_apply_service.rb b/app/services/libraries/agree_apply_service.rb new file mode 100644 index 00000000..8d901b67 --- /dev/null +++ b/app/services/libraries/agree_apply_service.rb @@ -0,0 +1,32 @@ +class Libraries::AgreeApplyService + Error = Class.new(StandardError) + + attr_reader :library_apply, :library, :user + + def initialize(library_apply, user) + @library_apply = library_apply + @library = library_apply.library + @user = user + end + + def call + raise Error, '该状态下不能进行此操作' unless library_apply.may_agree? + + ActiveRecord::Base.transaction do + library_apply.agree! + library_apply.library.publish! + + # 将消息改为已处理 + Tiding.where(container_id: library.id, container_type: 'Library', tiding_type: 'Apply', status: 0).update_all(status: 1) + notify_library_author! + end + end + + private + + def notify_library_author! + Tiding.create!(user_id: library.user_id, trigger_user_id: 1, + container_id: library.id, container_type: 'Library', + tiding_type: 'System', status: 1) + end +end \ No newline at end of file diff --git a/app/services/libraries/refuse_apply_service.rb b/app/services/libraries/refuse_apply_service.rb new file mode 100644 index 00000000..78fdbcb0 --- /dev/null +++ b/app/services/libraries/refuse_apply_service.rb @@ -0,0 +1,39 @@ +class Libraries::RefuseApplyService + Error = Class.new(StandardError) + + attr_reader :library_apply, :library, :user, :params + + def initialize(library_apply, user, params) + @library_apply = library_apply + @library = library_apply.library + @user = user + @params = params + end + + def call + reason = params[:reason].to_s.strip + raise Error, '原因不能为空' if reason.blank? + raise Error, '该状态下不能进行此操作' unless library_apply.may_refuse? + + ActiveRecord::Base.transaction do + library_apply.reason = reason + library_apply.refused_at = Time.current + library_apply.refuse + library_apply.save! + + library.refuse! + + # 将消息改为已处理 + Tiding.where(container_id: library.id, container_type: 'Library', tiding_type: 'Apply', status: 0).update_all(status: 1) + notify_library_author! + end + end + + private + + def notify_library_author! + Tiding.create!(user_id: library.user_id, trigger_user_id: 1, + container_id: library.id, container_type: 'Library', + tiding_type: 'System', status: 2, extra: library_apply.reason) + end +end \ No newline at end of file diff --git a/app/services/libraries/save_service.rb b/app/services/libraries/save_service.rb new file mode 100644 index 00000000..3a81d379 --- /dev/null +++ b/app/services/libraries/save_service.rb @@ -0,0 +1,37 @@ +class Libraries::SaveService + Error = Class.new(StandardError) + + attr_reader :library, :user, :params + + def initialize(library, user, params) + @library = library + @user = user + @params = params + end + + def call + validate_params! + + if library.new_record? + library.user_id = user.id + library.generate_uuid + end + + attachment_ids = params.delete(:attachment_ids) + + ActiveRecord::Base.transaction do + library.assign_attributes(params) + library.save! + + Attachment.where(id: attachment_ids).update_all(container_id: library.id, container_type: 'Library') + end + + library + end + + private + + def validate_params! + raise Error, '附件不能为空' if params[:attachment_ids].blank? + end +end diff --git a/app/services/libraries/submit_service.rb b/app/services/libraries/submit_service.rb new file mode 100644 index 00000000..965ba673 --- /dev/null +++ b/app/services/libraries/submit_service.rb @@ -0,0 +1,31 @@ +class Libraries::SubmitService + Error = Class.new(StandardError) + + attr_reader :library + + def initialize(library) + @library = library + end + + def call + raise Error, '该状态下不能提交审核' unless library.may_submit? + + ActiveRecord::Base.transaction do + library.published_at = Time.current + library.submit + library.save! + + library.library_applies.create! + send_library_apply_notify! + end + end + + private + + def send_library_apply_notify! + Tiding.create!(user_id: 1, trigger_user_id: library.user_id, + container_id: library.id, container_type: 'Library', + tiding_type: 'Apply', status: 0) + Trustie::Sms.send(mobile: '18711011226', send_type:'publish_library' , name: '管理员') rescue nil + end +end \ No newline at end of file diff --git a/app/services/users_service.rb b/app/services/users_service.rb index 14289425..6ab6d3f6 100644 --- a/app/services/users_service.rb +++ b/app/services/users_service.rb @@ -343,7 +343,7 @@ class UsersService g = Gitlab.client g.edit_user(@current_user.gid, :password => params[:new_password]) rescue Exception => e - logger.error "change users password failed! ===> #{e}" + Rails.logger.error "change users password failed! ===> #{e.message}" end end #raise @current_user.errors.full_message diff --git a/app/views/attachments/_from_libraries.html.erb b/app/views/attachments/_from_libraries.html.erb new file mode 100644 index 00000000..4abb3c80 --- /dev/null +++ b/app/views/attachments/_from_libraries.html.erb @@ -0,0 +1,62 @@ +
+
  • + 上传附件 + +

    从我的电脑选择要上传的文档:按住CTRL可以上传多份文档

    +
    上传出现错误,请检查您的网络环境,并刷新页面重新上传。
    +
  • +
    +
    + <% if defined?(container) && container && container.saved_attachments %> + <% container.attachments.each_with_index do |attachment, i| %> + + + <% size = judge_Chinese_num attachment.filename %> + <%= text_field_tag("attachments[p#{i}][filename]", attachment.filename, :class => 'upload_filename readonly hidden color-grey fl', :size => size, :style => 'border:none; max-width:980px;white-space: nowrap; text-overflow:ellipsis;font-family: Consolas;', :readonly => 'readonly') %> + <%= number_to_human_size attachment.filesize %> + <%= link_to(''.html_safe, attachment_path(attachment, :attachment_id => "p#{i}", :format => 'js'), :method => 'delete', :remote => true, :class => 'remove-upload') unless attachment.id.nil? %> + <%= hidden_field_tag "attachments[p#{i}][token]", "#{attachment.token}" %> + + <% end %> + <% container.saved_attachments.each_with_index do |attachment, i| %> + + + + <%= text_field_tag("attachments[p#{i}][filename]", attachment.filename, :class => 'hidden atta_input readonly color-grey fl', :style => 'border:none; max-width:980px;', :readonly => 'readonly') %> + <%= link_to(''.html_safe, attachment_path(attachment, :attachment_id => "p#{i}", :format => 'js'), :method => 'delete', :remote => true, :class => 'remove-upload fl mt2') unless attachment.id.nil? %> + <%= hidden_field_tag "attachments[p#{i}][token]", "#{attachment.token}" %> + + <% end %> + <% end %> +
    +<%= file_field_tag 'attachments[dummy][file]', + :id => '_file', + :class => ie8? ? '' : 'file_selector', + :multiple => true, + :onchange => 'addInputFiles(this);', + :style => ie8? ? '' : 'display:none', + :data => { + :max_file_size => Setting.attachment_max_size.to_i.kilobytes, + :max_file_size_message => l(:error_attachment_too_big, :max_size => number_to_human_size(Setting.attachment_max_size.to_i.kilobytes)), + :max_concurrent_uploads => Redmine::Configuration['max_concurrent_ajax_uploads'].to_i, + :upload_path => uploads_path(:format => 'js',:project =>nil), + :description_placeholder => l(:label_optional_description), + :field_is_public => l(:field_is_public), + :are_you_sure => l(:text_are_you_sure), + :file_count => l(:label_file_count), + :lebel_file_uploding => l(:lebel_file_uploding), + :delete_all_files => l(:text_are_you_sure_all) + } %> + + + +<%= javascript_include_tag 'attachments' %> + \ No newline at end of file diff --git a/app/views/competition_teams/_competition_team_form.html.erb b/app/views/competition_teams/_competition_team_form.html.erb index dc845c59..c182c138 100644 --- a/app/views/competition_teams/_competition_team_form.html.erb +++ b/app/views/competition_teams/_competition_team_form.html.erb @@ -1,7 +1,12 @@ <% none_edit = @team.try(:id).present? && @competition.enroll_end_time.present? && @competition.enroll_end_time < Time.now %> <%= labelled_form_for @team, :html => {:id => 'competition_team_form', :multipart => true, :remote => true} do |f| %> - - + <% teacher_staff = @competition.competition_staffs.where(category: 'teacher').first %> + <% min_member_staff = @competition.competition_staffs.where('category != "teacher"').sum(:minimum) %> + <% max_member_staff = @competition.competition_staffs.where('category != "teacher"').sum(:maximum) %> + + + + @@ -15,7 +20,8 @@

    -
    + <% if teacher_staff.present? %> +
    autocomplete="off" placeholder="请您输入老师姓名进行搜索" id="teacher_search_input" @@ -31,73 +37,82 @@ 添加导师

    -
    - -
    - autocomplete="off" style="width: 100%" placeholder="请您输入想要添加的成员搜索" id="user_search_input"> - - - - - - -
      -
    + <% end %> + <% if min_member_staff > 0 %> +
    + +
    + autocomplete="off" style="width: 100%" placeholder="请您输入想要添加的成员搜索" id="user_search_input"> + + + + + + +
      +
    +
    + 添加成员
    - 添加成员 -

    + <% end %> -
    -

    - 姓名 - 角色 - 单位 - 其他 - 操作 +

    +

    + 姓名 + 角色 + 单位 + 其他 + 操作 +

    + <% if @team.try(:id).present? %> + <% creator_teacher = @team.user.user_extensions.identity == 0 %> +

    + <%= @team.user.show_name %> + <%= @team.user.user_extensions.identity == 0 ? "导师/创建者" : "创建者" %> + <%= @team.user.school_name %> + <%= @team.user.user_extensions.identity == 0 ? "职称:#{@team.user.identity}" : "学号:#{@team.user.user_extensions.student_id.present? ? @team.user.user_extensions.student_id : "--"}" %> +

    - <% if @team.try(:id).present? %> -

    - <%= @team.user.show_name %> - <%= @team.user.user_extensions.identity == 0 ? "导师/创建者" : "创建者" %> - <%= @team.user.school_name %> - <%= @team.user.user_extensions.identity == 0 ? "职称:#{@team.user.identity}" : "学号:#{@team.user.user_extensions.student_id.present? ? @team.user.user_extensions.student_id : "--"}" %> - + + <% @team.teachers.includes(user: :user_extensions).each do |teacher| %> + <% next if teacher.user_id == @team.user_id %> +

    + + <%= teacher.user.show_name %> + 导师 + <%= teacher.user.school_name %> + 职称:<%= teacher.user.identity %> +

    - <% if @team.teacher.present? && @team.teacher != @team.user %> -

    - - <%= @team.teacher.show_name %> - 导师 - <%= @team.teacher.school_name %> - 职称:<%= @team.teacher.identity %> - -

    - <% end %> - <% @team.team_members.where(:role => 2, :is_teacher => 0).each do |team_user| %> -

    - - <%= team_user.user.show_name %> - 成员 - <%= team_user.user.school_name %> - 学号:<%= team_user.user.user_extensions.student_id.present? ? team_user.user.user_extensions.student_id : "--" %> - - <% unless none_edit %> - - <% end %> - -

    - <% end %> - <% else %> -

    - <%= @team_user.show_name %> - <%= @team_user.user_extensions.identity == 0 ? "导师/创建者" : "创建者" %> - <%= @team_user.school_name %> - <%= @team_user.user_extensions.identity == 0 ? "职称:#{@team_user.identity}" : "学号:#{@team_user.user_extensions.student_id.present? ? @team_user.user_extensions.student_id : "--"}" %> - + <% end %> + + <% @team.members.includes(user: :user_extensions).each do |team_user| %> + <% next if team_user.user_id == @team.user_id %> +

    + + <%= team_user.user.show_name %> + 成员 + <%= team_user.user.school_name %> + 学号:<%= team_user.user.user_extensions.student_id.present? ? team_user.user.user_extensions.student_id : "--" %> + + <% unless none_edit %> + + <% end %> +

    <% end %> -
    + <% else %> + <% creator_teacher = @team_user.user_extensions.identity == 0 %> +

    + <%= @team_user.show_name %> + <%= @team_user.user_extensions.identity == 0 ? "导师/创建者" : "创建者" %> + <%= @team_user.school_name %> + <%= @team_user.user_extensions.identity == 0 ? "职称:#{@team_user.identity}" : "学号:#{@team_user.user_extensions.student_id.present? ? @team_user.user_extensions.student_id : "--"}" %> + +

    + <% end %> +

    @@ -111,69 +126,81 @@ <%= answer_be_selected?(exercise_choice, User.current) ? "checked" : "" %>> - + <% end %>
    @@ -243,7 +247,11 @@ } <%= answer_be_selected?(exercise_choice, User.current) ? "checked" : "" %>> - + <% end %>
    diff --git a/app/views/exercise/_exercise_student_result.html.erb b/app/views/exercise/_exercise_student_result.html.erb index 6d48573f..8b6f7ab6 100644 --- a/app/views/exercise/_exercise_student_result.html.erb +++ b/app/views/exercise/_exercise_student_result.html.erb @@ -153,7 +153,11 @@ id="exercise_<%= exercise_choice.id %>_exercise_choice_id" type="radio" disabled <%= answer_be_selected?(exercise_choice, user) ? "checked" : "" %>> - + <% end %>
    @@ -168,7 +172,11 @@ <% exercise_choices.each_with_index do |exercise_choice, index| %>
  • > - +
  • <% end %>
    @@ -287,7 +295,7 @@ 调分 <% end %> - <% if game.present? && game.status == 2 && !is_answer_correct && game.answer_open %> + <% if game.present? && game.status == 2 && @exercise_user.end_at && game.end_time < @exercise_user.end_at && !is_answer_correct && game.answer_open %> (答案抄袭) <% end %> <% score = exercise_shixun_answer.present? ? exercise_shixun_answer.try(:score) : 0 %> diff --git a/app/views/exercise/student_exercise_list.html.erb b/app/views/exercise/student_exercise_list.html.erb index b8335515..e6eddc40 100644 --- a/app/views/exercise/student_exercise_list.html.erb +++ b/app/views/exercise/student_exercise_list.html.erb @@ -268,7 +268,11 @@ <% exercise_choices.each_with_index do |exercise_choice, index| %>
    - +
    <% end %> @@ -281,7 +285,11 @@ <% exercise_choices.each_with_index do |exercise_choice, index| %>
    - +
    <% end %> diff --git a/app/views/layouts/_footer.html.erb b/app/views/layouts/_footer.html.erb index 7fd5d587..3a8fdc20 100644 --- a/app/views/layouts/_footer.html.erb +++ b/app/views/layouts/_footer.html.erb @@ -16,7 +16,8 @@
    - +
    diff --git a/app/views/layouts/_logined_header.html.erb b/app/views/layouts/_logined_header.html.erb index 30ef0658..077ef249 100644 --- a/app/views/layouts/_logined_header.html.erb +++ b/app/views/layouts/_logined_header.html.erb @@ -25,6 +25,7 @@ <%= link_to "认证", department_ecs_path(:school_id => User.current.ec_school) %> <% end %> +
  • "><%= link_to '文库', libraries_path %>
  • + +
    + <%= link_to '确认提交', 'javascript:void(0)', class: 'white-btn edu-blueback-btn changebtn mr20 fl apply-publish-btn' %> + <%= link_to '保存', 'javascript:void(0)', class: 'white-btn edu-blueline-btn changebtn mr20 fl submit-btn' %> +
    + <% end %> + + + \ No newline at end of file diff --git a/app/views/libraries/_library_list.html.erb b/app/views/libraries/_library_list.html.erb new file mode 100644 index 00000000..63314d65 --- /dev/null +++ b/app/views/libraries/_library_list.html.erb @@ -0,0 +1,32 @@ +
    + <% if @libraries.present? %> + <% @libraries.each do |library| %> +
  • + <%= link_to image_tag(url_to_avatar(library.user), width: 50, height: 50, class: 'radius mr15 mt3'), user_path(library.user) %> +
    +

    <%= link_to library.title, library_path(library) %>

    +

    + <%= link_to library.user.show_real_name, user_path(library.user) %> + <%= library.visited_count || 0 %> 浏览 + <% if params[:type] == 'mine' %> + 上传时间:<%= library.created_at.strftime('%Y-%m-%d %H:%M') %> + <% else %> + 发布时间:<%= library.published_at.try(:strftime, '%Y-%m-%d %H:%M') %> + <% end %> +

    +
    +
  • + <% end %> + <% else %> + <%= render :partial => "welcome/no_data" %> + <% end %> +
    +
    + +
    + +
    +
    +
    \ No newline at end of file diff --git a/app/views/libraries/edit.html.erb b/app/views/libraries/edit.html.erb new file mode 100644 index 00000000..e258e1c1 --- /dev/null +++ b/app/views/libraries/edit.html.erb @@ -0,0 +1,8 @@ +
    +

    + <%= link_to '文库', libraries_path, class: 'color-grey-9' %> > + 编辑 +

    + + <%= render partial: 'form' %> +
    \ No newline at end of file diff --git a/app/views/libraries/index.html.erb b/app/views/libraries/index.html.erb new file mode 100644 index 00000000..98e80cb0 --- /dev/null +++ b/app/views/libraries/index.html.erb @@ -0,0 +1,51 @@ +
    +
    +

    + 文库 + <%= link_to '新建', new_library_path, class: 'fr color-blue font-16 mt3' %> +

    +
    +
      +
    • + <%= link_to '全部', libraries_path(search: params[:search]), remote: true %> +
    • +
    • + <%= link_to '我的', libraries_path(search: params[:search], type: 'mine'), remote: true %> +
    • +
    +
    + <%= hidden_field_tag(:type, params[:type]) %> + + +
    +
    +
    +
    + <%= render partial: 'library_list' %> +
    +
    + \ No newline at end of file diff --git a/app/views/libraries/index.js.erb b/app/views/libraries/index.js.erb new file mode 100644 index 00000000..78d48f8f --- /dev/null +++ b/app/views/libraries/index.js.erb @@ -0,0 +1,3 @@ +$('input[name="type"]').val('<%= params[:type].to_s %>'); +$('#search_name').val('<%= params[:search].to_s %>'); +$('.library-list-container').html('<%= j render(partial: 'library_list') %>') \ No newline at end of file diff --git a/app/views/libraries/new.html.erb b/app/views/libraries/new.html.erb new file mode 100644 index 00000000..987951d3 --- /dev/null +++ b/app/views/libraries/new.html.erb @@ -0,0 +1,8 @@ +
    +

    + <%= link_to '文库', libraries_path, class: 'color-grey-9' %> > + 新建 +

    + + <%= render partial: 'form' %> +
    \ No newline at end of file diff --git a/app/views/libraries/publish_success.html.erb b/app/views/libraries/publish_success.html.erb new file mode 100644 index 00000000..372053e6 --- /dev/null +++ b/app/views/libraries/publish_success.html.erb @@ -0,0 +1,14 @@ +
    +
    + +
    +

    恭喜!

    +

    文档上传成功

    +
    +

    通过平台管理员审核后,即可公开显示

    +
  • + <%= link_to '查看已上传文档', libraries_path(type: 'mine'), class: 'white-btn edu-blueline-btn changebtn mr20 fl' %> + <%= link_to '继续上传', new_library_path, class: 'white-btn edu-blueback-btn changebtn fl' %> +
  • +
    +
    \ No newline at end of file diff --git a/app/views/libraries/show.html.erb b/app/views/libraries/show.html.erb new file mode 100644 index 00000000..c098b069 --- /dev/null +++ b/app/views/libraries/show.html.erb @@ -0,0 +1,96 @@ +<% + admin_or_self = User.current.admin? || @library.user_id == User.current.id +%> +
    +

    + <%= link_to '文库', libraries_path, class: 'color-grey-9' %> > + 详情 +

    +

    + <%= @library.title %> + <% if admin_or_self %> + <% if @library.pending? %> + 草稿 + <% elsif @library.processing? %> + 审核中 + <% elsif @library.refused? %> + 未通过 + <% end %> + <% end %> + <%= link_to('返回', libraries_path, class: 'fr color-grey-9 mt5') %> +

    +
    + <% if admin_or_self && !@library.published? && @library_applies.size > 0 %> +
    +

    + 私有化原因 + (请按照提示修改,并在完成编辑后重新提交) + 点击展开 +

    +
    + <% @library_applies.each do |apply| %> +
  • +

    <%= apply.updated_at.strftime('%Y-%m-%d %H:%M') %>

    +

    <%= apply.reason %>

    +
  • + <% end %> +
    +
    + <% end %> +
    +

    + 详情 + <% if admin_or_self && @library.editable? %> + <%= link_to '编辑', edit_library_path(id: @library.id), class: 'white-btn edu-blueline-btn fr' %> + <% end %> +

    +
    + <%= link_to image_tag(url_to_avatar(@library.user), width: 50, height: 50, class: 'radius mr15 mt3'), user_path(@library.user) %> +
    +
  • <%= @library.user.show_real_name %>
  • +
  • + <%= @library.user.school_name %> + <%= @library.user.identity %> + + 编码:<%= @library.uuid %> + <% if @library.published? %> + 发布时间:<%= @library.published_at.strftime('%Y-%m-%d %H:%M') %> + <% else %> + 上传时间:<%= @library.created_at.strftime('%Y-%m-%d %H:%M') %> + <% end %> + +
  • +
    +
    +
    +
    + +
    +
    + <%= render partial: 'attachments/links', locals: { attachments: @library.attachments, options: {} } %> +
    +
    +
    +
    +
    + \ No newline at end of file diff --git a/app/views/managements/_competition_list_page.html.erb b/app/views/managements/_competition_list_page.html.erb index 2610f7dc..94cacc8d 100644 --- a/app/views/managements/_competition_list_page.html.erb +++ b/app/views/managements/_competition_list_page.html.erb @@ -68,13 +68,29 @@ <% end %> <% if com_module.name == "报名" %> -
    - ~ - 人 -
    -
    - 报名截止: - +
    +
    + 报名截止时间: + +
    +
    +
    报名要求:
    +
    + <% @competition.competition_staffs.each do |staff| %> +
    + <%= select_tag('competition_staffs[][category]', options_for_select(CompetitionStaff.category_options, staff.category), class: 'winput-120-30') %> + +   ~   + + 人 + + + + +
    + <% end %> +
    +
    <% end %> <% if com_module.name != "首页" && com_module.name != "报名" && com_module.name != "通知公告" && com_module.name != "排行榜" %> @@ -149,6 +165,20 @@
    + + <% content_for :header_tags do %> @@ -504,4 +534,17 @@ } }) } + + $(function(){ + $('.add-competition-staff-btn').on('click', function(){ + $('.competition-staff-settings').append($('.competition-staff-row-example').html()); + }); + + $('.competition-staff-settings').on('click', '.add-icon', function(){ + $('.competition-staff-settings').append($('.competition-staff-row-example').html()); + }); + $('.competition-staff-settings').on('click', '.delete-icon', function(){ + $(this).parents('.competition-staff-row').remove(); + }); + }) diff --git a/app/views/managements/library_applies/_library_apply_list.html.erb b/app/views/managements/library_applies/_library_apply_list.html.erb new file mode 100644 index 00000000..81e6c1d4 --- /dev/null +++ b/app/views/managements/library_applies/_library_apply_list.html.erb @@ -0,0 +1,78 @@ +<% if @library_applies.present? %> + <% @library_applies.each do |apply| %> + <% user = apply.library.user %> + <% library = apply.library %> +
    + + <%= image_tag(url_to_avatar(user), :class => "fl with10 edu-ad-user", :alt => "头像", :width => "50", :height => "50" ) %> + +
    + +
    +
    + <% end %> +
    +
    + +
    +
    +
    +<% else %> + <%= render :partial => "welcome/no_data" %> +<% end %> + + \ No newline at end of file diff --git a/app/views/managements/library_applies/index.html.erb b/app/views/managements/library_applies/index.html.erb new file mode 100644 index 00000000..23d898c4 --- /dev/null +++ b/app/views/managements/library_applies/index.html.erb @@ -0,0 +1,120 @@ +
    +
    +

    文库发布

    +
    +
    +
    +
      +
    • + <%= link_to "待审批", library_applies_path(status: :pending), class: 'tab_type', remote: true %> +
    • +
    • + <%= link_to "已审批", library_applies_path(status: [:refused, :agreed]), class: 'tab_type', remote: true %> +
    • +
    +
    +
    +
    +
    + + +
    +
    +
    + <%= render :partial => "managements/library_applies/library_apply_list"%> +
    +
    +
    + +
    +
    +

    + <%= link_to "全部", library_applies_path(status: [:refused, :agreed]), :class => "edu-filter-cir-grey mr5 fl font-12 active", :id => "library_all_authentication", :remote => true %> + <%= link_to "同意", library_applies_path(status: :agreed), :class => "edu-filter-cir-grey mr5 fl font-12", :id => "library_agree_authentication", :remote => true %> + <%= link_to "拒绝", library_applies_path(status: :refused), :class => "edu-filter-cir-grey mr5 fl font-12", :id => "library_reject_authentication", :remote => true %> +

    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + \ No newline at end of file diff --git a/app/views/managements/library_applies/index.js.erb b/app/views/managements/library_applies/index.js.erb new file mode 100644 index 00000000..aa6f932f --- /dev/null +++ b/app/views/managements/library_applies/index.js.erb @@ -0,0 +1,30 @@ +var nTabIcon_1 = $("#edu-tab-con-1"); +var nTabIcon_2 = $("#edu-tab-con-2"); +var nTabNav_1 = $("#edu-tab-nav-1"); +var nTabNav_2 = $("#edu-tab-nav-2"); +var nAudit = $("#library_all_authentication").parent(); + +<% if params[:status].to_s == 'pending' %> +$("#authentication_list").html("<%= j( render :partial => "managements/library_applies/library_apply_list" ) %>"); +nTabNav_1.addClass("background-orange"); +nTabNav_2.removeClass("background-orange"); +nTabIcon_1.show(); +nTabIcon_2.hide(); +<% else %> +$("#library_authentication_list").html("<%= j( render :partial => "managements/library_applies/library_apply_list" ) %>"); +nTabNav_1.removeClass("background-orange"); +nTabNav_2.addClass("background-orange"); +nTabIcon_1.hide(); +nTabIcon_2.show(); +/* -------------------------- 未审批(全部、同意、拒绝点击时动态样式) ------------------------------ */ +if(<%= params[:status].to_s == 'agreed' %>){ + nAudit.find(".active").removeClass("active"); + $("#library_agree_authentication").addClass("active"); +}else if(<%= params[:status].to_s == 'refused' %>){ + nAudit.find(".active").removeClass("active"); + $("#library_reject_authentication").addClass("active"); +}else{ + nAudit.find(".active").removeClass("active"); + $("#library_all_authentication").addClass("active"); +} +<% end %> \ No newline at end of file diff --git a/app/views/repositories/_dir_list_content.html.erb b/app/views/repositories/_dir_list_content.html.erb index b45305e3..dc02a078 100644 --- a/app/views/repositories/_dir_list_content.html.erb +++ b/app/views/repositories/_dir_list_content.html.erb @@ -46,20 +46,20 @@ - + + + + + + + + + + + + + + <% end %> diff --git a/app/views/shixuns/_settings_edit.html.erb b/app/views/shixuns/_settings_edit.html.erb index 6e6fff64..90efda66 100644 --- a/app/views/shixuns/_settings_edit.html.erb +++ b/app/views/shixuns/_settings_edit.html.erb @@ -71,7 +71,7 @@
    <% @small_type.try(:each) do |type| %>

    - + />

    <% end %> @@ -294,335 +294,416 @@
    <% end %> - <% if User.current.admin? || User.cuurent.business? %> -
    -

    服务配置

    - <% @shixun.shixun_service_configs.each do |config| %> -

    <%= config.mirror_repository.try(:type_name) %>

    - -
    - -
    - -
    -
    +
    + + + +

    服务配置

    + <% @shixun.shixun_service_configs.each do |config| %> +
    +

    <%= config.mirror_repository.try(:type_name) %>

    + +
    + +
    + name="cpu_limit[]" value="<%= config.cpu_limit %>" class="panel-box-sizing task-form-100 task-height-40" + placeholder="请输入类别名称"/>
    -
    - -
    - -
    -
    +
    +
    +
    + +
    + value="<%= config.lower_cpu_limit %>" class="panel-box-sizing task-form-100 task-height-40" + placeholder="请输入类别名称"/>
    -
    - -
    - -
    -
    +
    +
    +
    + +
    + value="<%= config.memory_limit %>" class="panel-box-sizing task-form-100 task-height-40" + placeholder="请输入类别名称"/>
    -
    - -
    - -
    - -
    +
    +
    +
    + +
    + value="<%= config.request_limit %>" class="panel-box-sizing task-form-100 task-height-40" + placeholder="请输入类别名称"/>
    + +
    +
    +
    + + + + + + + + + <% end %> +
    +
    - - - - - - - - - <% end %> +
    + 保存 + <%= link_to "取消", settings_shixun_path(@shixun), :class => "defalutCancelbtn fl" %> +
    + <% end %> + +
    + + + + + + \ No newline at end of file + $("#unit-all").show(); + } + + $("input[name='public_degree']").live("click", function () { + var item = $(this).attr("id"); + if ($(this).is(":checked") && item == "public-part") { + $("#person-unit").show(); + $("#person-unit").find("input").val(""); + //$(".unit-part").remove(); + $("#unit-all").show(); + } else { + $("#unit-all").hide(); + } + }); + + $("body").on("click", function (e) { + //alert($(e.target).attr("id")); + if ($(e.target).attr("id") != "person-unit") { + $("#scope-down-list").hide(); + } + }); + //设置编辑时显示的单位 + $(".unit-part input").each(function () { + $(this).attr("size", parseInt($(this).val().length) * 2); + }) + }); + + //申请新建 + function post_apply() { + var html = "<%= escape_javascript(render :partial => 'shixuns/apply_setnew') %>"; + pop_box_new(html, 460, 416); + } + + var setting_editormd = editormd("setting_introduction", { + width: "100%", + height: 210, + syncScrolling: "single", + //你的lib目录的路径,我这边用JSP做测试的 + path: "/editormd/lib/", + tex: true, + toolbarIcons: function () { + // Or return editormd.toolbarModes[name]; // full, simple, mini + // Using "||" set icons align right. + return ["bold", "italic", "|", "list-ul", "list-ol", "|", "code", "code-block", "|", "testIcon", "testIcon1", '|', "image", "table", '|', "watch", "clear"] + }, + toolbarCustomIcons: { + testIcon: "
    ", + testIcon1: "
    " + }, + onload: function () { + $("#setting_introduction [type=\"latex\"]").bind("click", function () { + setting_editormd.cm.replaceSelection("```latex"); + setting_editormd.cm.replaceSelection("\n"); + setting_editormd.cm.replaceSelection("\n"); + setting_editormd.cm.replaceSelection("```"); + var __Cursor = setting_editormd.cm.getDoc().getCursor(); + setting_editormd.cm.setCursor(__Cursor.line - 1, 0); + }); + + $("#setting_introduction [type=\"inline\"]").bind("click", function () { + setting_editormd.cm.replaceSelection("$$$$"); + var __Cursor = setting_editormd.cm.getDoc().getCursor(); + setting_editormd.cm.setCursor(__Cursor.line, __Cursor.ch - 2); + setting_editormd.cm.focus(); + }); + $("[type=\"inline\"]").attr("title", "行内公式"); + $("[type=\"latex\"]").attr("title", "多行公式"); + + }, + //这个配置在simple.html中并没有,但是为了能够提交表单,使用这个配置可以让构造出来的HTML代码直接在第二个隐藏的textarea域中,方便post提交表单。 + saveHTMLToTextarea: true, + autoFocus: false, + // 用于增加自定义工具栏的功能,可以直接插入HTML标签,不使用默认的元素创建图标 + dialogMaskOpacity: 0.6, + placeholder: "请输入完成当前任务依赖的知识点或者其它相关信息", + imageUpload: true, + imageFormats: ["jpg", "jpeg", "gif", "png", "bmp", "webp", "JPG", "JPEG", "GIF", "PNG", "BMP", "WEBP"], + imageUploadURL: "<%= upload_with_markdown_path(:container_id => @shixun.id, :container_type => @shixun.class) %>" //url + }); + md_elocalStorage(setting_editormd, "shixun_edit_<%= User.current.id %>", "in"); + + var script_Codemirror = CodeMirror.fromTextArea(document.getElementById("shixun_script"), { + lineNumbers: true, + theme: "default", + // extraKeys: {"Ctrl-Q": "autocomplete"}, // 快捷键 + indentUnit: 4, //代码缩进为一个tab的距离 + matchBrackets: true, + autoRefresh: true, + smartIndent: true,//智能换行 + styleActiveLine: true, + lint: true + }); + script_Codemirror.setSize("auto", "600px"); + // 非管理员只能查看 + \ No newline at end of file diff --git a/config/locales/competition_staffs/zh.yml b/config/locales/competition_staffs/zh.yml new file mode 100644 index 00000000..2d51f90c --- /dev/null +++ b/config/locales/competition_staffs/zh.yml @@ -0,0 +1,7 @@ +'zh': + competition_staff: + category: + all: 不限 + teacher: 教师 + student: 学生 + profession: 专业人士 \ No newline at end of file diff --git a/config/locales/libraries/zh.yml b/config/locales/libraries/zh.yml new file mode 100644 index 00000000..3004ecab --- /dev/null +++ b/config/locales/libraries/zh.yml @@ -0,0 +1,8 @@ +'zh': + activerecord: + models: + library: '文库' + attributes: + library: + title: '标题' + content: '描述' diff --git a/config/routes.rb b/config/routes.rb index 137a1231..5d523390 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -730,6 +730,15 @@ RedmineApp::Application.routes.draw do ## oauth相关 get :school_data_grow, controller: 'managements::schools', action: 'data_grow' get :school_data_contrast, controller: 'managements::schools', action: 'data_contrast' get :school_statistics_xlsx, controller: 'managements::schools', action: 'statistics_xlsx' + + scope module: :managements do + resources :library_applies, only: [:index] do + member do + post :agree + post :refuse + end + end + end end end # Enable Grack support @@ -2649,6 +2658,10 @@ RedmineApp::Application.routes.draw do ## oauth相关 resource :sso, only: [:show, :create] + resources :libraries do + get :publish_success, on: :collection + end + get '/:sub_dir_name', :to => 'org_subfields#show', :as => 'show_subfield_without_id' Dir.glob File.expand_path("plugins/*", Rails.root) do |plugin_dir| diff --git a/db/migrate/20190626004605_create_libraries.rb b/db/migrate/20190626004605_create_libraries.rb new file mode 100644 index 00000000..07e9c1d8 --- /dev/null +++ b/db/migrate/20190626004605_create_libraries.rb @@ -0,0 +1,18 @@ +class CreateLibraries < ActiveRecord::Migration + def change + create_table :libraries do |t| + t.references :user + + t.string :title + t.text :content + t.string :uuid, unique: true + t.string :status + t.integer :visited_count, default: 0 + t.datetime :published_at + + t.timestamps + end + + add_index :libraries, :published_at + end +end diff --git a/db/migrate/20190626005624_create_library_applies.rb b/db/migrate/20190626005624_create_library_applies.rb new file mode 100644 index 00000000..990bfa38 --- /dev/null +++ b/db/migrate/20190626005624_create_library_applies.rb @@ -0,0 +1,14 @@ +class CreateLibraryApplies < ActiveRecord::Migration + def change + create_table :library_applies do |t| + t.references :library + t.string :status + t.string :reason + + t.datetime :refused_at + t.timestamps + end + + add_index :library_applies, :refused_at + end +end diff --git a/db/migrate/20190626070641_add_limit_for_shixuns.rb b/db/migrate/20190626070641_add_limit_for_shixuns.rb index 1de29c80..e403c061 100644 --- a/db/migrate/20190626070641_add_limit_for_shixuns.rb +++ b/db/migrate/20190626070641_add_limit_for_shixuns.rb @@ -1,5 +1,8 @@ class AddLimitForShixuns < ActiveRecord::Migration def up + if !Challenge.first.has_attribute?(:exec_time) + add_column :challenges, :exec_time, :integer, :default => 120 + end Shixun.find_each do |shixun| shixun.challenges.update_all(:exec_time => shixun.exec_time) shixun.mirror_repositories.each do |mirror| diff --git a/db/migrate/20190626161150_modify_request_limit_for_shixun_service_config.rb b/db/migrate/20190626161150_modify_request_limit_for_shixun_service_config.rb new file mode 100644 index 00000000..060cad94 --- /dev/null +++ b/db/migrate/20190626161150_modify_request_limit_for_shixun_service_config.rb @@ -0,0 +1,15 @@ +class ModifyRequestLimitForShixunServiceConfig < ActiveRecord::Migration + def up + ShixunServiceConfig.find_each do |config| + # repertoire_id = 5 代表的是大数据的镜像 + if config.mirror_repository.repertoire_id != 5 + config.update_column(:request_limit, 10) + else + puts("####---#{config.mirror_repository.name}") + end + end + end + + def down + end +end diff --git a/db/migrate/20190627013059_create_competition_staffs.rb b/db/migrate/20190627013059_create_competition_staffs.rb new file mode 100644 index 00000000..7958534c --- /dev/null +++ b/db/migrate/20190627013059_create_competition_staffs.rb @@ -0,0 +1,13 @@ +class CreateCompetitionStaffs < ActiveRecord::Migration + def change + create_table :competition_staffs do |t| + t.references :competition + t.integer :position + t.string :category + t.integer :minimum + t.integer :maximum + + t.timestamps + end + end +end diff --git a/lib/trustie/sms/sms.rb b/lib/trustie/sms/sms.rb index 33584a0c..319de17c 100644 --- a/lib/trustie/sms/sms.rb +++ b/lib/trustie/sms/sms.rb @@ -57,6 +57,9 @@ module Trustie elsif send_type == "training_pay" params['text'] = "【计算机实践教学】亲爱的#{user_name}老师,您已经成功报名参与了11月24日--25日在深圳大学举办的全国软件工程实践教学案例与应用研讨会,请准时参加。(如有任何参会问题,请致电咨询会务联系人汤老师13099740868)" Rails.logger.info "#{params['text']}" + elsif send_type == 'publish_library' + params['text'] = "【Edu实训】亲爱的#{name},有新的文库发布申请,请尽快处理" + Rails.logger.info "#{params['text']}" end http = Net::HTTP.new(send_tpl_sms_uri.host, send_tpl_sms_uri.port) diff --git a/public/images/educoder/competition/qg/qg_two_1.png b/public/images/educoder/competition/qg/qg_two_1.png new file mode 100644 index 00000000..a8dab761 Binary files /dev/null and b/public/images/educoder/competition/qg/qg_two_1.png differ diff --git a/public/images/educoder/competition/qg/qg_two_2.png b/public/images/educoder/competition/qg/qg_two_2.png new file mode 100644 index 00000000..fe7daae9 Binary files /dev/null and b/public/images/educoder/competition/qg/qg_two_2.png differ diff --git a/public/images/educoder/competition/qg/qg_two_2_1.png b/public/images/educoder/competition/qg/qg_two_2_1.png new file mode 100644 index 00000000..b1bf161c Binary files /dev/null and b/public/images/educoder/competition/qg/qg_two_2_1.png differ diff --git a/public/images/educoder/competition/qg/qg_two_2_2.png b/public/images/educoder/competition/qg/qg_two_2_2.png new file mode 100644 index 00000000..3de73e74 Binary files /dev/null and b/public/images/educoder/competition/qg/qg_two_2_2.png differ diff --git a/public/images/educoder/competition/qg/qg_two_2_3.png b/public/images/educoder/competition/qg/qg_two_2_3.png new file mode 100644 index 00000000..9dde13d4 Binary files /dev/null and b/public/images/educoder/competition/qg/qg_two_2_3.png differ diff --git a/public/images/educoder/competition/qg/qg_two_2_4.png b/public/images/educoder/competition/qg/qg_two_2_4.png new file mode 100644 index 00000000..721f439a Binary files /dev/null and b/public/images/educoder/competition/qg/qg_two_2_4.png differ diff --git a/public/images/educoder/competition/qg/qg_two_2_5.png b/public/images/educoder/competition/qg/qg_two_2_5.png new file mode 100644 index 00000000..0f0bc7d9 Binary files /dev/null and b/public/images/educoder/competition/qg/qg_two_2_5.png differ diff --git a/public/images/educoder/competition/qg/qg_two_2_6.png b/public/images/educoder/competition/qg/qg_two_2_6.png new file mode 100644 index 00000000..9e0a5cf7 Binary files /dev/null and b/public/images/educoder/competition/qg/qg_two_2_6.png differ diff --git a/public/images/educoder/competition/qg/qg_two_2_7.png b/public/images/educoder/competition/qg/qg_two_2_7.png new file mode 100644 index 00000000..d5716ccc Binary files /dev/null and b/public/images/educoder/competition/qg/qg_two_2_7.png differ diff --git a/public/images/educoder/competition/qg/qg_two_2_8.png b/public/images/educoder/competition/qg/qg_two_2_8.png new file mode 100644 index 00000000..8c68c297 Binary files /dev/null and b/public/images/educoder/competition/qg/qg_two_2_8.png differ diff --git a/public/images/educoder/competition/qg/qg_two_3.png b/public/images/educoder/competition/qg/qg_two_3.png new file mode 100644 index 00000000..feea3642 Binary files /dev/null and b/public/images/educoder/competition/qg/qg_two_3.png differ diff --git a/public/images/educoder/competition/qg/qg_two_4.png b/public/images/educoder/competition/qg/qg_two_4.png new file mode 100644 index 00000000..07e6d90d Binary files /dev/null and b/public/images/educoder/competition/qg/qg_two_4.png differ diff --git a/public/images/educoder/competition/qg/qg_two_5.png b/public/images/educoder/competition/qg/qg_two_5.png new file mode 100644 index 00000000..55b68d40 Binary files /dev/null and b/public/images/educoder/competition/qg/qg_two_5.png differ diff --git a/public/images/educoder/competition/qg/qg_two_6.png b/public/images/educoder/competition/qg/qg_two_6.png new file mode 100644 index 00000000..96507a72 Binary files /dev/null and b/public/images/educoder/competition/qg/qg_two_6.png differ diff --git a/public/images/educoder/competition/qg/qg_two_7.png b/public/images/educoder/competition/qg/qg_two_7.png new file mode 100644 index 00000000..33e65de1 Binary files /dev/null and b/public/images/educoder/competition/qg/qg_two_7.png differ diff --git a/public/images/educoder/competition/qg/qg_two_8.png b/public/images/educoder/competition/qg/qg_two_8.png new file mode 100644 index 00000000..50016195 Binary files /dev/null and b/public/images/educoder/competition/qg/qg_two_8.png differ diff --git a/public/images/educoder/success.png b/public/images/educoder/success.png new file mode 100644 index 00000000..9282ef4d Binary files /dev/null and b/public/images/educoder/success.png differ diff --git a/public/stylesheets/css/edu-admin.css b/public/stylesheets/css/edu-admin.css index 7448e758..b3d4987b 100644 --- a/public/stylesheets/css/edu-admin.css +++ b/public/stylesheets/css/edu-admin.css @@ -104,4 +104,8 @@ a:hover.edu-admin-nav-a,.active a.edu-admin-nav-a{color: #5faee3;} /*超级管理员----技术体系*/ .createsystem{cursor: pointer;width: 100%;height: 70px;line-height: 70px;border:1px dashed #FF7500;color: #FF7500;text-align: center;margin:15px 0px 20px 0px;border-radius: 4px;} -.infoul li{list-style-type: disc} \ No newline at end of file +.infoul li{list-style-type: disc} + +/* 竞赛配置 */ +.competition-staff-settings .competition-staff-row .competition-staff-operate .add-icon { display: none; } +.competition-staff-settings .competition-staff-row:last-child .competition-staff-operate .add-icon { display: inline; } \ No newline at end of file diff --git a/public/stylesheets/educoder/edu-all.css b/public/stylesheets/educoder/edu-all.css index 3026e3f9..498eb759 100644 --- a/public/stylesheets/educoder/edu-all.css +++ b/public/stylesheets/educoder/edu-all.css @@ -602,7 +602,7 @@ p .activity-item:first-child{border-top: 1px solid #eee;} #competition-content img,#competition-db-content img,#ccfPage img{vertical-align: bottom;} #hnpage1{background: url('/images/educoder/competition/logo_1.jpg') no-repeat top center;min-height: 820px;} -#competition-header{background: linear-gradient(to right, #29bd8b , #13dc98);height: 60px;width: 100%;padding-right: 40px;box-sizing: border-box;position: fixed;top: 0px;left: 0px;width: 100%;z-index: 1000;} +#competition-header{background:#24292D;height: 60px;width: 100%;padding-right: 40px;box-sizing: border-box;position: fixed;top: 0px;left: 0px;width: 100%;z-index: 1000;} .nav-game{position: relative;} .nav-game li{position: relative;float: left;width: 110px;height: 60px;line-height: 60px;text-align: center;box-sizing: border-box} .nav-game li a{color:#fff;font-size: 16px;} @@ -639,6 +639,83 @@ a.enterLink{cursor: pointer;color: #418CCD!important;background: none!important; .position-shixun{position: absolute;z-index: 2;bottom: 40px;text-align: center;width: 100%} .ccf-position-shixun .shixun-btn,.position-shixun .shixun-btn,.ccf-position-shixun-2 .shixun-btn{display: block;float: left;width: 160px;text-align:center;letter-spacing: 1px;height: 40px;line-height: 40px;color:#fff!important;margin:0px 20px;background: linear-gradient(to right, #ff8634 , #ff9d5b);box-shadow: 6px 4px 11px #f7ece4;} +/*第二次竞赛-全国*/ +.second_1{min-height: 832px;} +.second_2{min-height: 446px;} +.second_3{min-height: 595px;padding-top: 190px;box-sizing: border-box;position: relative} +.second_4{min-height: 610px;padding-top: 190px;box-sizing: border-box;position: relative} +.second_5{min-height: 617px;padding-top: 190px;box-sizing: border-box;position: relative} +.second_6{min-height: 1053px;} +.second_7{min-height: 1096px;} +.second_8{min-height: 727px;} + + +.second_code_1{min-height: 791px;} +.second_code_2{min-height: 436px;} +.second_code_3{min-height: 1460px;padding-top: 190px;box-sizing: border-box;position: relative} +.second_code_4{min-height: 724px;padding-top: 190px;box-sizing: border-box;position: relative} +.second_code_5{min-height: 718px;padding-top: 190px;box-sizing: border-box;position: relative} +.second_code_6{min-height: 1060px;} +.second_code_7{min-height: 1116px;} +.second_code_8{min-height: 711px;} +.challenge_title{ + color: #41ABEF;font-size: 30px;font-weight: bold;text-align: center;letter-spacing: 1px;line-height: 60px;margin-bottom: 20px; +} +.challenge_sub_title{margin-bottom: 20px;} +.challenge_sub_title li span{color: #0B8298;font-size: 22px;font-weight: bold} +.challenge_sub_title li span:last-child{font-weight: 400!important;font-size: 20px!important;} +.enter_panel{ + width: 1200px;margin:0px auto;height: 360px;text-align: center;padding:20px;box-sizing: border-box; +} +.enter_title{ + color: #0B8298; +} +.enter_btn a{ + float: left;width: 300px;height: 60px;background: #ccc;color: #fff!important;margin:0px 35px;line-height: 60px; + font-size: 22px;font-weight: bold;border-radius: 2px; +} +.enter_btn a.active{ + background: #DAECFC;color: #2BC4C6!important; +} +.setNewBnt{width: 100%!important;margin:0px!important;} +.enter_btn a.active:hover{background: #2CDAD4;color: #fff!important;} +.challenge_describe{ + color: #51B2C4;text-align: left;line-height: 22px; +} +li.challenge_box{ + border:1px solid #ABDCF1;background: #F1F8FD;padding:40px 20px;border-radius: 4px;width: 32%;margin-right: 2%; + box-sizing: border-box;float: left; +} +.challenge_box .challenge_b_t{ + font-size: 30px;color: #0E8B87;line-height: 30px;margin-bottom: 30px; +} +.challenge_b_d{ + color: #0B8298;font-size: 20px;line-height: 20px;text-align: left;font-weight: bold;margin-bottom: 40px;padding-left: 3px; +} +.challenge_b_des{ + line-height: 20px;color: #0B8298;font-size: 18px;text-align: left;text-align:justify;margin-bottom: 40px;min-height: 220px; +} +li.challenge_box:last-child{ + margin-right: 0px; +} +.algorithm{margin-bottom: 40px;} +.algorithm a{display: block;text-align: left;color: #23A8FD;position: relative;float: left;font-size: 18px;line-height: 22px;} +.algorithm a:after{position: absolute;left: 0px;bottom: -2px;background:#23A8FD;width: 100%;height: 1px;content: ''; } + + + + + + + + + + + + + + + @media screen and (max-width: 1600px) { @@ -698,7 +775,7 @@ a.enterLink{cursor: pointer;color: #418CCD!important;background: none!important; .personListLine > span{float: left;text-align: center;overflow:hidden; white-space: nowrap; text-overflow:ellipsis;} .t-c-1{width: 120px;} .t-c-2{width: 150px;text-align: left!important;} -.t-c-3{width: 210px;} +.t-c-3{width: 210px;min-height:20px;} .t-c-4{width: 200px;} .t-c-5{width: 80px;} /*东北赛区*/ @@ -3249,4 +3326,40 @@ line-height: 16px;display: inline-block;color: rgba(65, 140, 205, 1) !important; position:absolute; top: 12px; right: 20px; +} + +/*文库*/ +.library_nav li{ + float: left;cursor: pointer;margin-right: 30px;position: relative;color: #05101A;height: 40px;line-height: 20px; + font-size: 16px; +} +.library_nav li.active,.library_nav li:hover{ + color: #4cacff; +} +.library_nav li.active:after{ + position: absolute;content: '';background: #4cacff;color: #4cacff;width: 100%;height: 2px;bottom: 0px;left:0px; +} +.library_list{ + margin-bottom: 30px; +} +.library_list_item{ + background: #fff;padding:30px;margin-bottom: 15px;display: flex; +} +.upload_Title{ + position: relative;margin-right: 30px;float: left;line-height: 35px;font-size: 16px; +} +.upload_Title:before{ + position: absolute;left: -10px;top:2px;content: '*';color: #FE4F4C; +} +.librariesField{ + width: 100%;background: #F2F9FF;justify-content: center;align-items: center;display: -webkit-flex;text-align: center; + height: 120px;border-radius: 4px;border:1px dashed #4cacff; +} +.private_reason{overflow: hidden;max-height:150px;} +.private_reason li{margin-bottom: 10px;} +.successPage{ + justify-content: center;align-items: center;display: -webkit-flex;height: 570px;text-align: center;margin-bottom: 50px; +} +.changebtn{ + width: 127px;font-size: 16px;height: 40px; line-height: 40px; } \ No newline at end of file diff --git a/public/stylesheets/educoder/edu-main.css b/public/stylesheets/educoder/edu-main.css index 266f9b7f..fca9b02b 100644 --- a/public/stylesheets/educoder/edu-main.css +++ b/public/stylesheets/educoder/edu-main.css @@ -180,7 +180,7 @@ a.decoration{text-decoration: underline} /*定位*/ .pr{position: relative} .df {display:flex;display: -webkit-flex;display: -ms-flex;} -.flex1{flex: 1;} +.flex1{flex: 1;width: 0} /*去掉IE input框输入时自带的清除按钮*/ input::-ms-clear{display:none;} /*自定义滚动条宽度*/ @@ -529,6 +529,10 @@ a.edu-blueback-btn{padding: 0px 10px;background: #4CACFF;color: #fff!important;b a.edu-blueline-btn{padding: 0px 10px;color: #4CACFF!important;border: 1px solid #4CACFF;} a.edu-blueback-btn:hover{background-color: #459BE6;} a.edu-blueline-btn:hover{border:1px solid #459BE6;color: #459BE6!important;} +input.edu-blueback-btn{padding: 0px 10px;background: #4CACFF;color: #fff!important;border: 1px solid #4CACFF;} +input.edu-blueline-btn{padding: 0px 10px;color: #4CACFF!important;border: 1px solid #4CACFF;} +input.edu-blueback-btn:hover{background-color: #459BE6;} +input.edu-blueline-btn:hover{border:1px solid #459BE6;color: #459BE6!important;} a.edu-orangeback-btn{background-color: #ff7500;color: #fff!important;border:1px solid #FF7500} a.edu-orangeback-btn:hover{background-color: #F06200;}