diff --git a/app/controllers/admins/competition_stages_controller.rb b/app/controllers/admins/competition_stages_controller.rb index bea2f1a63..c7f95159c 100644 --- a/app/controllers/admins/competition_stages_controller.rb +++ b/app/controllers/admins/competition_stages_controller.rb @@ -60,7 +60,7 @@ class Admins::CompetitionStagesController < Admins::BaseController end # 如果计算的是最后一个阶段,则同时计算总成绩(只有一个阶段则不需计算) - if current_stage.max_end_time == current_competition.max_stage_end_time && current_competition.competition_stages.size != 0 + if current_stage.max_end_time == current_competition.max_stage_end_time && current_competition.competition_stages.size > 1 calculate_total_score current_competition end end @@ -174,6 +174,7 @@ class Admins::CompetitionStagesController < Admins::BaseController end def calculate_total_score competition + competition.competition_scores.where(competition_stage_id: 0).destroy_all competition.competition_teams.each do |team| total_score = 0 total_time = 0 @@ -183,8 +184,11 @@ class Admins::CompetitionStagesController < Admins::BaseController total_score += stage_score.try(:score).to_f * stage.score_rate total_time += stage_score.try(:cost_time).to_i end - CompetitionScore.create!(user_id: team.user_id, competition_team_id: team.id, competition_id: competition.id, - competition_stage_id: 0, score: total_score, cost_time: total_time) + + unless team.competition_scores.exists?(competition_id: competition.id, competition_stage_id: 0) + CompetitionScore.create!(user_id: team.user_id, competition_team_id: team.id, competition_id: competition.id, + competition_stage_id: 0, score: total_score, cost_time: total_time) + end end end end \ No newline at end of file diff --git a/app/controllers/competitions/competition_modules_controller.rb b/app/controllers/competitions/competition_modules_controller.rb index 8c66368fb..8eec4acc5 100644 --- a/app/controllers/competitions/competition_modules_controller.rb +++ b/app/controllers/competitions/competition_modules_controller.rb @@ -7,7 +7,7 @@ class Competitions::CompetitionModulesController < Competitions::BaseController @modules = current_competition.unhidden_competition_modules.order(position: :asc) # 未登录、未获奖用户,不展示获奖证书栏目 - if !current_user.logged? || !current_competition.competition_prize_users.exists?(user: current_user) + if !current_user.logged? || !current_competition.finished? || !current_competition.competition_prize_users.exists?(user: current_user) @modules = @modules.select { |mod| mod.name != '获奖证书' } end end diff --git a/app/controllers/competitions/competitions_controller.rb b/app/controllers/competitions/competitions_controller.rb index 31ed4367d..1eaa0dc22 100644 --- a/app/controllers/competitions/competitions_controller.rb +++ b/app/controllers/competitions/competitions_controller.rb @@ -44,6 +44,12 @@ class Competitions::CompetitionsController < Competitions::BaseController def common_header @competition = current_competition @competition_modules = @competition.unhidden_competition_modules + + # 未登录、未获奖用户,不展示获奖证书栏目 + if !current_user.logged? || !current_competition.finished? || !current_competition.competition_prize_users.exists?(user: current_user) + @competition_modules = @competition_modules.select { |mod| mod.name != '获奖证书' } + end + @user = current_user current_competition.increment!(:visits) @@ -113,6 +119,8 @@ class Competitions::CompetitionsController < Competitions::BaseController @competition = current_competition if params[:stage_id] @stage = @competition.competition_stages.find_by(id: params[:stage_id]) + elsif @competition.competition_stages.count == 1 + @stage = @competition.competition_stages.take end @records = @competition.competition_teams.joins(:competition_scores).where(competition_scores: {competition_stage_id: @stage&.id.to_i}) diff --git a/app/helpers/competitions_helper.rb b/app/helpers/competitions_helper.rb index b980aba3d..0a5b8804c 100644 --- a/app/helpers/competitions_helper.rb +++ b/app/helpers/competitions_helper.rb @@ -39,9 +39,11 @@ module CompetitionsHelper stages = [] statistic_stages = competition.competition_stages.where("score_rate > 0") - end_time = competition.max_stage_end_time || competition.end_time - if end_time && end_time < Time.now - stages << {id: nil, name: statistic_stages.size > 1 ? "总排行榜" : "排行榜", rate: 1.0, start_time: competition.start_time, end_time: competition.end_time} + unless statistic_stages.size == 1 + end_time = competition.max_stage_end_time || competition.end_time + if end_time && end_time < Time.now + stages << {id: nil, name: statistic_stages.size > 1 ? "总排行榜" : "排行榜", rate: 1.0, start_time: competition.start_time, end_time: competition.end_time} + end end statistic_stages.each do |stage| diff --git a/app/helpers/pdfkit_helper.rb b/app/helpers/pdfkit_helper.rb new file mode 100644 index 000000000..950ccc61f --- /dev/null +++ b/app/helpers/pdfkit_helper.rb @@ -0,0 +1,5 @@ +module PdfkitHelper + def download_image(url) + 'data:image/png;base64,' + Base64.encode64(open(url) { |io| io.read }) + end +end \ No newline at end of file diff --git a/app/jobs/generate_competition_personal_certificate_job.rb b/app/jobs/generate_competition_personal_certificate_job.rb new file mode 100644 index 000000000..efe0c8ff6 --- /dev/null +++ b/app/jobs/generate_competition_personal_certificate_job.rb @@ -0,0 +1,19 @@ +# 生成竞赛个人证书Job +class GenerateCompetitionPersonalCertificateJob < ApplicationJob + queue_as :default + + def perform(prize_user_id) + @prize_user = CompetitionPrizeUser.find_by(id: prize_user_id) + return if @prize_user.blank? || @prize_user.certificate_exist? + + template = @prize_user.user.is_teacher? ? 'teacher' : 'personal' + file = File.open(Rails.root.join("app/templates/competition_certificates/#{template}.html.erb")) + html = ERB.new(file.read).result(binding) + kit = PDFKit.new(html, page_width: 842, page_height: 595) + + path = @prize_user.certificate_path + dir = File.dirname(path) + FileUtils.mkdir_p(dir) unless File.directory?(dir) + kit.to_pdf(path) + end +end \ No newline at end of file diff --git a/app/jobs/generate_competition_team_certificate_job.rb b/app/jobs/generate_competition_team_certificate_job.rb new file mode 100644 index 000000000..4e119c5dc --- /dev/null +++ b/app/jobs/generate_competition_team_certificate_job.rb @@ -0,0 +1,24 @@ +# 生成竞赛团体证书Job +class GenerateCompetitionTeamCertificateJob < ApplicationJob + queue_as :default + + def perform(competition_team_id) + @team = CompetitionTeam.find_by(id: competition_team_id) + @prize = @team&.competition_prize_users&.first&.competition_prize + return if @team.blank? || !@prize.team_certificate_exists? || @team.certificate_exists? + + members = @team.team_members.includes(user: :user_extension).to_a + + @member_names = members.select { |m| !m.user.is_teacher? }.map(&:user_name).join('、') + @teacher_names = members.select { |m| m.user.is_teacher? }.map(&:user_name).join('、') + + file = File.open(Rails.root.join("app/templates/competition_certificates/team.html.erb")) + html = ERB.new(file.read).result(binding) + kit = PDFKit.new(html, page_width: 842, page_height: 595) + + path = @team.certificate_path + dir = File.dirname(path) + FileUtils.mkdir_p(dir) unless File.directory?(dir) + kit.to_pdf(path) + end +end \ No newline at end of file diff --git a/app/models/competition_prize.rb b/app/models/competition_prize.rb index 8acbc6713..dd551fabe 100644 --- a/app/models/competition_prize.rb +++ b/app/models/competition_prize.rb @@ -7,6 +7,30 @@ class CompetitionPrize < ApplicationRecord enumerize :category, in: %i[bonus unset] + def member_certificate_exists? + Util::FileManage.exists?(self, self.class.member_suffix) + end + + def teacher_certificate_exists? + Util::FileManage.exists?(self, self.class.teacher_suffix) + end + + def team_certificate_exists? + Util::FileManage.exists?(self, self.class.team_suffix) + end + + def member_certificate_path + Util::FileManage.source_disk_filename(self, self.class.member_suffix) + end + + def teacher_certificate_path + Util::FileManage.source_disk_filename(self, self.class.teacher_suffix) + end + + def team_certificate_path + Util::FileManage.source_disk_filename(self, self.class.team_suffix) + end + def self.member_suffix '_member' end diff --git a/app/models/team_member.rb b/app/models/team_member.rb index 31890ea2e..90bbe1613 100644 --- a/app/models/team_member.rb +++ b/app/models/team_member.rb @@ -13,4 +13,8 @@ class TeamMember < ApplicationRecord def en_role is_teacher? ? 'teacher' : 'member' end + + def user_name + user&.real_name + end end \ No newline at end of file diff --git a/app/services/admins/approve_competition_prize_user_service.rb b/app/services/admins/approve_competition_prize_user_service.rb index cd1c2101b..efdd72253 100644 --- a/app/services/admins/approve_competition_prize_user_service.rb +++ b/app/services/admins/approve_competition_prize_user_service.rb @@ -1,26 +1,35 @@ class Admins::ApproveCompetitionPrizeUserService < ApplicationService - attr_reader :prize_user, :approver + attr_reader :competition, :prize_user, :approver def initialize(prize_user, approver) - @prize_user = prize_user - @approver = approver + @competition = prize_user.competition + @prize_user = prize_user + @approver = approver end def call raise Error, '请勿重复审批' if prize_user.approved? raise Error, '该用户未认证完成' unless prize_user.user_certified? + prize = prize_user.competition_prize + ActiveRecord::Base.transaction do prize_user.approve prize_user.approver = approver prize_user.approved_at = Time.now prize_user.save! - if prize_user.competition_team.all_prize_approved? - # TODO: 生成团队证书 + # 生成个人证书 + # 是老师并且教师证书模板存在 或者是学生而且个人证书模板存在 + if (prize_user.user.is_teacher? && prize.teacher_certificate_exists?) || + (!prize_user.user.is_teacher? && prize.member_certificate_exists?) + GenerateCompetitionPersonalCertificateJob.perform_later(prize_user.id) end - # TODO: 生成个人证书 + # 生成团队证书 + if !competition.personal? && prize_user.competition_team.all_prize_approved? && prize.team_certificate_exists? + GenerateCompetitionTeamCertificateJob.perform_later(prize_user.competition_team.id) + end end end end \ No newline at end of file diff --git a/app/templates/competition_certificates/personal.html.erb b/app/templates/competition_certificates/personal.html.erb new file mode 100644 index 000000000..cec70e5d5 --- /dev/null +++ b/app/templates/competition_certificates/personal.html.erb @@ -0,0 +1,19 @@ + + +
+ + + + +<%= @prize_user.user.school_name %> <%= @prize_user.user.real_name %>(学号 <%= @prize_user.student_id %>):
+
+ 荣获第二届“全国高校绿色计算大赛”( <%= @prize_user.competition.sub_title %> )“全国<%= @prize_user.competition_prize.name %>”。
+
特发此证,以资鼓励。
+
<%= @prize_user.user.school_name %> <%= @prize_user.user.real_name %> 老师:
++ 在第二届“全国高校绿色计算大赛”(<%= @prize_user.competition.sub_title %>)中,带领学生团队 表现突出,成绩优异,荣获“优秀指导教师”称号。 +
+特发此证,以资鼓励。
++ <%= @member_names %>(指导老师:<%= @teacher_names %>) 在第二届“全国高校绿色计算大赛”(任务挑战组)中成绩突出,荣获“团体 <%= @prize.name %>”。 +
+特发此证,以资鼓励。
+