diff --git a/app/assets/javascripts/admins/competition_settings/index.js b/app/assets/javascripts/admins/competition_settings/index.js index 81fbf7519..1b0dc65b0 100644 --- a/app/assets/javascripts/admins/competition_settings/index.js +++ b/app/assets/javascripts/admins/competition_settings/index.js @@ -154,7 +154,7 @@ $(document).on('turbolinks:load', function(){ }, templateResult: function (item) { if(!item.id || item.id === '') return item.text; - return $("
" + item.real_name + "" + item.school_name + "" + item.hidden_phone + "
"); + return $("
" + item.real_name + "" + item.school_name + "" + item.hidden_phone + "
"); }, templateSelection: function(item){ if (item.id) { @@ -471,45 +471,45 @@ $(document).on('turbolinks:load', function(){ ' \n' + '
\n' + '
\n' + - ' 第1阶段\n' + + ' 第1阶段\n' + '
\n' + '
\n' + - ' 有效时间:\n' + - '
\n' + + '
有效时间:\n' + + '
\n' + ' \n' + '
\n' + ' ~\n' + - '
\n' + + '
\n' + ' \n' + - '
\n' + - ' 总任务数:\n' + - '
\n' + + '
\n' + + '
总任务数:\n' + + '
\n' + ' \n' + - '
\n' + - ' 成绩来源:\n' + - '
\n' + + '
\n' + + '
成绩来源:\n' + + '
\n' + ' \n' + - '
\n' + + '
\n' + '
\n' + '
\n' + '
\n' + - ' 任务1\n' + - '
\n' + + ' 任务1\n' + + '
\n' + ' \n' + '
\n' + '
\n' + '
\n' + - ' 任务2\n' + - '
\n' + + ' 任务2\n' + + '
\n' + ' \n' + '
\n' + '
\n' + '
\n' + - ' 任务3\n' + - '
\n' + + ' 任务3\n' + + '
\n' + ' \n' + '
\n' + '
\n' + @@ -547,45 +547,45 @@ $(document).on('turbolinks:load', function(){ var html='
\n' + - ' 第'+showCount+'阶段\n' + + ' 第'+showCount+'阶段\n' + '
\n' + '
\n' + - ' 有效时间:\n' + - '
\n' + + '
有效时间:\n' + + '
\n' + ' \n' + '
\n' + ' ~\n' + - '
\n' + + '
\n' + ' \n' + - '
\n' + - ' 总任务数:\n' + - '
\n' + + '
\n' + + '
总任务数:\n' + + '
\n' + ' \n' + - '
\n' + - ' 成绩来源:\n' + - '
\n' + + '
\n' + + '
成绩来源:\n' + + '
\n' + ' \n' + - '
\n' + + '
\n' + '
\n' + '
\n'+ '
\n' + - ' 任务1\n' + - '
\n' + + ' 任务1\n' + + '
\n' + ' \n' + '
\n' + '
\n' + '
\n' + - ' 任务2\n' + - '
\n' + + ' 任务2\n' + + '
\n' + ' \n' + '
\n' + '
\n' + '
\n' + - ' 任务3\n' + - '
\n' + + ' 任务3\n' + + '
\n' + ' \n' + '
\n' + '
\n' + @@ -600,6 +600,67 @@ $(document).on('turbolinks:load', function(){ $(".stage-update-form .section-start-time").datetimepicker(timeOptions); $(".stage-update-form .section-end-time").datetimepicker(timeOptions); }); + + // 奖项设置 + var $prizeContainer = $('#competition-prize-card'); + var competitionId = $prizeContainer.data('id'); + $(document).on('prize.save.success', function(){ + $.ajax({ + method: 'GET', + url: '/admins/competitions/' + competitionId + '/competition_prizes', + dataType: 'script' + }) + }); + + $('.modal.admin-upload-file-modal').on('upload:success', function(e, data){ + var $imageElement; + if(data.suffix === '_member'){ + $imageElement = $('.prize-member-image-' + data.source_id); + } else if(data.suffix === '_team'){ + $imageElement = $('.prize-team-image-' + data.source_id); + } else { + $imageElement = $('.prize-teacher-image-' + data.source_id); + } + $imageElement.attr('src', data.url); + $imageElement.show(); + $imageElement.next().html('重新上传'); + }) + + // 生成获奖记录 + $prizeContainer.on('click', '.generate-prize-user-action', function(){ + var $link = $(this); + + var generateRequest = function(){ + return $.ajax({ + method: 'POST', + url: '/admins/competitions/' + competitionId + '/competition_prize_users', + dataType: 'json', + success: function(data){ + if(data && data.status === 0){ + show_success_flash(); + $link.remove(); + } else { + showErrorNotify(data.message); + } + }, + error: function(res){ + var data = res.responseJSON; + showErrorNotify(data.message); + } + }) + } + + customConfirm({ + content: '确认生成吗?', + ok: function () { + customLoading({ + ajax: generateRequest + }) + } + }) + }); + } else { + $(document).unbind('prize.save.success'); } }); @@ -633,8 +694,8 @@ function change_total(item) { var html = ""; if(count > divCount){ for(var i=0;i < count-divCount ;i++){ - html+='
任务'+(divCount+i+1)+'\n' + - '
\n' + + html+='
任务'+(divCount+i+1)+'\n' + + '
\n' + '\n' + '
\n' + '
'; @@ -688,45 +749,45 @@ function addNewTab(competition_id) { '
\n' + '
\n' + '
\n' + - ' 第1阶段\n' + + ' 第1阶段\n' + '
\n' + '
\n' + - ' 有效时间:\n' + - '
\n' + + '
有效时间:\n' + + '
\n' + ' \n' + '
\n' + ' ~\n' + - '
\n' + + '
\n' + ' \n' + - '
\n' + - ' 总任务数:\n' + - '
\n' + + '
\n' + + '
总任务数:\n' + + '
\n' + ' \n' + - '
\n' + - ' 成绩来源:\n' + - '
\n' + + '
\n' + + '
成绩来源:\n' + + '
\n' + ' \n' + - '
\n' + + '
\n' + '
\n' + '
\n' + '
\n' + - ' 任务1\n' + - '
\n' + + ' 任务1\n' + + '
\n' + ' \n' + '
\n' + '
\n' + '
\n' + - ' 任务2\n' + - '
\n' + + ' 任务2\n' + + '
\n' + ' \n' + '
\n' + '
\n' + '
\n' + - ' 任务3\n' + - '
\n' + + ' 任务3\n' + + '
\n' + ' \n' + '
\n' + '
\n' + @@ -739,4 +800,4 @@ function addNewTab(competition_id) { '
'; $("#large_panel").append(html); } -} \ No newline at end of file +} diff --git a/app/assets/javascripts/admins/modals/admin-edit-subject-modal.js b/app/assets/javascripts/admins/modals/admin-edit-subject-modal.js index c76449936..02fa5a372 100644 --- a/app/assets/javascripts/admins/modals/admin-edit-subject-modal.js +++ b/app/assets/javascripts/admins/modals/admin-edit-subject-modal.js @@ -1,18 +1,18 @@ -$(document).on('turbolinks:load', function() { - $('.admin-modal-container').on('show.bs.modal', '.modal.admin-edit-subject-modal', function(){ - var $modal = $('.modal.admin-edit-subject-modal'); - var $form = $modal.find('form.admin-edit-subject-form'); +$(document).on('turbolinks:load', function () { + $('.admin-modal-container').on('show.bs.modal', '.modal.admin-edit-subject-modal', function () { + var $modal = $('.modal.admin-edit-subject-modal'); + var $form = $modal.find('form.admin-edit-subject-form'); - $modal.on('click', '.submit-btn', function(){ - $form.find('.error').html(''); - var url = $form.attr('action'); + $modal.on('click', '.submit-btn', function () { + $form.find('.error').html(''); + var url = $form.attr('action'); - $.ajax({ - method: 'PATCH', - dataType: 'script', - url: url, - data: $form.serialize() - }); - }); - }) -}); \ No newline at end of file + $.ajax({ + method: 'PATCH', + dataType: 'script', + url: url, + data: $form.serialize() + }); + }); + }) +}); diff --git a/app/assets/javascripts/admins/modals/admin-save-competition-prize-modal.js b/app/assets/javascripts/admins/modals/admin-save-competition-prize-modal.js new file mode 100644 index 000000000..9d874dc08 --- /dev/null +++ b/app/assets/javascripts/admins/modals/admin-save-competition-prize-modal.js @@ -0,0 +1,46 @@ +$(document).on('turbolinks:load', function() { + $('.admin-modal-container').on('show.bs.modal', '.admin-save-competition-prize-modal', function(event){ + var $modal = $('.modal.admin-save-competition-prize-modal'); + var $form = $modal.find('form.admin-save-competition-prize-form'); + + $form.validate({ + errorElement: 'span', + errorClass: 'danger text-danger', + rules: { + 'competition_prize[name]': { + required: true, + maxlength: 10 + }, + 'competition_prize[num]': { + required: true, + digits: true, + min: 1 + } + } + }); + + $modal.on('click', '.submit-btn', function(){ + $form.find('.error').html(''); + var url = $form.attr('action'); + var formMethod = $form.data('form-method') + + if ($form.valid()) { + $.ajax({ + method: formMethod, + dataType: 'json', + url: url, + data: $form.serialize(), + success: function(data){ + if(data && data.status === 0) { + show_success_flash(); + $(document).trigger('prize.save.success'); + $modal.modal('hide'); + } else { + $modal.find('.error').html(data.message) + } + } + }); + } + }); + }) +}); \ No newline at end of file diff --git a/app/assets/javascripts/admins/subjects/index.js b/app/assets/javascripts/admins/subjects/index.js index 6198d56aa..93621544e 100644 --- a/app/assets/javascripts/admins/subjects/index.js +++ b/app/assets/javascripts/admins/subjects/index.js @@ -1,107 +1,107 @@ -$(document).on('turbolinks:load', function() { - if ($('body.admins-subjects-index-page').length > 0) { - var $form = $('.subject-list-form'); +$(document).on('turbolinks:load', function () { + if ($('body.admins-subjects-index-page').length > 0) { + var $form = $('.subject-list-form'); - // ************** 学校选择 ************* - $form.find('.school-select').select2({ - theme: 'bootstrap4', - placeholder: '请选择创建者单位', - minimumInputLength: 1, - ajax: { - delay: 500, - url: '/api/schools/for_option.json', - dataType: 'json', - data: function(params){ - return { keyword: params.term }; - }, - processResults: function(data){ - return { results: data.schools } - } - }, - templateResult: function (item) { - if(!item.id || item.id === '') return item.text; - return item.name; - }, - templateSelection: function(item){ - if (item.id) { - } - return item.name || item.text; - } - }); + // ************** 学校选择 ************* + $form.find('.school-select').select2({ + theme: 'bootstrap4', + placeholder: '请选择创建者单位', + minimumInputLength: 1, + ajax: { + delay: 500, + url: '/api/schools/for_option.json', + dataType: 'json', + data: function (params) { + return {keyword: params.term}; + }, + processResults: function (data) { + return {results: data.schools} + } + }, + templateResult: function (item) { + if (!item.id || item.id === '') return item.text; + return item.name; + }, + templateSelection: function (item) { + if (item.id) { + } + return item.name || item.text; + } + }); - // 清空 - $form.on('click', '.clear-btn', function(){ - $form.find('select[name="status"]').val(''); - $form.find('.school-select').val('').trigger('change'); - $form.find('input[name="keyword"]').val(''); - $form.find('#homepage_show').attr('checked', false); - $form.find('#excellent').attr('checked', false); - $form.find('input[type="submit"]').trigger('click'); - }) + // 清空 + $form.on('click', '.clear-btn', function () { + $form.find('select[name="status"]').val(''); + $form.find('.school-select').val('').trigger('change'); + $form.find('input[name="keyword"]').val(''); + $form.find('#homepage_show').attr('checked', false); + $form.find('#excellent').attr('checked', false); + $form.find('input[type="submit"]').trigger('click'); + }) - // 上传图片 - $('.modal.admin-upload-file-modal').on('upload:success', function(e, data){ - var $imageElement = $('.subject-image-' + data.source_id); - $imageElement.attr('src', data.url); - $imageElement.show(); - $imageElement.next().html('重新上传'); - }) + // 上传图片 + $('.modal.admin-upload-file-modal').on('upload:success', function (e, data) { + var $imageElement = $('.subject-image-' + data.source_id); + $imageElement.attr('src', data.url); + $imageElement.show(); + $imageElement.next().html('重新上传'); + }) - // 定义状态切换监听事件 - var defineStatusChangeFunc = function(doElement, undoElement, url, callback){ - $('.subject-list-container').on('click', doElement, function(){ - var $doAction = $(this); - var $undoAction = $doAction.siblings(undoElement); + // 定义状态切换监听事件 + var defineStatusChangeFunc = function (doElement, undoElement, url, callback) { + $('.subject-list-container').on('click', doElement, function () { + var $doAction = $(this); + var $undoAction = $doAction.siblings(undoElement); - var subjectId = $doAction.data('id'); - customConfirm({ - content: '确认进行该操作吗?', - ok: function(){ - $.ajax({ - url: '/admins/subjects/' + subjectId + url, - method: 'POST', - dataType: 'json', - success: function() { - show_success_flash(); - $doAction.hide(); - $undoAction.show(); - if(callback && typeof callback === "function"){ - callback(subjectId, url); - } - } - }); - } - }); - }); - } - // 隐藏与取消隐藏 - defineStatusChangeFunc('.hide-action', '.active-action', '/hide'); - defineStatusChangeFunc('.active-action', '.hide-action', '/cancel_hide'); + var subjectId = $doAction.data('id'); + customConfirm({ + content: '确认进行该操作吗?', + ok: function () { + $.ajax({ + url: '/admins/subjects/' + subjectId + url, + method: 'POST', + dataType: 'json', + success: function () { + show_success_flash(); + $doAction.hide(); + $undoAction.show(); + if (callback && typeof callback === "function") { + callback(subjectId, url); + } + } + }); + } + }); + }); + } + // 隐藏与取消隐藏 + defineStatusChangeFunc('.hide-action', '.active-action', '/hide'); + defineStatusChangeFunc('.active-action', '.hide-action', '/cancel_hide'); - // 首页展示与取消首页展示 - var homepageShowCallback = function(subjectId, url){ - var $subjectItem = $('.subject-list-container').find('.subject-item-' + subjectId); + // 首页展示与取消首页展示 + var homepageShowCallback = function (subjectId, url) { + var $subjectItem = $('.subject-list-container').find('.subject-item-' + subjectId); - if(url === '/homepage_show'){ - $subjectItem.find('.homepage-show-badge').show(); - } else { - $subjectItem.find('.homepage-show-badge').hide(); - } - } - defineStatusChangeFunc('.homepage-show-action', '.homepage-hide-action', '/homepage_show', homepageShowCallback); - defineStatusChangeFunc('.homepage-hide-action', '.homepage-show-action', '/cancel_homepage_show', homepageShowCallback); + if (url === '/homepage_show') { + $subjectItem.find('.homepage-show-badge').show(); + } else { + $subjectItem.find('.homepage-show-badge').hide(); + } + } + defineStatusChangeFunc('.homepage-show-action', '.homepage-hide-action', '/homepage_show', homepageShowCallback); + defineStatusChangeFunc('.homepage-hide-action', '.homepage-show-action', '/cancel_homepage_show', homepageShowCallback); - // 设为金课与取消金课 - var excellentCallback = function(subjectId, url){ - var $subjectItem = $('.subject-list-container').find('.subject-item-' + subjectId); + // 设为金课与取消金课 + var excellentCallback = function (subjectId, url) { + var $subjectItem = $('.subject-list-container').find('.subject-item-' + subjectId); - if(url === '/excellent'){ - $subjectItem.find('.excellent-badge').show(); - } else { - $subjectItem.find('.excellent-badge').hide(); - } - } - defineStatusChangeFunc('.excellent-action', '.cancel-excellent-action', '/excellent', excellentCallback); - defineStatusChangeFunc('.cancel-excellent-action', '.excellent-action', '/cancel_excellent', excellentCallback); - } -}); \ No newline at end of file + if (url === '/excellent') { + $subjectItem.find('.excellent-badge').show(); + } else { + $subjectItem.find('.excellent-badge').hide(); + } + } + defineStatusChangeFunc('.excellent-action', '.cancel-excellent-action', '/excellent', excellentCallback); + defineStatusChangeFunc('.cancel-excellent-action', '.excellent-action', '/cancel_excellent', excellentCallback); + } +}); diff --git a/app/assets/javascripts/common.js b/app/assets/javascripts/common.js index a88ad5006..4589f52c2 100644 --- a/app/assets/javascripts/common.js +++ b/app/assets/javascripts/common.js @@ -66,10 +66,32 @@ function customConfirm(opts){ return $.confirm($.extend({}, defaultOpts, opts)) } +function customLoading(opts) { + var loading; + var defaultOpts = { + content: opts.ajax, + contentLoaded: function(){ + setTimeout(function(){ + loading.close() + }, 200); + } + } + loading = $.confirm($.extend({}, defaultOpts, opts)); + return loading; +} + function show_success_flash(message){ $.notify({ - message: message || '操作成功' + message: message || '操作成功' },{ type: 'success' }); -} \ No newline at end of file +} + +function showErrorNotify(message){ + $.notify({ + message: message || '操作失败' + },{ + type: 'danger' + }); +} diff --git a/app/assets/stylesheets/admins/competition_settings.scss b/app/assets/stylesheets/admins/competition_settings.scss index cef12cae3..481a2d9b0 100644 --- a/app/assets/stylesheets/admins/competition_settings.scss +++ b/app/assets/stylesheets/admins/competition_settings.scss @@ -87,5 +87,30 @@ .row:last-child{ border:none; } + + .task_Input_div:nth-child(3n-2) > span.col-4{ + flex: 0 0 81px; + max-width: 81px; + } + .task_Input_div:nth-child(3n-2){ + flex: 0 0 50%; + max-width: 50%; + } + .task_Input_div:nth-child(3n-1){ + flex: 0 0 25%; + max-width: 25%; + } + .task_Input_div:nth-child(3n){ + flex: 0 0 33.3%; + max-width: 33.3%; + } + .task_Input_div:nth-child(3n) > span.col-4{ + flex: 0 0 25%; + max-width: 25%; + } + .task_Input_div:nth-child(3n) > div.col-6{ + flex: 0 0 58.3%; + max-width: 58.3%; + } } } \ No newline at end of file diff --git a/app/controllers/admins/competition_prize_users_controller.rb b/app/controllers/admins/competition_prize_users_controller.rb new file mode 100644 index 000000000..50d11e211 --- /dev/null +++ b/app/controllers/admins/competition_prize_users_controller.rb @@ -0,0 +1,41 @@ +class Admins::CompetitionPrizeUsersController < Admins::BaseController + def index + @competition = current_competition + + prize_users = Admins::CompetitionPrizeUserQuery.call(params.merge(competition_id: current_competition.id)) + include_class = [:competition_team, :competition_prize, :approver, + user: [:process_real_name_apply, :process_professional_apply, user_extension: :school]] + @prize_users = paginate(prize_users.preload(include_class)) + end + + def create + Admins::CreateCompetitionPrizeUsersService.call(current_competition) + render_ok + rescue ApplicationService::Error => ex + render_error(ex.message) + end + + def approve + Admins::ApproveCompetitionPrizeUserService.call(current_prize_user, current_user) + @prize_user = current_prize_user + rescue ApplicationService::Error => ex + render_js_error(ex.message, type: :notify) + end + + def unapprove + Admins::UnapproveCompetitionPrizeUserService.call(current_prize_user, current_user) + @prize_user = current_prize_user + rescue ApplicationService::Error => ex + render_js_error(ex.message, type: :notify) + end + + private + + def current_prize_user + @_current_prize_user ||= current_competition.competition_prize_users.find(params[:id]) + end + + def current_competition + @_current_competition ||= Competition.find(params[:competition_id]) + end +end \ No newline at end of file diff --git a/app/controllers/admins/competition_prizes_controller.rb b/app/controllers/admins/competition_prizes_controller.rb new file mode 100644 index 000000000..cde48f96e --- /dev/null +++ b/app/controllers/admins/competition_prizes_controller.rb @@ -0,0 +1,43 @@ +class Admins::CompetitionPrizesController < Admins::BaseController + def index + @competition = current_competition + end + + def new + @prize = current_competition.competition_prizes.new + end + + def create + @prize = current_competition.competition_prizes.create!(save_params) + render_ok + end + + def edit + @prize = current_competition_prize + end + + def update + current_competition_prize.update!(save_params) + render_ok + end + + def destroy + current_competition_prize.destroy! + + render_delete_success + end + + private + + def current_competition_prize + @_current_competition_prize ||= current_competition.competition_prizes.find(params[:id]) + end + + def current_competition + @_current_competition ||= Competition.find(params[:competition_id]) + end + + def save_params + params.require(:competition_prize).permit(:name, :category, :num) + end +end \ No newline at end of file diff --git a/app/controllers/competitions/certificates_controller.rb b/app/controllers/competitions/certificates_controller.rb new file mode 100644 index 000000000..ab52920cd --- /dev/null +++ b/app/controllers/competitions/certificates_controller.rb @@ -0,0 +1,23 @@ +class Competitions::CertificatesController < Competitions::BaseController + def personal + prize_user = CompetitionPrizeUser.find_by!(user: current_user, id: params[:id]) + return render_not_found unless prize_user.certificate_exist? + + team = prize_user.competition_team + prize = prize_user.competition_prize + filename = "#{current_competition.name}-#{prize.name}-#{team.name}-#{prize_user.user.real_name}.pdf" + + send_file prize_user.certificate_path, filename: filename + end + + def team + team = CompetitionTeam.find(id: params[:id]) + return render_forbidden unless team.team_members.exists?(user_id: current_user.id) + return render_not_found unless team.certificate_exist? + + prize = team.competition_prize_users.first.competition_prize + filename = "#{current_competition.name}-#{prize.name}-#{team.name}.pdf" + + send_file team.certificate_path, filename: filename + 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 c4692af70..8c66368fb 100644 --- a/app/controllers/competitions/competition_modules_controller.rb +++ b/app/controllers/competitions/competition_modules_controller.rb @@ -5,6 +5,11 @@ class Competitions::CompetitionModulesController < Competitions::BaseController def index @modules = current_competition.unhidden_competition_modules.order(position: :asc) + + # 未登录、未获奖用户,不展示获奖证书栏目 + if !current_user.logged? || !current_competition.competition_prize_users.exists?(user: current_user) + @modules = @modules.select { |mod| mod.name != '获奖证书' } + end end def show diff --git a/app/controllers/competitions/competitions_controller.rb b/app/controllers/competitions/competitions_controller.rb index 1a80dc7e6..31ed4367d 100644 --- a/app/controllers/competitions/competitions_controller.rb +++ b/app/controllers/competitions/competitions_controller.rb @@ -22,7 +22,7 @@ class Competitions::CompetitionsController < Competitions::BaseController @count = competitions.count competitions = competitions.order(published_at: :desc, online_time: :desc) - @competitions = paginate(competitions.includes(sponsor_schools: :school, current_stage_section: :competition_stage)) + @competitions = paginate(competitions.includes(:competition_mode_setting, sponsor_schools: :school, current_stage_section: :competition_stage)) ids = @competitions.map(&:id) @member_count_map = TeamMember.where(competition_id: ids).group(:competition_id).count diff --git a/app/controllers/competitions/prize_leader_accounts_controller.rb b/app/controllers/competitions/prize_leader_accounts_controller.rb new file mode 100644 index 000000000..0c01e2738 --- /dev/null +++ b/app/controllers/competitions/prize_leader_accounts_controller.rb @@ -0,0 +1,25 @@ +class Competitions::PrizeLeaderAccountsController < Competitions::BaseController + before_action :require_prize_team_leader! + + def update + Competitions::SavePrizeTeamAccountService.call(current_competition, current_user, update_params) + render_ok + rescue ApplicationService::Error => ex + render_error(ex.message) + end + + private + + def require_prize_team_leader! + prize_user = current_competition.competition_prize_users.joins(:competition_prize) + .where(competition_prizes: { category: :bonus }) + .find_by(leader: true, user_id: current_user.id) + return if prize_user.present? + + render_forbidden + end + + def update_params + params.permit(:bank, :second_bank, :card_no) + end +end \ No newline at end of file diff --git a/app/controllers/competitions/prizes_controller.rb b/app/controllers/competitions/prizes_controller.rb new file mode 100644 index 000000000..aab1df9a1 --- /dev/null +++ b/app/controllers/competitions/prizes_controller.rb @@ -0,0 +1,26 @@ +class Competitions::PrizesController < Competitions::BaseController + before_action :require_prize_user! + + def show + self_prizes = current_competition.competition_prize_users.where(user_id: current_user.id).includes(:competition_team) + + @leader = self_prizes.any?(&:leader?) # 是否为队长 + @bank_account = self_prizes.find(&:leader?).extra if @leader + + @self_prizes = self_prizes.select(&:certificate_exist?) # 个人证书quit + @team_prizes = self_prizes.map(&:competition_team).uniq.select(&:certificate_exists?) # 团队证书 + + prize_users = current_competition.competition_prize_users.where(competition_team_id: self_prizes.map(&:competition_team_id)) + .includes(:competition_team, user: [:user_extension, :process_real_name_apply, :process_professional_apply]) + + @prize_user_map = prize_users.group_by(&:competition_team) + end + + private + + def require_prize_user! + return if current_competition.competition_prize_users.exists?(user: current_user) + + render_forbidden + end +end \ No newline at end of file diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb index 3b6273465..9df7a0d6c 100644 --- a/app/controllers/courses_controller.rb +++ b/app/controllers/courses_controller.rb @@ -257,8 +257,8 @@ class CoursesController < ApplicationController user_ids = all_members.map(&:user_id) rank = user_ids.index(current_user.id).to_i + 1 if rank > 10 - current_member = all_members.select{|member| member.user_id == current_user.id} - @course_members << current_member + current_member = all_members.select{|member| member.user_id == current_user.id}.first + @course_members << current_member if current_member.present? end end end diff --git a/app/controllers/exercises_controller.rb b/app/controllers/exercises_controller.rb index bd5a41123..a6464a151 100644 --- a/app/controllers/exercises_controller.rb +++ b/app/controllers/exercises_controller.rb @@ -605,6 +605,21 @@ class ExercisesController < ApplicationController end end + # 对未提交的用户进行调分 + def adjust_score + exercise_user = @exercise.exercise_users.find_by!(user_id: params[:user_id]) + tip_exception("已提交的作品请去评阅页进行调分") if exercise_user.commit_status == 1 + tip_exception("分数不能为空") if params[:score].blank? + tip_exception("分数不能超过0-#{@exercise.question_scores}") if params[:score].to_f < 0 || params[:score].to_f.round(1) > @exercise.question_scores.round(1) + + ActiveRecord::Base.transaction do + start_at_time = exercise_user.start_at || Time.now + exercise_user.update_attributes!(start_at: start_at_time, end_at: Time.now, status: 1, commit_status: 1, score: params[:score].to_f.round(2), commit_method: 5) + ExerciseUserScore.create!(exercise_id: @exercise.id, exercise_user_id: exercise_user.id, score: params[:score], comment: params[:comment]) + normal_status("操作成功") + end + end + #我的题库 def my_exercises ActiveRecord::Base.transaction do diff --git a/app/controllers/homework_commons_controller.rb b/app/controllers/homework_commons_controller.rb index 5d27de7b8..6d627df33 100644 --- a/app/controllers/homework_commons_controller.rb +++ b/app/controllers/homework_commons_controller.rb @@ -125,7 +125,7 @@ class HomeworkCommonsController < ApplicationController # 学生已提交作品且补交(提交)已截止、作品公开、非匿评阶段 if @work&.work_status.to_i > 0 && (@homework.work_public || @homework.score_open) && ((!@homework.anonymous_comment && @homework.end_or_late) || (@homework_detail_manual.comment_status > 4 && @homework.end_or_late)) - @student_works = student_works.where("user_id != #{@work.user_id}") + @student_works = student_works.where("student_works.user_id != #{@work.user_id}") # 匿评、申诉阶段只能看到分配给自己的匿评作品 elsif @work&.work_status.to_i > 0 && @homework.anonymous_comment && @homework_detail_manual.comment_status > 2 && @homework_detail_manual.comment_status <= 4 @@ -572,10 +572,13 @@ class HomeworkCommonsController < ApplicationController if @homework.homework_type == "practice" # 实训作业的评分设置 + tip_exception("总分值不能为空") if params[:total_score].blank? + tip_exception("总分值不能小于0") if params[:total_score].to_i < 0 tip_exception("缺少answer_open_evaluation参数") if params[:answer_open_evaluation].nil? tip_exception("缺少work_efficiency参数") if params[:work_efficiency].nil? tip_exception("缺少eff_score参数") if params[:work_efficiency] && params[:eff_score].blank? tip_exception("效率分不能小于等于0") if params[:eff_score] && params[:eff_score].to_i <= 0 + tip_exception("效率分不能大于总分值") if params[:eff_score] && params[:eff_score].to_i > params[:total_score].to_i tip_exception("缺少shixun_evaluation参数") if params[:shixun_evaluation].blank? tip_exception("缺少challenge_settings参数") if params[:challenge_settings].blank? # tip_exception("缺少challenge_id参数") if params[:challenge_settings][:challenge_id].blank? @@ -584,6 +587,7 @@ class HomeworkCommonsController < ApplicationController # params[:challenge_settings][:challenge_score].length != params[:challenge_settings][:challenge_id].length current_eff_score = @homework.eff_score + @homework.total_score = params[:total_score] @homework.work_efficiency = params[:work_efficiency] @homework.eff_score = params[:work_efficiency] ? params[:eff_score].to_i : 0 diff --git a/app/controllers/student_works_controller.rb b/app/controllers/student_works_controller.rb index b7a6953a5..c45bca268 100644 --- a/app/controllers/student_works_controller.rb +++ b/app/controllers/student_works_controller.rb @@ -534,7 +534,9 @@ class StudentWorksController < ApplicationController # 作品调分 def adjust_score tip_exception("分数不能为空") if params[:score].blank? - tip_exception("分数不能超过0-100") if params[:score].to_f < 0 || params[:score].to_f > 100 + tip_exception("分数不能超过0-100") if @homework.homework_type != "practice" && (params[:score].to_f < 0 || params[:score].to_f.round(1) > 100.round(1)) + tip_exception("已提交的作品请去评阅页进行调分") if @homework.homework_type == "practice" && @work.work_status > 0 + tip_exception("分数不能超过总分值#{@homework.total_score}") if @homework.homework_type == "practice" && (params[:score].to_f < 0 || params[:score].to_f.round(1) > @homework.total_score.round(1)) ActiveRecord::Base.transaction do begin # 分数不为空的历史评阅都置为失效 diff --git a/app/controllers/users/authentication_applies_controller.rb b/app/controllers/users/authentication_applies_controller.rb index 2fec6e0cd..6a2c20893 100644 --- a/app/controllers/users/authentication_applies_controller.rb +++ b/app/controllers/users/authentication_applies_controller.rb @@ -4,10 +4,16 @@ class Users::AuthenticationAppliesController < Users::BaseAccountController def create Users::ApplyAuthenticationService.call(observed_user, create_params) render_ok - rescue Users::ApplyAuthenticationService::Error => ex + rescue ApplicationService::Error => ex render_error(ex.message) end + def destroy + return render_error('已认证后不能撤销') if observed_user.authentication? + observed_user.process_real_name_apply&.revoke! + render_ok + end + private def create_params diff --git a/app/controllers/users/professional_auth_applies_controller.rb b/app/controllers/users/professional_auth_applies_controller.rb index b2603f642..5a9d305ff 100644 --- a/app/controllers/users/professional_auth_applies_controller.rb +++ b/app/controllers/users/professional_auth_applies_controller.rb @@ -8,6 +8,12 @@ class Users::ProfessionalAuthAppliesController < Users::BaseAccountController render_error(ex.message) end + def destroy + return render_error('已认证后不能撤销') if observed_user.professional_certification? + observed_user.process_professional_apply&.revoke! + render_ok + end + private def create_params diff --git a/app/forms/competitions/save_prize_team_account_form.rb b/app/forms/competitions/save_prize_team_account_form.rb new file mode 100644 index 000000000..b048c8368 --- /dev/null +++ b/app/forms/competitions/save_prize_team_account_form.rb @@ -0,0 +1,9 @@ +class Competitions::SavePrizeTeamAccountForm + include ActiveModel::Model + + attr_accessor :bank, :second_bank, :card_no + + validates :bank, presence: true + validates :second_bank, presence: true + validates :card_no, presence: true +end diff --git a/app/helpers/admins/competition_prize_users_helper.rb b/app/helpers/admins/competition_prize_users_helper.rb new file mode 100644 index 000000000..0fa338341 --- /dev/null +++ b/app/helpers/admins/competition_prize_users_helper.rb @@ -0,0 +1,10 @@ +module Admins::CompetitionPrizeUsersHelper + def display_auth_state(flag, other = false, success: nil, normal: nil, error: nil) + success ||= ''.html_safe + normal ||= '--' + error ||= ''.html_safe + + return success if flag + other ? normal : error + end +end \ No newline at end of file diff --git a/app/helpers/courses_helper.rb b/app/helpers/courses_helper.rb index 4de15b20f..a28668c6b 100644 --- a/app/helpers/courses_helper.rb +++ b/app/helpers/courses_helper.rb @@ -63,6 +63,8 @@ module CoursesHelper "/courses/#{course.id}/boards/#{course_board.id}" when "course_group" "/courses/#{course.id}/course_groups" + when "statistics" + "/courses/#{course.id}/statistics" end end diff --git a/app/models/competition.rb b/app/models/competition.rb index 9eac28616..fa1267025 100644 --- a/app/models/competition.rb +++ b/app/models/competition.rb @@ -29,6 +29,9 @@ class Competition < ApplicationRecord has_many :competition_managers, dependent: :destroy has_many :managers, through: :competition_managers, source: :user + has_many :competition_prizes, dependent: :destroy + has_many :competition_prize_users, dependent: :destroy + after_create :create_competition_modules def mode_type @@ -46,6 +49,12 @@ class Competition < ApplicationRecord end end + # 报名数 + def team_member_count + course = competition_mode_setting&.course if mode == 2 + course ? course.students.count : team_members.count + end + def sponsor_schools_name sponsor_schools.map{|sponsor| sponsor.school.name} end @@ -131,7 +140,7 @@ class Competition < ApplicationRecord end def all_module_types - %w[home enroll inform chart resource] + %w[home enroll inform chart resource certificate] end def max_stage_end_time @@ -146,6 +155,10 @@ class Competition < ApplicationRecord user && competition_managers.exists?(user_id: user.id) end + def finished? + end_time.blank? || end_time < Time.now + end + private def get_module_name type @@ -155,6 +168,7 @@ class Competition < ApplicationRecord when 'inform' then '通知公告' when 'chart' then '排行榜' when 'resource' then '资料下载' + when 'certificate' then '获奖证书' else '' end end diff --git a/app/models/competition_prize.rb b/app/models/competition_prize.rb new file mode 100644 index 000000000..8acbc6713 --- /dev/null +++ b/app/models/competition_prize.rb @@ -0,0 +1,21 @@ +class CompetitionPrize < ApplicationRecord + extend Enumerize + + belongs_to :competition + + has_many :competition_prize_users, dependent: :destroy + + enumerize :category, in: %i[bonus unset] + + def self.member_suffix + '_member' + end + + def self.teacher_suffix + '_teacher' + end + + def self.team_suffix + '_team' + end +end \ No newline at end of file diff --git a/app/models/competition_prize_user.rb b/app/models/competition_prize_user.rb new file mode 100644 index 000000000..fe5877e4d --- /dev/null +++ b/app/models/competition_prize_user.rb @@ -0,0 +1,48 @@ +class CompetitionPrizeUser < ApplicationRecord + include AASM + + belongs_to :competition + belongs_to :competition_team + belongs_to :competition_prize + belongs_to :user + belongs_to :approver, class_name: 'User', optional: true # 审批人 + + serialize :extra, JSON + + aasm(:status) do + state :pending, initial: true + state :approved + + event :approve do + transitions from: [:pending], to: :approved, guard: :user_certified? + end + + event :unapprove do + transitions from: [:approved], to: :pending + end + end + + delegate :bank, :second_bank, :card_no, to: :extra, allow_nil: true + + def user_certified? + user.certification? && user.professional_certification? + end + + def certificate_exist? + Util::FileManage.exists?(self) + end + + def certificate_url + Util::FileManage.source_disk_file_url(self) + end + + def certificate_path + Util::FileManage.source_disk_filename(self) + end + + def role_text + return '队长' if leader? + + user.is_teacher? ? '教师' : '队员' + end +end \ No newline at end of file diff --git a/app/models/competition_team.rb b/app/models/competition_team.rb index a05ceb032..ecfdd218a 100644 --- a/app/models/competition_team.rb +++ b/app/models/competition_team.rb @@ -11,6 +11,8 @@ class CompetitionTeam < ApplicationRecord has_many :members, -> { without_teachers }, class_name: 'TeamMember' has_many :teachers, -> { only_teachers }, class_name: 'TeamMember' + has_many :competition_prize_users, dependent: :destroy + def group_team_type? team_type.zero? end @@ -48,4 +50,24 @@ class CompetitionTeam < ApplicationRecord def members_name members.map{|member| member.user.real_name}.join(",") end + + def all_prize_approved? + !competition_prize_users.exists?(status: :pending) + end + + def certificate_exists? + Util::FileManage.exists?(self, self.class.certificate_suffix) + end + + def certificate_url + Util::FileManage.source_disk_file_url(self, self.class.certificate_suffix) + end + + def certificate_path + Util::FileManage.source_disk_filename(self, self.class.certificate_suffix) + end + + def self.certificate_suffix + '_CERT' + end end \ No newline at end of file diff --git a/app/models/exercise_user.rb b/app/models/exercise_user.rb index 0f2e8456e..fb2034998 100644 --- a/app/models/exercise_user.rb +++ b/app/models/exercise_user.rb @@ -1,8 +1,10 @@ class ExerciseUser < ApplicationRecord - # commit_method 0 为默认, 1为学生的手动提交,2为倒计时结束后自动提交,3为试卷定时截止的自动提交, 4为教师手动的立即截止 + # commit_method 0 为默认, 1为学生的手动提交,2为倒计时结束后自动提交,3为试卷定时截止的自动提交, 4为教师手动的立即截止, 5为老师调分 belongs_to :user belongs_to :exercise + has_many :exercise_user_scores, dependent: :destroy + scope :commit_exercise_by_status, lambda { |s| where(commit_status: s) } scope :exercise_user_committed, -> {where("commit_status != ?",0) } scope :current_exercise_user, lambda { |user_id,exercise_id| where(user_id: user_id,exercise_id:exercise_id)} diff --git a/app/models/exercise_user_score.rb b/app/models/exercise_user_score.rb new file mode 100644 index 000000000..d022b0b31 --- /dev/null +++ b/app/models/exercise_user_score.rb @@ -0,0 +1,5 @@ +class ExerciseUserScore < ApplicationRecord + belongs_to :exercise + belongs_to :exercise_user + belongs_to :user +end diff --git a/app/models/user.rb b/app/models/user.rb index 4d13727db..85b9ef551 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -503,6 +503,10 @@ class User < ApplicationRecord phone.present? end + def email_binded? + mail.present? + end + def self.current=(user) Thread.current[:current_user] = user end diff --git a/app/queries/admins/competition_prize_user_query.rb b/app/queries/admins/competition_prize_user_query.rb new file mode 100644 index 000000000..c6cdfb562 --- /dev/null +++ b/app/queries/admins/competition_prize_user_query.rb @@ -0,0 +1,77 @@ +class Admins::CompetitionPrizeUserQuery < ApplicationQuery + include CustomSortable + + attr_reader :params + + sort_columns :rank, default_by: :rank, default_direction: :asc + + def initialize(params) + @params = params + end + + def call + records = CompetitionPrizeUser.all + + # 竞赛过滤 + records = records.where(competition_id: params[:competition_id]) if params[:competition_id].present? + + # 关键字检索 + keyword = params[:keyword].to_s.strip + if keyword.present? + like_sql = 'competition_teams.name LIKE :keyword OR schools.name LIKE :keyword' + records = records.left_joins(:competition_team, user: { user_extension: :school }) + .where(like_sql, keyword: "%#{keyword}%") + end + + # 奖项过滤 + records = records.where(competition_prize_id: params[:prize_id]) if params[:prize_id].present? + + # 审批状态过滤 + records = records.where(status: params[:status]) if params[:status].present? + + # 职业过滤 + if params[:identity].present? + records = records.left_joins(user: :user_extension).where(user_extensions: { identity: params[:identity] }) + end + + # 实名认证过滤 + records = real_name_auth_filter(records) if params[:real_name_auth].present? + + # 职业认证过滤 + records = professional_auth_filter(records) if params[:professional_auth].present? + + custom_sort(records, params[:sort_by], params[:sort_direction]) + end + + private + + def real_name_auth_filter(records) + records = records.left_joins(:user) + sql = ApplyUserAuthentication.real_name_auth.processing.where('apply_user_authentications.user_id = users.id').to_sql + + case params[:real_name_auth] + when 'authed' then + records.where(users: { authentication: true }) + when 'not_authed' then + records.where(users: { authentication: false }).where("NOT EXISTS (#{sql})") + when 'authing' then + records.where(users: { authentication: false }).where("EXISTS (#{sql})") + else records + end + end + + def professional_auth_filter(records) + records = records.left_joins(:user) + sql = ApplyUserAuthentication.professional_auth.processing.where('apply_user_authentications.user_id = users.id').to_sql + + case params[:professional_auth] + when 'authed' then + records.where(users: { professional_certification: true }) + when 'not_authed' then + records.where(users: { professional_certification: false }).where("NOT EXISTS (#{sql})") + when 'authing' then + records.where(users: { professional_certification: false }).where("EXISTS (#{sql})") + else records + end + 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 new file mode 100644 index 000000000..cd1c2101b --- /dev/null +++ b/app/services/admins/approve_competition_prize_user_service.rb @@ -0,0 +1,26 @@ +class Admins::ApproveCompetitionPrizeUserService < ApplicationService + attr_reader :prize_user, :approver + + def initialize(prize_user, approver) + @prize_user = prize_user + @approver = approver + end + + def call + raise Error, '请勿重复审批' if prize_user.approved? + raise Error, '该用户未认证完成' unless prize_user.user_certified? + + 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: 生成团队证书 + end + + # TODO: 生成个人证书 + end + end +end \ No newline at end of file diff --git a/app/services/admins/create_competition_prize_users_service.rb b/app/services/admins/create_competition_prize_users_service.rb new file mode 100644 index 000000000..0cacaa2f1 --- /dev/null +++ b/app/services/admins/create_competition_prize_users_service.rb @@ -0,0 +1,70 @@ +class Admins::CreateCompetitionPrizeUsersService < ApplicationService + attr_reader :competition + + def initialize(competition) + @competition = competition + end + + def call + raise Error, '竞赛还未结束' unless competition.finished? + raise Error, '请勿重复生成' if competition.competition_prize_users.exists? + raise Error, '请先设置奖项' if prizes.blank? + raise Error, '无获奖队伍' if prize_teams.blank? + + ActiveRecord::Base.transaction do + columns = %i[competition_id competition_team_id competition_prize_id user_id + status rank leader created_at updated_at] + + CompetitionPrizeUser.bulk_insert(*columns) do |worker| + prize_teams.each_with_index do |team, index| + rank = index + 1 + prize = team_prize(rank) # 根据排名获取当前队伍奖项 + + team.team_members.each do |member| + attr = { + competition_id: competition.id, + competition_team_id: team.id, + competition_prize_id: prize.id, + user_id: member.user_id, + leader: member.creator?, + status: :pending, + rank: rank + } + + worker.add(attr) + end + end + end + end + end + + private + + def prizes + @_prizes ||= competition.competition_prizes.order(id: :asc).to_a + end + + def team_prize(rank) + current = 0 + prizes.each do |prize| + return prize if rank > current && rank <= current + prize.num + + current += prize.num + end + end + + def prize_teams + @_prize_teams ||= begin + prize_num_total = prizes.sum(&:num) + + # 只有一个阶段,则成绩为该阶段成绩,否则为stage ID为0的总成绩 + stage_id = competition.competition_stages.count == 1 ? competition.competition_stages.first.id : 0 + + competition.competition_teams.joins(:competition_scores) + .where(competition_scores: { competition_stage_id: stage_id }) + .order("competition_scores.score desc, competition_scores.cost_time desc") + .includes(:team_members) + .limit(prize_num_total) + end + end +end \ No newline at end of file diff --git a/app/services/admins/unapprove_competition_prize_user_service.rb b/app/services/admins/unapprove_competition_prize_user_service.rb new file mode 100644 index 000000000..0bfcd20c1 --- /dev/null +++ b/app/services/admins/unapprove_competition_prize_user_service.rb @@ -0,0 +1,27 @@ +class Admins::UnapproveCompetitionPrizeUserService < ApplicationService + attr_reader :prize_user, :approver + + def initialize(prize_user, approver) + @prize_user = prize_user + @approver = approver + end + + def call + raise Error, '状态有误' if prize_user.pending? + + ActiveRecord::Base.transaction do + prize_user.unapprove + prize_user.approver = approver + prize_user.approved_at = nil + prize_user.save! + + # 删除团队证书 + team_certificate_path = Util::FileManage.source_disk_filename(prize_user.competition_team, CompetitionTeam.certificate_suffix) + File.delete(team_certificate_path) if File.exist?(team_certificate_path) + + # 删除个人证书 + user_certificate_path = Util::FileManage.source_disk_filename(prize_user) + File.delete(user_certificate_path) if File.exist?(user_certificate_path) + end + end +end \ No newline at end of file diff --git a/app/services/competitions/save_prize_team_account_service.rb b/app/services/competitions/save_prize_team_account_service.rb new file mode 100644 index 000000000..60d10cf54 --- /dev/null +++ b/app/services/competitions/save_prize_team_account_service.rb @@ -0,0 +1,19 @@ +class Competitions::SavePrizeTeamAccountService < ApplicationService + attr_reader :competition, :user, :params + + def initialize(competition, user, params) + @competition = competition + @user = user + @params = params + end + + def call + Competitions::SavePrizeTeamAccountForm.new(params).validate! + + prize_leaders = competition.competition_prize_users.where(competition.competition_prize_users) + + raise Error, '审批通过后不能修改' if prize_leaders.exists?(status: :approved) + + prize_leaders.update_all(extra: params) + end +end \ No newline at end of file diff --git a/app/services/users/apply_authentication_service.rb b/app/services/users/apply_authentication_service.rb index a96e13809..a9fa12638 100644 --- a/app/services/users/apply_authentication_service.rb +++ b/app/services/users/apply_authentication_service.rb @@ -1,6 +1,4 @@ class Users::ApplyAuthenticationService < ApplicationService - Error = Class.new(StandardError) - attr_reader :user, :params def initialize(user, params) diff --git a/app/templates/shared/main.css b/app/templates/shared/main.css index 31ebfabac..09d295421 100644 --- a/app/templates/shared/main.css +++ b/app/templates/shared/main.css @@ -220,6 +220,11 @@ a.color-blue:hover,a.color-blue_4C:hover{color: #459BE6!important;} /*橙色*/ .color-orange{color: #ff6800!important;}/*辅助文字*/ .color-orange-tip{color: #FF954C!important;}/*提示文字*/ +.color-orange-tips { + color: #FF8204 !important; +} + +/*提示文字*/ a.color-orange:hover,a.color-orange-tip:hover{color: #F06200!important;} /*黄色*/ .color-yellow{color: #EFC003!important;} @@ -778,4 +783,4 @@ html>body #ajax-indicator { position: fixed; } } .yslminHeigth{ min-height: 400px; -} \ No newline at end of file +} diff --git a/app/views/admins/competition_prize_users/approve.js.erb b/app/views/admins/competition_prize_users/approve.js.erb new file mode 100644 index 000000000..d8e8f3a66 --- /dev/null +++ b/app/views/admins/competition_prize_users/approve.js.erb @@ -0,0 +1 @@ +$('.competition-prize-user-list-container .competition-prize-user-item-<%= @prize_user.id %>').html("<%= j( render partial: 'admins/competition_prize_users/shared/tr', locals: { prize_user: @prize_user } ) %>"); \ No newline at end of file diff --git a/app/views/admins/competition_prize_users/index.html.erb b/app/views/admins/competition_prize_users/index.html.erb new file mode 100644 index 000000000..dbb86d066 --- /dev/null +++ b/app/views/admins/competition_prize_users/index.html.erb @@ -0,0 +1,58 @@ +<% + define_admin_breadcrumbs do + add_admin_breadcrumb('竞赛列表', admins_competitions_path) + add_admin_breadcrumb(@competition.name) + end +%> + +
+ + +
+ <%= form_tag(admins_competition_competition_prize_users_path(unsafe_params), method: :get, class: 'search-form mt-3 flex-1 d-flex align-items-end', remote: true) do %> +
+ + <% prize_options = [['不限', '']] + @competition.competition_prizes.map{ |p| [p.name, p.id] } %> + <%= select_tag(:prize_id, options_for_select(prize_options), class: 'form-control') %> +
+ + <% auth_options = [['不限', ''], %w(未认证 not_authed), %w(待认证 authing), %w(已认证 authed)] %> +
+ + <%= select_tag(:real_name_auth, options_for_select(auth_options), class: 'form-control') %> +
+
+ + <%= select_tag(:professional_auth, options_for_select(auth_options), class: 'form-control') %> +
+ +
+ + <%- identity_options = [['不限', ''], %w(教师 0), %w(学生 1)] %> + <%= select_tag(:identity, options_for_select(identity_options), class: 'form-control') %> +
+ +
+ + <%- status_options = [['不限', ''], %w(未审批 pending), %w(已审批 approved)] %> + <%= select_tag(:status, options_for_select(status_options), class: 'form-control') %> +
+ + <%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: '战队/学校名称检索') %> + + <%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %> + <%= link_to '清除', admins_competition_competition_prize_users_path(@competition), class: "btn btn-default",'data-disable-with': '清除中...' %> + <% end %> +
+
+ +
+ <%= render(partial: 'admins/competition_prize_users/shared/list', locals: { prize_users: @prize_users }) %> +
\ No newline at end of file diff --git a/app/views/admins/competition_prize_users/index.js.erb b/app/views/admins/competition_prize_users/index.js.erb new file mode 100644 index 000000000..53091f7d5 --- /dev/null +++ b/app/views/admins/competition_prize_users/index.js.erb @@ -0,0 +1 @@ +$('.competition-prize-user-list-container').html("<%= j( render partial: 'admins/competition_prize_users/shared/list', locals: { prize_users: @prize_users } ) %>"); \ No newline at end of file diff --git a/app/views/admins/competition_prize_users/shared/_list.html.erb b/app/views/admins/competition_prize_users/shared/_list.html.erb new file mode 100644 index 000000000..27cb5b46c --- /dev/null +++ b/app/views/admins/competition_prize_users/shared/_list.html.erb @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + <% if prize_users.present? %> + <% prize_users.each do |prize_user| %> + + <%= render('admins/competition_prize_users/shared/tr', prize_user: prize_user) %> + + <% end %> + <% else %> + <%= render 'admins/shared/no_data_for_table' %> + <% end %> + +
奖项排名战队名称真实姓名职业学号单位实名职业手机队长审批时间审批人操作
+ +<%= render partial: 'admins/shared/paginate', locals: { objects: prize_users } %> \ No newline at end of file diff --git a/app/views/admins/competition_prize_users/shared/_tr.html.erb b/app/views/admins/competition_prize_users/shared/_tr.html.erb new file mode 100644 index 000000000..d3b2cd51d --- /dev/null +++ b/app/views/admins/competition_prize_users/shared/_tr.html.erb @@ -0,0 +1,26 @@ +<%- user = prize_user.user -%> +<%= prize_user.competition_prize.name %> +<%= prize_user.rank %> +<%= prize_user.competition_team.name %> +<%= user.real_name %> +<%= user.identity %> +<%= user.is_teacher? ? user.user_extension.technical_title : user.user_extension.student_id %> +<%= user.school_name %> +<%= display_auth_state(user.authentication?, user.process_real_name_apply.present?) %> +<%= display_auth_state(user.professional_certification?, user.process_professional_apply.present?) %> +<%= display_auth_state user.phone_binded? %> +<%= display_auth_state prize_user.leader?, error: '' %> +<%= display_text prize_user.approved_at&.strftime('%Y-%m-%d %H:%M') %> +<%= display_text prize_user.approver&.real_name %> + + + <% if prize_user.pending? %> + <%= link_to('审批通过', approve_admins_competition_competition_prize_user_path(prize_user.competition, prize_user), + data: { confirm: '确认审批通过吗?' }, + remote: true, method: :post, class: 'approve-action') %> + <% else %> + <%= link_to('撤销审批', unapprove_admins_competition_competition_prize_user_path(prize_user.competition, prize_user), + data: { confirm: '确认撤销审批吗?' }, + remote: true, method: :post, class: 'approve-action') %> + <% end %> + \ No newline at end of file diff --git a/app/views/admins/competition_prize_users/unapprove.js.erb b/app/views/admins/competition_prize_users/unapprove.js.erb new file mode 100644 index 000000000..d8e8f3a66 --- /dev/null +++ b/app/views/admins/competition_prize_users/unapprove.js.erb @@ -0,0 +1 @@ +$('.competition-prize-user-list-container .competition-prize-user-item-<%= @prize_user.id %>').html("<%= j( render partial: 'admins/competition_prize_users/shared/tr', locals: { prize_user: @prize_user } ) %>"); \ No newline at end of file diff --git a/app/views/admins/competition_prizes/edit.js.erb b/app/views/admins/competition_prizes/edit.js.erb new file mode 100644 index 000000000..7e3eb89c6 --- /dev/null +++ b/app/views/admins/competition_prizes/edit.js.erb @@ -0,0 +1,2 @@ +$('.admin-modal-container').html("<%= j( render partial: 'admins/competition_prizes/shared/save_competition_prize_modal', locals: { prize: @prize, title: '编辑奖项', form_method: 'PATCH' } ) %>"); +$('.modal.admin-save-competition-prize-modal').modal('show'); \ No newline at end of file diff --git a/app/views/admins/competition_prizes/index.js.erb b/app/views/admins/competition_prizes/index.js.erb new file mode 100644 index 000000000..6b9a49cfe --- /dev/null +++ b/app/views/admins/competition_prizes/index.js.erb @@ -0,0 +1 @@ +$('#competition-prize-card .competition-prize-table tbody').html("<%= j( render partial: 'admins/competition_settings/shared/competition_prizes', locals: { competition: @competition } ) %>"); \ No newline at end of file diff --git a/app/views/admins/competition_prizes/new.js.erb b/app/views/admins/competition_prizes/new.js.erb new file mode 100644 index 000000000..8e19df25d --- /dev/null +++ b/app/views/admins/competition_prizes/new.js.erb @@ -0,0 +1,2 @@ +$('.admin-modal-container').html("<%= j( render partial: 'admins/competition_prizes/shared/save_competition_prize_modal', locals: { prize: @prize, title: '新建奖项', form_method: 'POST' } ) %>"); +$('.modal.admin-save-competition-prize-modal').modal('show'); \ No newline at end of file diff --git a/app/views/admins/competition_prizes/shared/_save_competition_prize_modal.html.erb b/app/views/admins/competition_prizes/shared/_save_competition_prize_modal.html.erb new file mode 100644 index 000000000..5bdc8fa0e --- /dev/null +++ b/app/views/admins/competition_prizes/shared/_save_competition_prize_modal.html.erb @@ -0,0 +1,29 @@ + \ No newline at end of file diff --git a/app/views/admins/competition_settings/index.html.erb b/app/views/admins/competition_settings/index.html.erb index 225f05573..9d929f024 100644 --- a/app/views/admins/competition_settings/index.html.erb +++ b/app/views/admins/competition_settings/index.html.erb @@ -266,7 +266,7 @@ <% end %>
- <% when 'inform', 'chart', 'resource' %> + <% when 'inform', 'chart', 'resource', 'certificate' %>