diff --git a/app/assets/javascripts/admins/carousels/index.js b/app/assets/javascripts/admins/carousels/index.js index fe665a35f..31ce3000d 100644 --- a/app/assets/javascripts/admins/carousels/index.js +++ b/app/assets/javascripts/admins/carousels/index.js @@ -1,6 +1,13 @@ $(document).on('turbolinks:load', function() { if ($('body.admins-carousels-index-page').length > 0) { var laboratoryId = $('#carousels-container').data('laboratoryId'); + var resetNo = function(){ + $('#carousels-container .custom-carousel-item-no').each(function(index, ele){ + $(ele).html(index + 1); + }) + } + // 删除后 + $(document).on('delete_success', resetNo); // ------------ 保存链接 ----------- $('.carousels-card').on('click', '.save-data-btn', function(){ @@ -67,9 +74,7 @@ $(document).on('turbolinks:load', function() { dataType: 'json', data: { move_id: moveId, after_id: insertId }, success: function(data){ - $('#carousels-container .custom-carousel-item-no').each(function(index, ele){ - $(ele).html(index + 1); - }) + resetNo(); }, error: function(res){ var data = res.responseJSON; diff --git a/app/assets/javascripts/admins/weapp_adverts/index.js b/app/assets/javascripts/admins/weapp_adverts/index.js new file mode 100644 index 000000000..74e06fbab --- /dev/null +++ b/app/assets/javascripts/admins/weapp_adverts/index.js @@ -0,0 +1,124 @@ +$(document).on('turbolinks:load', function() { + if ($('body.admins-weapp-adverts-index-page').length > 0) { + var resetNo = function(){ + $('#adverts-container .advert-item-no').each(function(index, ele){ + $(ele).html(index + 1); + }) + } + + // ------------ 保存链接 ----------- + $('.adverts-card').on('click', '.save-data-btn', function(){ + var $link = $(this); + var id = $link.data('id'); + var link = $('.advert-item-' + id).find('.link-input').val(); + $link.attr('disabled', true); + + $.ajax({ + url: '/admins/weapp_adverts/' + id, + method: 'PATCH', + dataType: 'json', + data: { link: link }, + success: function(data){ + $.notify({ message: '操作成功' }); + }, + error: ajaxErrorNotifyHandler, + complete: function(){ + $link.removeAttr('disabled'); + } + }) + }); + // -------------- 是否在首页展示 -------------- + $('.adverts-card').on('change', '.online-check-box', function(){ + var $checkbox = $(this); + var id = $checkbox.data('id'); + var checked = $checkbox.is(':checked'); + $checkbox.attr('disabled', true); + + $.ajax({ + url: '/admins/weapp_adverts/' + id, + method: 'PATCH', + dataType: 'json', + data: { online: checked }, + success: function(data){ + $.notify({ message: '保存成功' }); + var box = $('.advert-item-' + id).find('.drag'); + if(checked){ + box.removeClass('not_active'); + }else{ + box.addClass('not_active'); + } + }, + error: ajaxErrorNotifyHandler, + complete: function(){ + $checkbox.removeAttr('disabled'); + } + }) + }); + + // ------------ 拖拽 ------------- + var onDropFunc = function(el, _target, _source, sibling){ + var moveId = $(el).data('id'); + var insertId = $(sibling).data('id') || ''; + + $.ajax({ + url: '/admins/weapp_adverts/drag', + method: 'POST', + dataType: 'json', + data: { move_id: moveId, after_id: insertId }, + success: function(data){ + resetNo(); + }, + error: function(res){ + var data = res.responseJSON; + $.notify({message: '移动失败,原因:' + data.message}, {type: 'danger'}); + } + }) + }; + var ele1 = document.getElementById('adverts-container'); + dragula([ele1], { mirrorContainer: ele1 }).on('drop', onDropFunc); + + + // ----------- 新增 -------------- + var $createModal = $('.modal.admin-add-weapp-advert-modal'); + var $createForm = $createModal.find('form.admin-add-weapp-advert-form'); + + $createForm.validate({ + errorElement: 'span', + errorClass: 'danger text-danger', + rules: { + "weapp_settings_advert[image]": { + required: true + } + } + }); + + $createModal.on('show.bs.modal', function(event){ + resetFileInputFunc($createModal.find('.img-file-input')); + $createModal.find('.file-names').html('选择文件'); + }); + + $createModal.on('click', '.submit-btn', function() { + $createForm.find('.error').html(''); + + if ($createForm.valid()) { + $createForm.submit(); + } else { + $createForm.find('.error').html('请选择图片'); + } + }); + $createModal.on('change', '.img-file-input', function(){ + var file = $(this)[0].files[0]; + $createModal.find('.file-names').html(file ? file.name : '请选择文件'); + }) + + // -------------- 重新上传图片 -------------- + //replace_image_url + $('.modal.admin-upload-file-modal').on('upload:success', function(e, data){ + var $advertItem = $('.advert-item-' + data.source_id); + $advertItem.find('.advert-item-img img').attr('src', data.url); + }) + + // 删除后 + $(document).on('delete_success', resetNo) + } +}) \ No newline at end of file diff --git a/app/assets/javascripts/admins/weapp_carousels/index.js b/app/assets/javascripts/admins/weapp_carousels/index.js new file mode 100644 index 000000000..2fc63f61d --- /dev/null +++ b/app/assets/javascripts/admins/weapp_carousels/index.js @@ -0,0 +1,123 @@ +$(document).on('turbolinks:load', function() { + if ($('body.admins-weapp-carousels-index-page').length > 0) { + var resetNo = function(){ + $('#carousels-container .custom-carousel-item-no').each(function(index, ele){ + $(ele).html(index + 1); + }) + } + // ------------ 保存链接 ----------- + $('.carousels-card').on('click', '.save-data-btn', function(){ + var $link = $(this); + var id = $link.data('id'); + var link = $('.custom-carousel-item-' + id).find('.link-input').val(); + $link.attr('disabled', true); + + $.ajax({ + url: '/admins/weapp_carousels/' + id, + method: 'PATCH', + dataType: 'json', + data: { link: link }, + success: function(data){ + $.notify({ message: '操作成功' }); + }, + error: ajaxErrorNotifyHandler, + complete: function(){ + $link.removeAttr('disabled'); + } + }) + }); + // -------------- 是否在首页展示 -------------- + $('.carousels-card').on('change', '.online-check-box', function(){ + var $checkbox = $(this); + var id = $checkbox.data('id'); + var checked = $checkbox.is(':checked'); + $checkbox.attr('disabled', true); + + $.ajax({ + url: '/admins/weapp_carousels/' + id, + method: 'PATCH', + dataType: 'json', + data: { online: checked }, + success: function(data){ + $.notify({ message: '保存成功' }); + var box = $('.custom-carousel-item-' + id).find('.drag'); + if(checked){ + box.removeClass('not_active'); + }else{ + box.addClass('not_active'); + } + }, + error: ajaxErrorNotifyHandler, + complete: function(){ + $checkbox.removeAttr('disabled'); + } + }) + }); + + // ------------ 拖拽 ------------- + var onDropFunc = function(el, _target, _source, sibling){ + var moveId = $(el).data('id'); + var insertId = $(sibling).data('id') || ''; + + $.ajax({ + url: '/admins/weapp_carousels/drag', + method: 'POST', + dataType: 'json', + data: { move_id: moveId, after_id: insertId }, + success: function(data){ + resetNo(); + }, + error: function(res){ + var data = res.responseJSON; + $.notify({message: '移动失败,原因:' + data.message}, {type: 'danger'}); + } + }) + }; + var ele1 = document.getElementById('carousels-container'); + dragula([ele1], { mirrorContainer: ele1 }).on('drop', onDropFunc); + + + // ----------- 新增 -------------- + var $createModal = $('.modal.admin-add-weapp-carousel-modal'); + var $createForm = $createModal.find('form.admin-add-weapp-carousel-form'); + + $createForm.validate({ + errorElement: 'span', + errorClass: 'danger text-danger', + rules: { + "weapp_settings_carousel[image]": { + required: true + } + } + }); + + $createModal.on('show.bs.modal', function(event){ + resetFileInputFunc($createModal.find('.img-file-input')); + $createModal.find('.file-names').html('选择文件'); + }); + + $createModal.on('click', '.submit-btn', function() { + $createForm.find('.error').html(''); + + if ($createForm.valid()) { + $createForm.submit(); + } else { + $createForm.find('.error').html('请选择图片'); + } + }); + $createModal.on('change', '.img-file-input', function(){ + var file = $(this)[0].files[0]; + $createModal.find('.file-names').html(file ? file.name : '请选择文件'); + }) + + // -------------- 重新上传图片 -------------- + //replace_image_url + $('.modal.admin-upload-file-modal').on('upload:success', function(e, data){ + var $carouselItem = $('.custom-carousel-item-' + data.source_id); + $carouselItem.find('.custom-carousel-item-img img').attr('src', data.url); + }) + + // 删除后 + $(document).on('delete_success', resetNo) + } +}) \ No newline at end of file diff --git a/app/assets/javascripts/cooperative/carousels/index.js b/app/assets/javascripts/cooperative/carousels/index.js index 4d8fe1b2c..42c87f46f 100644 --- a/app/assets/javascripts/cooperative/carousels/index.js +++ b/app/assets/javascripts/cooperative/carousels/index.js @@ -1,5 +1,12 @@ $(document).on('turbolinks:load', function() { if ($('body.cooperative-carousels-index-page').length > 0) { + var resetNo = function(){ + $('#carousels-container .custom-carousel-item-no').each(function(index, ele){ + $(ele).html(index + 1); + }) + } + // 删除后 + $(document).on('delete_success', resetNo); // ------------ 保存链接 ----------- $('.carousels-card').on('click', '.save-data-btn', function(){ var $link = $(this); @@ -65,9 +72,7 @@ $(document).on('turbolinks:load', function() { dataType: 'json', data: { move_id: moveId, after_id: insertId }, success: function(data){ - $('#carousels-container .custom-carousel-item-no').each(function(index, ele){ - $(ele).html(index + 1); - }) + resetNo(); }, error: function(res){ var data = res.responseJSON; diff --git a/app/assets/stylesheets/admins/weapp_adverts.scss b/app/assets/stylesheets/admins/weapp_adverts.scss new file mode 100644 index 000000000..d6bfa48ea --- /dev/null +++ b/app/assets/stylesheets/admins/weapp_adverts.scss @@ -0,0 +1,60 @@ +.admins-weapp-adverts-index-page { + .adverts-card { + .advert-item { + & > .drag { + cursor: move; + background: #fff; + box-shadow: 1px 2px 5px 3px #f0f0f0; + } + + &-no { + font-size: 28px; + text-align: center; + } + + &-img { + cursor: pointer; + width: 100%; + height: 60px; + + & > img { + display: block; + width: 100%; + height: 60px; + background: #F5F5F5; + } + } + + .not_active { + background: #F0F0F0; + } + + .delete-btn { + font-size: 20px; + color: red; + cursor: pointer; + } + + .save-url-btn { + cursor: pointer; + } + + .operate-box { + display: flex; + justify-content: space-between; + align-items: center; + } + + .online-check-box { + font-size: 20px; + } + + .name-input { + flex: 1; + } + .link-input { + flex: 3; + } + } + } +} \ No newline at end of file diff --git a/app/assets/stylesheets/admins/weapp_carousels.scss b/app/assets/stylesheets/admins/weapp_carousels.scss new file mode 100644 index 000000000..4ecf35da0 --- /dev/null +++ b/app/assets/stylesheets/admins/weapp_carousels.scss @@ -0,0 +1,60 @@ +.admins-weapp-carousels-index-page { + .carousels-card { + .custom-carousel-item { + & > .drag { + cursor: move; + background: #fff; + box-shadow: 1px 2px 5px 3px #f0f0f0; + } + + &-no { + font-size: 28px; + text-align: center; + } + + &-img { + cursor: pointer; + width: 100%; + height: 60px; + + & > img { + display: block; + width: 100%; + height: 60px; + background: #F5F5F5; + } + } + + .not_active { + background: #F0F0F0; + } + + .delete-btn { + font-size: 20px; + color: red; + cursor: pointer; + } + + .save-url-btn { + cursor: pointer; + } + + .operate-box { + display: flex; + justify-content: space-between; + align-items: center; + } + + .online-check-box { + font-size: 20px; + } + + .name-input { + flex: 1; + } + .link-input { + flex: 3; + } + } + } +} \ No newline at end of file diff --git a/app/controllers/admins/enroll_lists_controller.rb b/app/controllers/admins/enroll_lists_controller.rb index ccac6a72d..135ef55ae 100644 --- a/app/controllers/admins/enroll_lists_controller.rb +++ b/app/controllers/admins/enroll_lists_controller.rb @@ -2,8 +2,7 @@ class Admins::EnrollListsController < Admins::BaseController def index @competition = current_competition - params[:sort_by] = params[:sort_by].presence || 'created_at' - params[:sort_direction] = params[:sort_direction].presence || 'desc' + default_sort('created_at', 'desc') enroll_lists = Admins::CompetitionEnrollListQuery.call(@competition, params) @params_page = params[:page] || 1 @@ -13,10 +12,21 @@ class Admins::EnrollListsController < Admins::BaseController respond_to do |format| format.js format.html - format.xls + format.xls{ + filename = "#{@competition.name}竞赛报名列表_#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}.xls" + send_data(shixun_list_xls(shixuns), :type => 'application/octet-stream', :filename => filename_for_content_disposition(filename)) + } end end + def export + default_sort('created_at', 'desc') + @enroll_lists = Admins::CompetitionEnrollListQuery.call(current_competition, params) + + filename = ["#{current_competition.name}竞赛报名列表", Time.zone.now.strftime('%Y-%m-%d%H:%M:%S')].join('-') << '.xlsx' + render xlsx: 'export', filename: filename + end + private def current_competition @_current_competition ||= Competition.find(params[:competition_id]) diff --git a/app/controllers/admins/weapp_adverts_controller.rb b/app/controllers/admins/weapp_adverts_controller.rb new file mode 100644 index 000000000..873036ae7 --- /dev/null +++ b/app/controllers/admins/weapp_adverts_controller.rb @@ -0,0 +1,79 @@ +class Admins::WeappAdvertsController < Admins::BaseController + before_action :convert_file!, only: [:create] + def index + @adverts = WeappSettings::Advert.all + end + + def create + position = WeappSettings::Advert.count + 1 + + ActiveRecord::Base.transaction do + advert = WeappSettings::Advert.create!(create_params.merge(position: position)) + + file_path = Util::FileManage.source_disk_filename(advert) + File.delete(file_path) if File.exist?(file_path) # 删除之前的文件 + Util.write_file(@file, file_path) + end + + flash[:success] = '保存成功' + redirect_to admins_weapp_adverts_path + end + + def update + current_advert.update!(update_params) + render_ok + end + + def destroy + ActiveRecord::Base.transaction do + current_advert.destroy! + # 前移 + WeappSettings::Advert.where('position > ?', current_advert.position) + .update_all('position = position - 1') + + file_path = Util::FileManage.source_disk_filename(current_advert) + File.delete(file_path) if File.exist?(file_path) + end + render_delete_success + end + + def drag + move = WeappSettings::Advert.find_by(id: params[:move_id]) + after = WeappSettings::Advert.find_by(id: params[:after_id]) + + Admins::DragWeappAdvertService.call(move, after) + render_ok + rescue ApplicationService::Error => e + render_error(e.message) + end + + private + + def current_advert + @_current_advert ||= WeappSettings::Advert.find(params[:id]) + end + + def create_params + params.require(:weapp_settings_advert).permit(:link) + end + + def update_params + params.permit(:link, :online) + end + + def convert_file! + max_size = 10 * 1024 * 1024 # 10M + file = params.dig('weapp_settings_advert', 'image') + if file.class == ActionDispatch::Http::UploadedFile + @file = file + render_error('请上传文件') if @file.size.zero? + render_error('文件大小超过限制') if @file.size > max_size + else + file = file.to_s.strip + return render_error('请上传正确的图片') if file.blank? + @file = Util.convert_base64_image(file, max_size: max_size) + end + rescue Base64ImageConverter::Error => ex + render_error(ex.message) + end +end \ No newline at end of file diff --git a/app/controllers/admins/weapp_carousels_controller.rb b/app/controllers/admins/weapp_carousels_controller.rb new file mode 100644 index 000000000..9f22efdbe --- /dev/null +++ b/app/controllers/admins/weapp_carousels_controller.rb @@ -0,0 +1,80 @@ +class Admins::WeappCarouselsController < Admins::BaseController + before_action :convert_file!, only: [:create] + + def index + @carousels = WeappSettings::Carousel.all + end + + def create + position = WeappSettings::Carousel.count + 1 + + ActiveRecord::Base.transaction do + carousel = WeappSettings::Carousel.create!(create_params.merge(position: position)) + + file_path = Util::FileManage.source_disk_filename(carousel) + File.delete(file_path) if File.exist?(file_path) # 删除之前的文件 + Util.write_file(@file, file_path) + end + + flash[:success] = '保存成功' + redirect_to admins_weapp_carousels_path + end + + def update + current_carousel.update!(update_params) + render_ok + end + + def destroy + ActiveRecord::Base.transaction do + current_carousel.destroy! + # 前移 + WeappSettings::Carousel.where('position > ?', current_carousel.position) + .update_all('position = position - 1') + + file_path = Util::FileManage.source_disk_filename(current_carousel) + File.delete(file_path) if File.exist?(file_path) + end + render_delete_success + end + + def drag + move = WeappSettings::Carousel.find_by(id: params[:move_id]) + after = WeappSettings::Carousel.find_by(id: params[:after_id]) + + Admins::DragWeappCarouselService.call(move, after) + render_ok + rescue ApplicationService::Error => e + render_error(e.message) + end + + private + + def current_carousel + @_current_carousel ||= WeappSettings::Carousel.find(params[:id]) + end + + def create_params + params.require(:weapp_settings_carousel).permit(:link) + end + + def update_params + params.permit(:link, :online) + end + + def convert_file! + max_size = 10 * 1024 * 1024 # 10M + file = params.dig('weapp_settings_carousel', 'image') + if file.class == ActionDispatch::Http::UploadedFile + @file = file + render_error('请上传文件') if @file.size.zero? + render_error('文件大小超过限制') if @file.size > max_size + else + file = file.to_s.strip + return render_error('请上传正确的图片') if file.blank? + @file = Util.convert_base64_image(file, max_size: max_size) + end + rescue Base64ImageConverter::Error => ex + render_error(ex.message) + end +end \ No newline at end of file diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index df3e9c96e..76ffe23d4 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -112,6 +112,8 @@ class ApplicationController < ActionController::Base "验证码发送次数超过频率" when 43 "一天内同一手机号发送次数超过限制" + when 53 + "手机号接收超过频率限制" end end diff --git a/app/controllers/poll_votes_controller.rb b/app/controllers/poll_votes_controller.rb index b1191d8ea..4a15ae301 100644 --- a/app/controllers/poll_votes_controller.rb +++ b/app/controllers/poll_votes_controller.rb @@ -16,9 +16,9 @@ class PollVotesController < ApplicationController # 当前用户的当前答案,如果已存在,当再次点击的时候,取消答案,即删除该答案 current_vote_text = nil - if user_votes.find_vote_text.present? - current_vote_text = user_votes.find_vote_text.first - end + # if user_votes.find_vote_text.present? + # current_vote_text = user_votes.find_vote_text.first + # end vote_answer_params = { :user_id => current_user.id, @@ -36,7 +36,6 @@ class PollVotesController < ApplicationController else if question_answer_text.present? - current_user_answer.update_attribute("vote_text", question_answer_text) end end @@ -48,17 +47,23 @@ class PollVotesController < ApplicationController if question_answer_ids.present? if question_answer_text.present? #有文字输入,但是不存在其他选项的 ques_vote_id = question_answer_ids.map(&:to_i).max - if current_vote_text.present? #已有其他输入文字的选项 + if user_votes.find_vote_text.present? + current_vote_text = user_votes.find_vote_text.first current_vote_text.update_attribute("vote_text", question_answer_text) else answer_option = { - :user_id => current_user.id, - :poll_question_id => @poll_question.id, - :poll_answer_id => ques_vote_id, - :vote_text => question_answer_text + :user_id => current_user.id, + :poll_question_id => @poll_question.id, + :poll_answer_id => ques_vote_id, + :vote_text => question_answer_text } PollVote.create(answer_option) end + # if current_vote_text.present? #已有其他输入文字的选项 + # current_vote_text.update_attribute("vote_text", question_answer_text) + # else + # + # end end ea_ids = user_votes.pluck(:poll_answer_id) @@ -85,12 +90,14 @@ class PollVotesController < ApplicationController user_votes.destroy_all end else #主观题的输入 - if current_vote_text.present? - if question_answer_text.present? - user_votes.first.update_attribute("vote_text", question_answer_text) - else - user_votes.destroy_all - end + # current_vote_text = user_votes.find_vote_text + if user_votes.present? + user_votes.first.update_attribute("vote_text", question_answer_text) + # if question_answer_text.present? + # user_votes.first.update_attribute("vote_text", question_answer_text) + # else + # user_votes.destroy_all + # end else PollVote.create(vote_answer_params) end diff --git a/app/controllers/polls_controller.rb b/app/controllers/polls_controller.rb index cb507fdcb..bbd2a06fa 100644 --- a/app/controllers/polls_controller.rb +++ b/app/controllers/polls_controller.rb @@ -900,12 +900,30 @@ class PollsController < ApplicationController # 判断是否已经回答还是新建的回答 @poll_questions.each do |q| ques_vote = q.poll_votes.find_current_vote("user_id",@poll_current_user_id) - if ques_vote.present? - ques_status = 1 - question_answered += 1 + ques_type = q.question_type + + if ques_type != 3 #非简答题时 + if ques_vote.exists? + ques_status = 1 + question_answered += 1 + else + ques_status = 0 + end else - ques_status = 0 + if ques_vote.find_vote_text.first.present? + ques_status = 1 + question_answered += 1 + else + ques_status = 0 + end end + + # if ques_vote.present? + # ques_status = 1 + # question_answered += 1 + # else + # ques_status = 0 + # end answer_status = { :ques_id => q.id, :ques_number => q.question_number, diff --git a/app/controllers/weapps/code_sessions_controller.rb b/app/controllers/weapps/code_sessions_controller.rb index 687605fc4..a99a048e2 100644 --- a/app/controllers/weapps/code_sessions_controller.rb +++ b/app/controllers/weapps/code_sessions_controller.rb @@ -1,8 +1,10 @@ class Weapps::CodeSessionsController < Weapps::BaseController def create - logged = false return render_error('code不能为空') if params[:code].blank? + reset_session + logged = false + result = Wechat::Weapp.jscode2session(params[:code]) # 能根据 code 拿到 unionid diff --git a/app/controllers/weapps/homes_controller.rb b/app/controllers/weapps/homes_controller.rb index efb80b898..9646f6108 100644 --- a/app/controllers/weapps/homes_controller.rb +++ b/app/controllers/weapps/homes_controller.rb @@ -1,12 +1,15 @@ class Weapps::HomesController < Weapps::BaseController def show - # banner图 - @images = PortalImage.where(status: true).order(position: :asc) + # banner + @carousels = WeappSettings::Carousel.only_online + # 广告 + @advert = WeappSettings::Advert.only_online.first # 热门实训 @shixuns = Shixun.where(homepage_show: true).includes(:tag_repertoires, :challenges).limit(4) # 热门实践课程 @subjects = Subject.where(homepage_show: true).includes(:shixuns, :repertoire).limit(4) + end end \ No newline at end of file diff --git a/app/helpers/polls_helper.rb b/app/helpers/polls_helper.rb index 52e90f559..03210fccd 100644 --- a/app/helpers/polls_helper.rb +++ b/app/helpers/polls_helper.rb @@ -13,7 +13,7 @@ module PollsHelper end def poll_votes_count(votes,user_ids) - votes.find_current_vote("user_id",user_ids.uniq).size + votes.find_current_vote("user_id",user_ids.uniq).reject(&:blank?).size end #公用tab页的相关信息 diff --git a/app/libs/util.rb b/app/libs/util.rb index 84f14a6c0..38b5c9af5 100644 --- a/app/libs/util.rb +++ b/app/libs/util.rb @@ -65,4 +65,19 @@ module Util else "#{str[0..2]}***#{str[-3..-1]}" end end + + def display_cost_time(time) + time = time.to_i + return if time.zero? || time < 60 + + day = time / (24 * 60 * 60) + hour = (time % (24 * 60 * 60)) / (60 * 60) + minute = (time % (60 * 60)) / 60 + + str = '' + str += "#{day}天" unless day.zero? + str += "#{hour}小时" unless hour.zero? + str += "#{minute}分" unless minute.zero? + str + end end \ No newline at end of file diff --git a/app/models/myshixun.rb b/app/models/myshixun.rb index 006bbf26d..54dcf9011 100644 --- a/app/models/myshixun.rb +++ b/app/models/myshixun.rb @@ -83,6 +83,11 @@ class Myshixun < ApplicationRecord self.games.select{|game| game.status == 2}.size end + # 查看答案的关卡数 + def view_answer_count + self.games.select{|game| game.status == 2 && game.answer_open != 0}.size + end + # 通关时间 def passed_time self.status == 1 ? self.games.select{|game| game.status == 2}.map(&:end_time).max : "--" diff --git a/app/models/weapp_setting.rb b/app/models/weapp_setting.rb new file mode 100644 index 000000000..a4ef86eb1 --- /dev/null +++ b/app/models/weapp_setting.rb @@ -0,0 +1,3 @@ +class WeappSetting < ApplicationRecord + scope :only_online, -> { where(online: true) } +end \ No newline at end of file diff --git a/app/models/weapp_settings/advert.rb b/app/models/weapp_settings/advert.rb new file mode 100644 index 000000000..564e85565 --- /dev/null +++ b/app/models/weapp_settings/advert.rb @@ -0,0 +1,2 @@ +class WeappSettings::Advert < WeappSetting +end \ No newline at end of file diff --git a/app/models/weapp_settings/carousel.rb b/app/models/weapp_settings/carousel.rb new file mode 100644 index 000000000..71445fd3f --- /dev/null +++ b/app/models/weapp_settings/carousel.rb @@ -0,0 +1,3 @@ +class WeappSettings::Carousel < WeappSetting + default_scope { order(position: :asc) } +end \ No newline at end of file diff --git a/app/queries/admins/user_statistic_query.rb b/app/queries/admins/user_statistic_query.rb index d1811e5ab..d05656b3e 100644 --- a/app/queries/admins/user_statistic_query.rb +++ b/app/queries/admins/user_statistic_query.rb @@ -50,6 +50,8 @@ class Admins::UserStatisticQuery < ApplicationQuery finish_myshixun_map = finish_myshixun.group(:user_id).count study_challenge_map = study_challenge.group(:user_id).count finish_challenge_map = finish_challenge.group(:user_id).count + evaluate_count_map = study_challenge.group(:user_id).sum(:evaluate_count) + cost_time_map = study_challenge.group(:user_id).sum(:cost_time) users.each do |user| user._extra_data = { @@ -57,6 +59,8 @@ class Admins::UserStatisticQuery < ApplicationQuery finish_shixun_count: finish_myshixun_map.fetch(user.id, 0), study_challenge_count: study_challenge_map.fetch(user.id, 0), finish_challenge_count: finish_challenge_map.fetch(user.id, 0), + evaluate_count: evaluate_count_map.fetch(user.id, 0), + cost_time: cost_time_map.fetch(user.id, 0), } end diff --git a/app/services/admins/drag_weapp_advert_service.rb b/app/services/admins/drag_weapp_advert_service.rb new file mode 100644 index 000000000..b041c9d18 --- /dev/null +++ b/app/services/admins/drag_weapp_advert_service.rb @@ -0,0 +1,32 @@ +class Admins::DragWeappAdvertService < ApplicationService + attr_reader :move, :after + + def initialize(move, after) + @move = move + @after = after # 移动后下一个位置的元素 + end + + def call + return if move.position + 1 == after&.position # 未移动 + + carousels = WeappSettings::Advert.all + + ActiveRecord::Base.transaction do + if after.blank? || move.id == after.id # 移动至末尾 + total = carousels.count + + carousels.where('position > ?', move.position).update_all('position = position - 1') + move.update!(position: total) + return + end + + if move.position > after.position # 前移 + carousels.where('position >= ? AND position < ?', after.position, move.position).update_all('position = position + 1') + move.update!(position: after.position) + else # 后移 + carousels.where('position > ? AND position < ?', move.position, after.position).update_all('position = position - 1') + move.update!(position: after.position - 1) + end + end + end +end \ No newline at end of file diff --git a/app/services/admins/drag_weapp_carousel_service.rb b/app/services/admins/drag_weapp_carousel_service.rb new file mode 100644 index 000000000..f0b3832b2 --- /dev/null +++ b/app/services/admins/drag_weapp_carousel_service.rb @@ -0,0 +1,32 @@ +class Admins::DragWeappCarouselService < ApplicationService + attr_reader :move, :after + + def initialize(move, after) + @move = move + @after = after # 移动后下一个位置的元素 + end + + def call + return if move.position + 1 == after&.position # 未移动 + + carousels = WeappSettings::Carousel.all + + ActiveRecord::Base.transaction do + if after.blank? || move.id == after.id # 移动至末尾 + total = carousels.count + + carousels.where('position > ?', move.position).update_all('position = position - 1') + move.update!(position: total) + return + end + + if move.position > after.position # 前移 + carousels.where('position >= ? AND position < ?', after.position, move.position).update_all('position = position + 1') + move.update!(position: after.position) + else # 后移 + carousels.where('position > ? AND position < ?', move.position, after.position).update_all('position = position - 1') + move.update!(position: after.position - 1) + end + end + end +end \ No newline at end of file diff --git a/app/views/admins/shared/_sidebar.html.erb b/app/views/admins/shared/_sidebar.html.erb index 4d6986bc6..87b1a7f67 100644 --- a/app/views/admins/shared/_sidebar.html.erb +++ b/app/views/admins/shared/_sidebar.html.erb @@ -78,6 +78,14 @@
  • <%= sidebar_item(edit_admins_help_center_path, '帮助中心', icon: 'question-circle-o', controller: 'admins-help_centers') %>
  • <% end %> + +
  • + <%= sidebar_item_group('#weapp-setting-submenu', '小程序设置', icon: 'id-badge') do %> +
  • <%= sidebar_item(admins_weapp_carousels_path, '轮播图', icon: 'image', controller: 'admins-weapp_carousels') %>
  • +
  • <%= sidebar_item(admins_weapp_adverts_path, '广告栏', icon: 'paper-plane', controller: 'admins-weapp_adverts') %>
  • + <% end %> + +
  • <%= sidebar_item('/', '返回主站', icon: 'sign-out', controller: 'root') %>
  • \ No newline at end of file diff --git a/app/views/admins/shared/delete.js.erb b/app/views/admins/shared/delete.js.erb index 0da435fd7..d4989f392 100644 --- a/app/views/admins/shared/delete.js.erb +++ b/app/views/admins/shared/delete.js.erb @@ -24,4 +24,5 @@ if (!notRefresh) { } } else { deleteRow.remove(); -} \ No newline at end of file +} +$(document).trigger('delete_success'); \ No newline at end of file diff --git a/app/views/admins/user_statistics/export.xlsx.axlsx b/app/views/admins/user_statistics/export.xlsx.axlsx index b66e62a99..1511b6ea3 100644 --- a/app/views/admins/user_statistics/export.xlsx.axlsx +++ b/app/views/admins/user_statistics/export.xlsx.axlsx @@ -1,6 +1,6 @@ wb = xlsx_package.workbook wb.add_worksheet(name: '用户实训情况') do |sheet| - sheet.add_row %w(姓名 单位部门 学习关卡数 完成关卡数 学习实训数 完成实训数) + sheet.add_row %w(姓名 单位部门 学习关卡数 完成关卡数 学习实训数 完成实训数 评测次数 实战时间) @users.each do |user| data = [ @@ -9,7 +9,9 @@ wb.add_worksheet(name: '用户实训情况') do |sheet| user.display_extra_data(:study_challenge_count), user.display_extra_data(:finish_challenge_count), user.display_extra_data(:study_shixun_count), - user.display_extra_data(:finish_shixun_count) + user.display_extra_data(:finish_shixun_count), + user.display_extra_data(:evaluate_count), + Util.display_cost_time(user.display_extra_data(:cost_time)), ] sheet.add_row(data) end diff --git a/app/views/admins/user_statistics/shared/_list.html.erb b/app/views/admins/user_statistics/shared/_list.html.erb index 1e1b14ea3..44076812d 100644 --- a/app/views/admins/user_statistics/shared/_list.html.erb +++ b/app/views/admins/user_statistics/shared/_list.html.erb @@ -2,11 +2,13 @@ 姓名 - 单位部门 - <%= sort_tag('学习关卡数', name: 'study_challenge_count', path: admins_user_statistics_path) %> - <%= sort_tag('完成关卡数', name: 'finish_challenge_count', path: admins_user_statistics_path) %> - <%= sort_tag('学习实训数', name: 'study_shixun_count', path: admins_user_statistics_path) %> - <%= sort_tag('完成实训数', name: 'finish_shixun_count', path: admins_user_statistics_path) %> + 单位部门 + <%= sort_tag('学习关卡数', name: 'study_challenge_count', path: admins_user_statistics_path) %> + <%= sort_tag('完成关卡数', name: 'finish_challenge_count', path: admins_user_statistics_path) %> + <%= sort_tag('学习实训数', name: 'study_shixun_count', path: admins_user_statistics_path) %> + <%= sort_tag('完成实训数', name: 'finish_shixun_count', path: admins_user_statistics_path) %> + 评测次数 + 实战时间 @@ -23,6 +25,8 @@ <%= user.display_extra_data(:finish_challenge_count) %> <%= user.display_extra_data(:study_shixun_count) %> <%= user.display_extra_data(:finish_shixun_count) %> + <%= user.display_extra_data(:evaluate_count) %> + <%= Util.display_cost_time(user.display_extra_data(:cost_time)) || '--' %> <% end %> <% else %> diff --git a/app/views/admins/weapp_adverts/index.html.erb b/app/views/admins/weapp_adverts/index.html.erb new file mode 100644 index 000000000..c560fdb8a --- /dev/null +++ b/app/views/admins/weapp_adverts/index.html.erb @@ -0,0 +1,42 @@ +<% + define_admin_breadcrumbs do + add_admin_breadcrumb('广告栏') + end +%> + +
    +
    + 广告栏 + <%= javascript_void_link '添加', class: 'btn btn-primary btn-sm add-btn', data: { toggle: 'modal', target: '.admin-add-weapp-advert-modal' } %> +
    +
    + <% @adverts.each_with_index do |advert, index| %> + + <% end %> +
    +
    + + +<%= render partial: 'admins/weapp_adverts/shared/add_weapp_advert_modal' %> +<%= render partial: 'admins/shared/modal/upload_file_modal' %> \ No newline at end of file diff --git a/app/views/admins/weapp_adverts/shared/_add_weapp_advert_modal.html.erb b/app/views/admins/weapp_adverts/shared/_add_weapp_advert_modal.html.erb new file mode 100644 index 000000000..9909084b8 --- /dev/null +++ b/app/views/admins/weapp_adverts/shared/_add_weapp_advert_modal.html.erb @@ -0,0 +1,35 @@ + \ No newline at end of file diff --git a/app/views/admins/weapp_carousels/index.html.erb b/app/views/admins/weapp_carousels/index.html.erb new file mode 100644 index 000000000..ec6cfa57c --- /dev/null +++ b/app/views/admins/weapp_carousels/index.html.erb @@ -0,0 +1,42 @@ +<% + define_admin_breadcrumbs do + add_admin_breadcrumb('轮播图') + end +%> + +
    +
    + 顶部轮播图(拖动排序) + <%= javascript_void_link '添加', class: 'btn btn-primary btn-sm add-btn', data: { toggle: 'modal', target: '.admin-add-weapp-carousel-modal' } %> +
    +
    + <% @carousels.each_with_index do |carousel, index| %> + + <% end %> +
    +
    + + +<%= render partial: 'admins/weapp_carousels/shared/add_weapp_carousel_modal' %> +<%= render partial: 'admins/shared/modal/upload_file_modal' %> \ No newline at end of file diff --git a/app/views/admins/weapp_carousels/shared/_add_weapp_carousel_modal.html.erb b/app/views/admins/weapp_carousels/shared/_add_weapp_carousel_modal.html.erb new file mode 100644 index 000000000..767ae61ae --- /dev/null +++ b/app/views/admins/weapp_carousels/shared/_add_weapp_carousel_modal.html.erb @@ -0,0 +1,35 @@ + \ No newline at end of file diff --git a/app/views/cooperative/shared/delete.js.erb b/app/views/cooperative/shared/delete.js.erb index 0da435fd7..d4989f392 100644 --- a/app/views/cooperative/shared/delete.js.erb +++ b/app/views/cooperative/shared/delete.js.erb @@ -24,4 +24,5 @@ if (!notRefresh) { } } else { deleteRow.remove(); -} \ No newline at end of file +} +$(document).trigger('delete_success'); \ No newline at end of file diff --git a/app/views/homework_commons/works_list.json.jbuilder b/app/views/homework_commons/works_list.json.jbuilder index 839b40bfd..24d1f354a 100644 --- a/app/views/homework_commons/works_list.json.jbuilder +++ b/app/views/homework_commons/works_list.json.jbuilder @@ -41,6 +41,7 @@ elsif @user_course_identity == Course::STUDENT json.efficiency work_score_format(@work.efficiency, true, @score_open) json.eff_score work_score_format(@work.eff_score, true, @score_open) json.complete_count @work.myshixun.try(:passed_count) + json.view_answer_count @work.myshixun.try(:view_answer_count) else json.(@work, :id, :work_status, :update_time, :ultimate_score) @@ -95,6 +96,7 @@ if @homework.homework_type == "practice" json.cost_time work.myshixun.try(:total_spend_time) json.complete_count work.myshixun.try(:passed_count) + json.view_answer_count work.myshixun.try(:view_answer_count) json.user_login work.user.try(:login) json.user_name work.user.try(:real_name) json.student_id work.user.try(:student_id) diff --git a/app/views/student_works/shixun_work_report.json.jbuilder b/app/views/student_works/shixun_work_report.json.jbuilder index 2c9558fdc..862a6be50 100644 --- a/app/views/student_works/shixun_work_report.json.jbuilder +++ b/app/views/student_works/shixun_work_report.json.jbuilder @@ -40,6 +40,7 @@ if @shixun json.challenge_comment challenge_comment&.comment json.challenge_comment_hidden @user_course_identity < Course::STUDENT ? challenge_comment&.hidden_comment : nil json.comment_id challenge_comment&.id + json.view_answer game.answer_open != 0 end end diff --git a/app/views/weapps/homes/show.json.jbuilder b/app/views/weapps/homes/show.json.jbuilder index eb5b238ac..ab366507c 100644 --- a/app/views/weapps/homes/show.json.jbuilder +++ b/app/views/weapps/homes/show.json.jbuilder @@ -1,8 +1,19 @@ -json.images do - json.array! @images do |image| - json.path image.link - json.image_url Util::FileManage.source_disk_file_url(image) +json.carousels do + json.array! @carousels do |carousel| + json.extract! carousel, :id, :link, :position + + json.path carousel.link + json.image_url Util::FileManage.source_disk_file_url(carousel) + end +end + +if @advert.present? + json.advert do + json.extract! @advert, :id, :link + json.image_url Util::FileManage.source_disk_file_url(@advert) end +else + json.advert nil end json.shixuns do diff --git a/config/routes.rb b/config/routes.rb index 6013eaf3f..b2037ff78 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1025,6 +1025,13 @@ Rails.application.routes.draw do resources :competition_settings, only: [:index, :update] resources :enroll_lists, only: [:index] end + + resources :weapp_carousels, only: [:index, :create, :update, :destroy] do + post :drag, on: :collection + end + resources :weapp_adverts, only: [:index, :create, :update, :destroy] do + post :drag, on: :collection + end end namespace :cooperative do diff --git a/db/migrate/20191022003750_create_weapp_settings.rb b/db/migrate/20191022003750_create_weapp_settings.rb new file mode 100644 index 000000000..20b3d5879 --- /dev/null +++ b/db/migrate/20191022003750_create_weapp_settings.rb @@ -0,0 +1,12 @@ +class CreateWeappSettings < ActiveRecord::Migration[5.2] + def change + create_table :weapp_settings do |t| + t.string :type + t.string :link + t.boolean :online, default: false + t.integer :position, default: 0 + + t.timestamps + end + end +end diff --git a/public/assets/.sprockets-manifest-4627fa5586ef7fed55ca286af7c028e9.json b/public/assets/.sprockets-manifest-4627fa5586ef7fed55ca286af7c028e9.json index 81a6274f1..2404fbf37 100644 --- a/public/assets/.sprockets-manifest-4627fa5586ef7fed55ca286af7c028e9.json +++ b/public/assets/.sprockets-manifest-4627fa5586ef7fed55ca286af7c028e9.json @@ -1 +1 @@ -{"files":{"admin-cd9ca8bacc973ce2dbace30c97f6c40bc08e2c2ee44972f668e738e1902c0121.js":{"logical_path":"admin.js","mtime":"2019-09-11T16:20:07+08:00","size":4350881,"digest":"cd9ca8bacc973ce2dbace30c97f6c40bc08e2c2ee44972f668e738e1902c0121","integrity":"sha256-zZyousyXPOLbrOMMl/bEC8COLC7kSXL2aOc44ZAsASE="},"admin-a1b3356efe50ff4717cf22475639b5333c5354ba03fd107c9b7a8d4ae76f47aa.css":{"logical_path":"admin.css","mtime":"2019-09-11T16:20:07+08:00","size":773445,"digest":"a1b3356efe50ff4717cf22475639b5333c5354ba03fd107c9b7a8d4ae76f47aa","integrity":"sha256-obM1bv5Q/0cXzyJHVjm1MzxTVLoD/RB8m3qNSudvR6o="},"font-awesome/fontawesome-webfont-7bfcab6db99d5cfbf1705ca0536ddc78585432cc5fa41bbd7ad0f009033b2979.eot":{"logical_path":"font-awesome/fontawesome-webfont.eot","mtime":"2019-08-14T17:22:43+08:00","size":165742,"digest":"7bfcab6db99d5cfbf1705ca0536ddc78585432cc5fa41bbd7ad0f009033b2979","integrity":"sha256-e/yrbbmdXPvxcFygU23ceFhUMsxfpBu9etDwCQM7KXk="},"font-awesome/fontawesome-webfont-2adefcbc041e7d18fcf2d417879dc5a09997aa64d675b7a3c4b6ce33da13f3fe.woff2":{"logical_path":"font-awesome/fontawesome-webfont.woff2","mtime":"2019-08-14T17:22:43+08:00","size":77160,"digest":"2adefcbc041e7d18fcf2d417879dc5a09997aa64d675b7a3c4b6ce33da13f3fe","integrity":"sha256-Kt78vAQefRj88tQXh53FoJmXqmTWdbejxLbOM9oT8/4="},"font-awesome/fontawesome-webfont-ba0c59deb5450f5cb41b3f93609ee2d0d995415877ddfa223e8a8a7533474f07.woff":{"logical_path":"font-awesome/fontawesome-webfont.woff","mtime":"2019-08-14T17:22:43+08:00","size":98024,"digest":"ba0c59deb5450f5cb41b3f93609ee2d0d995415877ddfa223e8a8a7533474f07","integrity":"sha256-ugxZ3rVFD1y0Gz+TYJ7i0NmVQVh33foiPoqKdTNHTwc="},"font-awesome/fontawesome-webfont-aa58f33f239a0fb02f5c7a6c45c043d7a9ac9a093335806694ecd6d4edc0d6a8.ttf":{"logical_path":"font-awesome/fontawesome-webfont.ttf","mtime":"2019-08-14T17:22:43+08:00","size":165548,"digest":"aa58f33f239a0fb02f5c7a6c45c043d7a9ac9a093335806694ecd6d4edc0d6a8","integrity":"sha256-qljzPyOaD7AvXHpsRcBD16msmgkzNYBmlOzW1O3A1qg="},"font-awesome/fontawesome-webfont-ad6157926c1622ba4e1d03d478f1541368524bfc46f51e42fe0d945f7ef323e4.svg":{"logical_path":"font-awesome/fontawesome-webfont.svg","mtime":"2019-08-14T17:22:43+08:00","size":444379,"digest":"ad6157926c1622ba4e1d03d478f1541368524bfc46f51e42fe0d945f7ef323e4","integrity":"sha256-rWFXkmwWIrpOHQPUePFUE2hSS/xG9R5C/g2UX37zI+Q="},"college-18f5e8400331634e898a35acc2187815c096c25e0ab74aba341ae916166cd287.js":{"logical_path":"college.js","mtime":"2019-10-17T09:44:58+08:00","size":3352744,"digest":"18f5e8400331634e898a35acc2187815c096c25e0ab74aba341ae916166cd287","integrity":"sha256-GPXoQAMxY06JijWswhh4FcCWwl4Kt0q6NBrpFhZs0oc="},"college-944d4273f62c7538368b9017fdd3387b5e3bea31a87873770eb231324546d4d9.css":{"logical_path":"college.css","mtime":"2019-09-11T16:20:07+08:00","size":546841,"digest":"944d4273f62c7538368b9017fdd3387b5e3bea31a87873770eb231324546d4d9","integrity":"sha256-lE1Cc/YsdTg2i5AX/dM4e1476jGoeHN3DrIxMkVG1Nk="},"logo-7ff112568709bf97f9898fe87249b7a8f200ff1f48d537d85af87215f1870423.png":{"logical_path":"logo.png","mtime":"2019-09-03T08:55:53+08:00","size":2816,"digest":"7ff112568709bf97f9898fe87249b7a8f200ff1f48d537d85af87215f1870423","integrity":"sha256-f/ESVocJv5f5iY/ockm3qPIA/x9I1TfYWvhyFfGHBCM="},"application-9cfbc3d792599a1d0de5c7b84209e1c2b2e60336f0f01e19f0581663918708fb.js":{"logical_path":"application.js","mtime":"2019-10-17T09:44:58+08:00","size":600706,"digest":"9cfbc3d792599a1d0de5c7b84209e1c2b2e60336f0f01e19f0581663918708fb","integrity":"sha256-nPvD15JZmh0N5ce4QgnhwrLmAzbw8B4Z8FgWY5GHCPs="},"application-5eb87c6e13676d0183317debce17fade27e68c4acee28c419438da15d53c94f2.css":{"logical_path":"application.css","mtime":"2019-09-11T16:20:07+08:00","size":1844002,"digest":"5eb87c6e13676d0183317debce17fade27e68c4acee28c419438da15d53c94f2","integrity":"sha256-Xrh8bhNnbQGDMX3rzhf63ifmjErO4oxBlDjaFdU8lPI="},"admin-c9e5ebe6191548550e27514196ea125cfbb402820ec125a0c9acf99d2d378fe4.js":{"logical_path":"admin.js","mtime":"2019-09-21T15:28:08+08:00","size":4382031,"digest":"c9e5ebe6191548550e27514196ea125cfbb402820ec125a0c9acf99d2d378fe4","integrity":"sha256-yeXr5hkVSFUOJ1FBluoSXPu0AoIOwSWgyaz5nS03j+Q="},"admin-59c59f8cae8bef4a8359286c985458110c9d03ea121516595c988943f4717c38.css":{"logical_path":"admin.css","mtime":"2019-09-21T14:49:04+08:00","size":840093,"digest":"59c59f8cae8bef4a8359286c985458110c9d03ea121516595c988943f4717c38","integrity":"sha256-WcWfjK6L70qDWShsmFRYEQydA+oSFRZZXJiJQ/RxfDg="},"college-38f953d6ba5b85d3fab63cb3c2bbf0d057ccc6454d07cfaafac3b06da37b8437.css":{"logical_path":"college.css","mtime":"2019-09-16T13:56:09+08:00","size":579109,"digest":"38f953d6ba5b85d3fab63cb3c2bbf0d057ccc6454d07cfaafac3b06da37b8437","integrity":"sha256-OPlT1rpbhdP6tjyzwrvw0FfMxkVNB8+q+sOwbaN7hDc="},"application-646b1158a4e8c1f13e684d6fe9025abc75f8d3ba5256e440802c0398223374f3.css":{"logical_path":"application.css","mtime":"2019-09-21T14:49:04+08:00","size":1988767,"digest":"646b1158a4e8c1f13e684d6fe9025abc75f8d3ba5256e440802c0398223374f3","integrity":"sha256-ZGsRWKTowfE+aE1v6QJavHX407pSVuRAgCwDmCIzdPM="},"admin-a47e37c0ec7cf5f22380249776d1e82d65b6b6aa272ed7389185aa200fa40751.js":{"logical_path":"admin.js","mtime":"2019-09-25T15:33:05+08:00","size":4383107,"digest":"a47e37c0ec7cf5f22380249776d1e82d65b6b6aa272ed7389185aa200fa40751","integrity":"sha256-pH43wOx89fIjgCSXdtHoLWW2tqonLtc4kYWqIA+kB1E="},"admin-432c4eac09b036c57ff1e88d902b8aa7df81164e4b419bac557cf1366c1d3ad9.js":{"logical_path":"admin.js","mtime":"2019-09-25T15:35:20+08:00","size":4383103,"digest":"432c4eac09b036c57ff1e88d902b8aa7df81164e4b419bac557cf1366c1d3ad9","integrity":"sha256-QyxOrAmwNsV/8eiNkCuKp9+BFk5LQZusVXzxNmwdOtk="},"admin-978e5ce607f77c26814a174f480da79ac246c2201868ef84654aa03bb6727b5a.js":{"logical_path":"admin.js","mtime":"2019-09-30T14:43:41+08:00","size":4387200,"digest":"978e5ce607f77c26814a174f480da79ac246c2201868ef84654aa03bb6727b5a","integrity":"sha256-l45c5gf3fCaBShdPSA2nmsJGwiAYaO+EZUqgO7Zye1o="},"admin-896281f4731722b0c084dbb1af21d0f34a5bc142d58aff57b391864ab71ddca7.css":{"logical_path":"admin.css","mtime":"2019-09-30T14:43:41+08:00","size":842269,"digest":"896281f4731722b0c084dbb1af21d0f34a5bc142d58aff57b391864ab71ddca7","integrity":"sha256-iWKB9HMXIrDAhNuxryHQ80pbwULViv9Xs5GGSrcd3Kc="},"application-97f313e9bb7d25476649f7d7215959cf421480fd0a3785d1956953bf94a1e8bd.css":{"logical_path":"application.css","mtime":"2019-09-30T14:43:41+08:00","size":1993118,"digest":"97f313e9bb7d25476649f7d7215959cf421480fd0a3785d1956953bf94a1e8bd","integrity":"sha256-l/MT6bt9JUdmSffXIVlZz0IUgP0KN4XRlWlTv5Sh6L0="},"admin-2cdb23442fa735025385b88f2900df04fef38b61530041a6dbe375ef0f0ae888.js":{"logical_path":"admin.js","mtime":"2019-10-11T14:38:33+08:00","size":4394616,"digest":"2cdb23442fa735025385b88f2900df04fef38b61530041a6dbe375ef0f0ae888","integrity":"sha256-LNsjRC+nNQJThbiPKQDfBP7zi2FTAEGm2+N17w8K6Ig="},"admin-2c2854b9a02158ded5a809aaf7144a8630b10354ab4e56fecc4dffcc713796cc.css":{"logical_path":"admin.css","mtime":"2019-10-10T17:12:05+08:00","size":846514,"digest":"2c2854b9a02158ded5a809aaf7144a8630b10354ab4e56fecc4dffcc713796cc","integrity":"sha256-LChUuaAhWN7VqAmq9xRKhjCxA1SrTlb+zE3/zHE3lsw="},"application-50059ae929866043b47015128702fcfba53d32a2df148e64e1d961c10651c6af.css":{"logical_path":"application.css","mtime":"2019-10-10T17:12:05+08:00","size":2001607,"digest":"50059ae929866043b47015128702fcfba53d32a2df148e64e1d961c10651c6af","integrity":"sha256-UAWa6SmGYEO0cBUShwL8+6U9MqLfFI5k4dlhwQZRxq8="},"admin-992cde09b6d17f00a49576ae2d9f1ced127244ba401ef5b7d677cab9741688d2.js":{"logical_path":"admin.js","mtime":"2019-10-16T16:11:32+08:00","size":4394790,"digest":"992cde09b6d17f00a49576ae2d9f1ced127244ba401ef5b7d677cab9741688d2","integrity":"sha256-mSzeCbbRfwCklXauLZ8c7RJyRLpAHvW31nfKuXQWiNI="},"admin-84f2a7791e275d6f820514370b3f968176b994b9dd7b8c3ba8bf48336b03f257.css":{"logical_path":"admin.css","mtime":"2019-10-16T19:25:40+08:00","size":846676,"digest":"84f2a7791e275d6f820514370b3f968176b994b9dd7b8c3ba8bf48336b03f257","integrity":"sha256-hPKneR4nXW+CBRQ3Cz+WgXa5lLnde4w7qL9IM2sD8lc="},"application-ef6bab84852baaf69a91fe6af875b6e1b118c55b4c7d165665c488fac80c4997.css":{"logical_path":"application.css","mtime":"2019-10-16T19:25:40+08:00","size":2001931,"digest":"ef6bab84852baaf69a91fe6af875b6e1b118c55b4c7d165665c488fac80c4997","integrity":"sha256-72urhIUrqvaakf5q+HW24bEYxVtMfRZWZcSI+sgMSZc="},"admin-c99030d305662f740aa84b6c925a1adbbaadaa07fd74e2655e64d44b4b97fc4a.js":{"logical_path":"admin.js","mtime":"2019-10-17T09:44:58+08:00","size":4394897,"digest":"c99030d305662f740aa84b6c925a1adbbaadaa07fd74e2655e64d44b4b97fc4a","integrity":"sha256-yZAw0wVmL3QKqEtskloa27qtqgf9dOJlXmTUS0uX/Eo="},"admin-534bde871d67f4d6fc8da611917d78be4066fc7593ba53ee92aa17068a199d6d.css":{"logical_path":"admin.css","mtime":"2019-10-17T10:22:41+08:00","size":846699,"digest":"534bde871d67f4d6fc8da611917d78be4066fc7593ba53ee92aa17068a199d6d","integrity":"sha256-U0vehx1n9Nb8jaYRkX14vkBm/HWTulPukqoXBooZnW0="},"cooperative-04cd6a60d41220d38ee45ce40b1d004e1d0bcd87c132fb1a7bab6144c1deb8d7.js":{"logical_path":"cooperative.js","mtime":"2019-10-17T10:17:56+08:00","size":4330072,"digest":"04cd6a60d41220d38ee45ce40b1d004e1d0bcd87c132fb1a7bab6144c1deb8d7","integrity":"sha256-BM1qYNQSINOO5FzkCx0ATh0LzYfBMvsae6thRMHeuNc="},"cooperative-a345bbfd8e38b70c9285ecc1747012ffcde429187983e2aea5657abb56b9b4f3.css":{"logical_path":"cooperative.css","mtime":"2019-10-17T10:21:41+08:00","size":830628,"digest":"a345bbfd8e38b70c9285ecc1747012ffcde429187983e2aea5657abb56b9b4f3","integrity":"sha256-o0W7/Y44twyShezBdHAS/83kKRh5g+KupWV6u1a5tPM="},"application-0e417478d56f42467e857cd186b29cbbc0d6c7c6e85c8a6f42f39ac618943de8.css":{"logical_path":"application.css","mtime":"2019-09-03T08:55:53+08:00","size":442932,"digest":"0e417478d56f42467e857cd186b29cbbc0d6c7c6e85c8a6f42f39ac618943de8","integrity":"sha256-DkF0eNVvQkZ+hXzRhrKcu8DWx8boXIpvQvOaxhiUPeg="},"cooperative-149f47b8675d60a8014ccff50f00f932ff69e2be286ffb74343bc4a3effb135b.js":{"logical_path":"cooperative.js","mtime":"2019-10-17T14:03:03+08:00","size":4338033,"digest":"149f47b8675d60a8014ccff50f00f932ff69e2be286ffb74343bc4a3effb135b","integrity":"sha256-FJ9HuGddYKgBTM/1DwD5Mv9p4r4ob/t0NDvEo+/7E1s="},"cooperative-6273b766d6ef11dd56174d868bab55e7f17af17546c888d2ba0dd0a6bcda76c8.css":{"logical_path":"cooperative.css","mtime":"2019-10-17T11:13:07+08:00","size":832914,"digest":"6273b766d6ef11dd56174d868bab55e7f17af17546c888d2ba0dd0a6bcda76c8","integrity":"sha256-YnO3ZtbvEd1WF02Gi6tV5/F68XVGyIjSug3Qprzadsg="},"admin-82f66cc80b5649c6530a562567f28fe8d05f7bc3b8221e0695b2216255c52ba6.js":{"logical_path":"admin.js","mtime":"2019-10-21T13:51:43+08:00","size":4397012,"digest":"82f66cc80b5649c6530a562567f28fe8d05f7bc3b8221e0695b2216255c52ba6","integrity":"sha256-gvZsyAtWScZTClYlZ/KP6NBfe8O4Ih4GlbIhYlXFK6Y="},"admin-1b5728d94f6bccfbcef452a760d94c3b6f31966bc65d7f89be077fc2ea512bec.js":{"logical_path":"admin.js","mtime":"2019-10-21T16:41:06+08:00","size":4397437,"digest":"1b5728d94f6bccfbcef452a760d94c3b6f31966bc65d7f89be077fc2ea512bec","integrity":"sha256-G1co2U9rzPvO9FKnYNlMO28xlmvGXX+Jvgd/wupRK+w="}},"assets":{"admin.js":"admin-1b5728d94f6bccfbcef452a760d94c3b6f31966bc65d7f89be077fc2ea512bec.js","admin.css":"admin-534bde871d67f4d6fc8da611917d78be4066fc7593ba53ee92aa17068a199d6d.css","font-awesome/fontawesome-webfont.eot":"font-awesome/fontawesome-webfont-7bfcab6db99d5cfbf1705ca0536ddc78585432cc5fa41bbd7ad0f009033b2979.eot","font-awesome/fontawesome-webfont.woff2":"font-awesome/fontawesome-webfont-2adefcbc041e7d18fcf2d417879dc5a09997aa64d675b7a3c4b6ce33da13f3fe.woff2","font-awesome/fontawesome-webfont.woff":"font-awesome/fontawesome-webfont-ba0c59deb5450f5cb41b3f93609ee2d0d995415877ddfa223e8a8a7533474f07.woff","font-awesome/fontawesome-webfont.ttf":"font-awesome/fontawesome-webfont-aa58f33f239a0fb02f5c7a6c45c043d7a9ac9a093335806694ecd6d4edc0d6a8.ttf","font-awesome/fontawesome-webfont.svg":"font-awesome/fontawesome-webfont-ad6157926c1622ba4e1d03d478f1541368524bfc46f51e42fe0d945f7ef323e4.svg","college.js":"college-18f5e8400331634e898a35acc2187815c096c25e0ab74aba341ae916166cd287.js","college.css":"college-38f953d6ba5b85d3fab63cb3c2bbf0d057ccc6454d07cfaafac3b06da37b8437.css","logo.png":"logo-7ff112568709bf97f9898fe87249b7a8f200ff1f48d537d85af87215f1870423.png","application.js":"application-9cfbc3d792599a1d0de5c7b84209e1c2b2e60336f0f01e19f0581663918708fb.js","application.css":"application-0e417478d56f42467e857cd186b29cbbc0d6c7c6e85c8a6f42f39ac618943de8.css","cooperative.js":"cooperative-149f47b8675d60a8014ccff50f00f932ff69e2be286ffb74343bc4a3effb135b.js","cooperative.css":"cooperative-6273b766d6ef11dd56174d868bab55e7f17af17546c888d2ba0dd0a6bcda76c8.css"}} \ No newline at end of file +{"files":{"admin-cd9ca8bacc973ce2dbace30c97f6c40bc08e2c2ee44972f668e738e1902c0121.js":{"logical_path":"admin.js","mtime":"2019-09-11T16:20:07+08:00","size":4350881,"digest":"cd9ca8bacc973ce2dbace30c97f6c40bc08e2c2ee44972f668e738e1902c0121","integrity":"sha256-zZyousyXPOLbrOMMl/bEC8COLC7kSXL2aOc44ZAsASE="},"admin-a1b3356efe50ff4717cf22475639b5333c5354ba03fd107c9b7a8d4ae76f47aa.css":{"logical_path":"admin.css","mtime":"2019-09-11T16:20:07+08:00","size":773445,"digest":"a1b3356efe50ff4717cf22475639b5333c5354ba03fd107c9b7a8d4ae76f47aa","integrity":"sha256-obM1bv5Q/0cXzyJHVjm1MzxTVLoD/RB8m3qNSudvR6o="},"font-awesome/fontawesome-webfont-7bfcab6db99d5cfbf1705ca0536ddc78585432cc5fa41bbd7ad0f009033b2979.eot":{"logical_path":"font-awesome/fontawesome-webfont.eot","mtime":"2019-08-14T17:22:43+08:00","size":165742,"digest":"7bfcab6db99d5cfbf1705ca0536ddc78585432cc5fa41bbd7ad0f009033b2979","integrity":"sha256-e/yrbbmdXPvxcFygU23ceFhUMsxfpBu9etDwCQM7KXk="},"font-awesome/fontawesome-webfont-2adefcbc041e7d18fcf2d417879dc5a09997aa64d675b7a3c4b6ce33da13f3fe.woff2":{"logical_path":"font-awesome/fontawesome-webfont.woff2","mtime":"2019-08-14T17:22:43+08:00","size":77160,"digest":"2adefcbc041e7d18fcf2d417879dc5a09997aa64d675b7a3c4b6ce33da13f3fe","integrity":"sha256-Kt78vAQefRj88tQXh53FoJmXqmTWdbejxLbOM9oT8/4="},"font-awesome/fontawesome-webfont-ba0c59deb5450f5cb41b3f93609ee2d0d995415877ddfa223e8a8a7533474f07.woff":{"logical_path":"font-awesome/fontawesome-webfont.woff","mtime":"2019-08-14T17:22:43+08:00","size":98024,"digest":"ba0c59deb5450f5cb41b3f93609ee2d0d995415877ddfa223e8a8a7533474f07","integrity":"sha256-ugxZ3rVFD1y0Gz+TYJ7i0NmVQVh33foiPoqKdTNHTwc="},"font-awesome/fontawesome-webfont-aa58f33f239a0fb02f5c7a6c45c043d7a9ac9a093335806694ecd6d4edc0d6a8.ttf":{"logical_path":"font-awesome/fontawesome-webfont.ttf","mtime":"2019-08-14T17:22:43+08:00","size":165548,"digest":"aa58f33f239a0fb02f5c7a6c45c043d7a9ac9a093335806694ecd6d4edc0d6a8","integrity":"sha256-qljzPyOaD7AvXHpsRcBD16msmgkzNYBmlOzW1O3A1qg="},"font-awesome/fontawesome-webfont-ad6157926c1622ba4e1d03d478f1541368524bfc46f51e42fe0d945f7ef323e4.svg":{"logical_path":"font-awesome/fontawesome-webfont.svg","mtime":"2019-08-14T17:22:43+08:00","size":444379,"digest":"ad6157926c1622ba4e1d03d478f1541368524bfc46f51e42fe0d945f7ef323e4","integrity":"sha256-rWFXkmwWIrpOHQPUePFUE2hSS/xG9R5C/g2UX37zI+Q="},"college-18f5e8400331634e898a35acc2187815c096c25e0ab74aba341ae916166cd287.js":{"logical_path":"college.js","mtime":"2019-10-17T09:44:58+08:00","size":3352744,"digest":"18f5e8400331634e898a35acc2187815c096c25e0ab74aba341ae916166cd287","integrity":"sha256-GPXoQAMxY06JijWswhh4FcCWwl4Kt0q6NBrpFhZs0oc="},"college-944d4273f62c7538368b9017fdd3387b5e3bea31a87873770eb231324546d4d9.css":{"logical_path":"college.css","mtime":"2019-09-11T16:20:07+08:00","size":546841,"digest":"944d4273f62c7538368b9017fdd3387b5e3bea31a87873770eb231324546d4d9","integrity":"sha256-lE1Cc/YsdTg2i5AX/dM4e1476jGoeHN3DrIxMkVG1Nk="},"logo-7ff112568709bf97f9898fe87249b7a8f200ff1f48d537d85af87215f1870423.png":{"logical_path":"logo.png","mtime":"2019-09-03T08:55:53+08:00","size":2816,"digest":"7ff112568709bf97f9898fe87249b7a8f200ff1f48d537d85af87215f1870423","integrity":"sha256-f/ESVocJv5f5iY/ockm3qPIA/x9I1TfYWvhyFfGHBCM="},"application-9cfbc3d792599a1d0de5c7b84209e1c2b2e60336f0f01e19f0581663918708fb.js":{"logical_path":"application.js","mtime":"2019-10-17T09:44:58+08:00","size":600706,"digest":"9cfbc3d792599a1d0de5c7b84209e1c2b2e60336f0f01e19f0581663918708fb","integrity":"sha256-nPvD15JZmh0N5ce4QgnhwrLmAzbw8B4Z8FgWY5GHCPs="},"application-5eb87c6e13676d0183317debce17fade27e68c4acee28c419438da15d53c94f2.css":{"logical_path":"application.css","mtime":"2019-09-11T16:20:07+08:00","size":1844002,"digest":"5eb87c6e13676d0183317debce17fade27e68c4acee28c419438da15d53c94f2","integrity":"sha256-Xrh8bhNnbQGDMX3rzhf63ifmjErO4oxBlDjaFdU8lPI="},"admin-c9e5ebe6191548550e27514196ea125cfbb402820ec125a0c9acf99d2d378fe4.js":{"logical_path":"admin.js","mtime":"2019-09-21T15:28:08+08:00","size":4382031,"digest":"c9e5ebe6191548550e27514196ea125cfbb402820ec125a0c9acf99d2d378fe4","integrity":"sha256-yeXr5hkVSFUOJ1FBluoSXPu0AoIOwSWgyaz5nS03j+Q="},"admin-59c59f8cae8bef4a8359286c985458110c9d03ea121516595c988943f4717c38.css":{"logical_path":"admin.css","mtime":"2019-09-21T14:49:04+08:00","size":840093,"digest":"59c59f8cae8bef4a8359286c985458110c9d03ea121516595c988943f4717c38","integrity":"sha256-WcWfjK6L70qDWShsmFRYEQydA+oSFRZZXJiJQ/RxfDg="},"college-38f953d6ba5b85d3fab63cb3c2bbf0d057ccc6454d07cfaafac3b06da37b8437.css":{"logical_path":"college.css","mtime":"2019-09-16T13:56:09+08:00","size":579109,"digest":"38f953d6ba5b85d3fab63cb3c2bbf0d057ccc6454d07cfaafac3b06da37b8437","integrity":"sha256-OPlT1rpbhdP6tjyzwrvw0FfMxkVNB8+q+sOwbaN7hDc="},"application-646b1158a4e8c1f13e684d6fe9025abc75f8d3ba5256e440802c0398223374f3.css":{"logical_path":"application.css","mtime":"2019-09-21T14:49:04+08:00","size":1988767,"digest":"646b1158a4e8c1f13e684d6fe9025abc75f8d3ba5256e440802c0398223374f3","integrity":"sha256-ZGsRWKTowfE+aE1v6QJavHX407pSVuRAgCwDmCIzdPM="},"admin-a47e37c0ec7cf5f22380249776d1e82d65b6b6aa272ed7389185aa200fa40751.js":{"logical_path":"admin.js","mtime":"2019-09-25T15:33:05+08:00","size":4383107,"digest":"a47e37c0ec7cf5f22380249776d1e82d65b6b6aa272ed7389185aa200fa40751","integrity":"sha256-pH43wOx89fIjgCSXdtHoLWW2tqonLtc4kYWqIA+kB1E="},"admin-432c4eac09b036c57ff1e88d902b8aa7df81164e4b419bac557cf1366c1d3ad9.js":{"logical_path":"admin.js","mtime":"2019-09-25T15:35:20+08:00","size":4383103,"digest":"432c4eac09b036c57ff1e88d902b8aa7df81164e4b419bac557cf1366c1d3ad9","integrity":"sha256-QyxOrAmwNsV/8eiNkCuKp9+BFk5LQZusVXzxNmwdOtk="},"admin-978e5ce607f77c26814a174f480da79ac246c2201868ef84654aa03bb6727b5a.js":{"logical_path":"admin.js","mtime":"2019-09-30T14:43:41+08:00","size":4387200,"digest":"978e5ce607f77c26814a174f480da79ac246c2201868ef84654aa03bb6727b5a","integrity":"sha256-l45c5gf3fCaBShdPSA2nmsJGwiAYaO+EZUqgO7Zye1o="},"admin-896281f4731722b0c084dbb1af21d0f34a5bc142d58aff57b391864ab71ddca7.css":{"logical_path":"admin.css","mtime":"2019-09-30T14:43:41+08:00","size":842269,"digest":"896281f4731722b0c084dbb1af21d0f34a5bc142d58aff57b391864ab71ddca7","integrity":"sha256-iWKB9HMXIrDAhNuxryHQ80pbwULViv9Xs5GGSrcd3Kc="},"application-97f313e9bb7d25476649f7d7215959cf421480fd0a3785d1956953bf94a1e8bd.css":{"logical_path":"application.css","mtime":"2019-09-30T14:43:41+08:00","size":1993118,"digest":"97f313e9bb7d25476649f7d7215959cf421480fd0a3785d1956953bf94a1e8bd","integrity":"sha256-l/MT6bt9JUdmSffXIVlZz0IUgP0KN4XRlWlTv5Sh6L0="},"admin-2cdb23442fa735025385b88f2900df04fef38b61530041a6dbe375ef0f0ae888.js":{"logical_path":"admin.js","mtime":"2019-10-11T14:38:33+08:00","size":4394616,"digest":"2cdb23442fa735025385b88f2900df04fef38b61530041a6dbe375ef0f0ae888","integrity":"sha256-LNsjRC+nNQJThbiPKQDfBP7zi2FTAEGm2+N17w8K6Ig="},"admin-2c2854b9a02158ded5a809aaf7144a8630b10354ab4e56fecc4dffcc713796cc.css":{"logical_path":"admin.css","mtime":"2019-10-10T17:12:05+08:00","size":846514,"digest":"2c2854b9a02158ded5a809aaf7144a8630b10354ab4e56fecc4dffcc713796cc","integrity":"sha256-LChUuaAhWN7VqAmq9xRKhjCxA1SrTlb+zE3/zHE3lsw="},"application-50059ae929866043b47015128702fcfba53d32a2df148e64e1d961c10651c6af.css":{"logical_path":"application.css","mtime":"2019-10-10T17:12:05+08:00","size":2001607,"digest":"50059ae929866043b47015128702fcfba53d32a2df148e64e1d961c10651c6af","integrity":"sha256-UAWa6SmGYEO0cBUShwL8+6U9MqLfFI5k4dlhwQZRxq8="},"admin-992cde09b6d17f00a49576ae2d9f1ced127244ba401ef5b7d677cab9741688d2.js":{"logical_path":"admin.js","mtime":"2019-10-16T16:11:32+08:00","size":4394790,"digest":"992cde09b6d17f00a49576ae2d9f1ced127244ba401ef5b7d677cab9741688d2","integrity":"sha256-mSzeCbbRfwCklXauLZ8c7RJyRLpAHvW31nfKuXQWiNI="},"admin-84f2a7791e275d6f820514370b3f968176b994b9dd7b8c3ba8bf48336b03f257.css":{"logical_path":"admin.css","mtime":"2019-10-16T19:25:40+08:00","size":846676,"digest":"84f2a7791e275d6f820514370b3f968176b994b9dd7b8c3ba8bf48336b03f257","integrity":"sha256-hPKneR4nXW+CBRQ3Cz+WgXa5lLnde4w7qL9IM2sD8lc="},"application-ef6bab84852baaf69a91fe6af875b6e1b118c55b4c7d165665c488fac80c4997.css":{"logical_path":"application.css","mtime":"2019-10-16T19:25:40+08:00","size":2001931,"digest":"ef6bab84852baaf69a91fe6af875b6e1b118c55b4c7d165665c488fac80c4997","integrity":"sha256-72urhIUrqvaakf5q+HW24bEYxVtMfRZWZcSI+sgMSZc="},"admin-c99030d305662f740aa84b6c925a1adbbaadaa07fd74e2655e64d44b4b97fc4a.js":{"logical_path":"admin.js","mtime":"2019-10-17T09:44:58+08:00","size":4394897,"digest":"c99030d305662f740aa84b6c925a1adbbaadaa07fd74e2655e64d44b4b97fc4a","integrity":"sha256-yZAw0wVmL3QKqEtskloa27qtqgf9dOJlXmTUS0uX/Eo="},"admin-534bde871d67f4d6fc8da611917d78be4066fc7593ba53ee92aa17068a199d6d.css":{"logical_path":"admin.css","mtime":"2019-10-17T10:22:41+08:00","size":846699,"digest":"534bde871d67f4d6fc8da611917d78be4066fc7593ba53ee92aa17068a199d6d","integrity":"sha256-U0vehx1n9Nb8jaYRkX14vkBm/HWTulPukqoXBooZnW0="},"cooperative-04cd6a60d41220d38ee45ce40b1d004e1d0bcd87c132fb1a7bab6144c1deb8d7.js":{"logical_path":"cooperative.js","mtime":"2019-10-17T10:17:56+08:00","size":4330072,"digest":"04cd6a60d41220d38ee45ce40b1d004e1d0bcd87c132fb1a7bab6144c1deb8d7","integrity":"sha256-BM1qYNQSINOO5FzkCx0ATh0LzYfBMvsae6thRMHeuNc="},"cooperative-a345bbfd8e38b70c9285ecc1747012ffcde429187983e2aea5657abb56b9b4f3.css":{"logical_path":"cooperative.css","mtime":"2019-10-17T10:21:41+08:00","size":830628,"digest":"a345bbfd8e38b70c9285ecc1747012ffcde429187983e2aea5657abb56b9b4f3","integrity":"sha256-o0W7/Y44twyShezBdHAS/83kKRh5g+KupWV6u1a5tPM="},"application-0e417478d56f42467e857cd186b29cbbc0d6c7c6e85c8a6f42f39ac618943de8.css":{"logical_path":"application.css","mtime":"2019-09-03T08:55:53+08:00","size":442932,"digest":"0e417478d56f42467e857cd186b29cbbc0d6c7c6e85c8a6f42f39ac618943de8","integrity":"sha256-DkF0eNVvQkZ+hXzRhrKcu8DWx8boXIpvQvOaxhiUPeg="},"cooperative-149f47b8675d60a8014ccff50f00f932ff69e2be286ffb74343bc4a3effb135b.js":{"logical_path":"cooperative.js","mtime":"2019-10-17T14:03:03+08:00","size":4338033,"digest":"149f47b8675d60a8014ccff50f00f932ff69e2be286ffb74343bc4a3effb135b","integrity":"sha256-FJ9HuGddYKgBTM/1DwD5Mv9p4r4ob/t0NDvEo+/7E1s="},"cooperative-6273b766d6ef11dd56174d868bab55e7f17af17546c888d2ba0dd0a6bcda76c8.css":{"logical_path":"cooperative.css","mtime":"2019-10-17T11:13:07+08:00","size":832914,"digest":"6273b766d6ef11dd56174d868bab55e7f17af17546c888d2ba0dd0a6bcda76c8","integrity":"sha256-YnO3ZtbvEd1WF02Gi6tV5/F68XVGyIjSug3Qprzadsg="},"admin-82f66cc80b5649c6530a562567f28fe8d05f7bc3b8221e0695b2216255c52ba6.js":{"logical_path":"admin.js","mtime":"2019-10-21T13:51:43+08:00","size":4397012,"digest":"82f66cc80b5649c6530a562567f28fe8d05f7bc3b8221e0695b2216255c52ba6","integrity":"sha256-gvZsyAtWScZTClYlZ/KP6NBfe8O4Ih4GlbIhYlXFK6Y="},"admin-1b5728d94f6bccfbcef452a760d94c3b6f31966bc65d7f89be077fc2ea512bec.js":{"logical_path":"admin.js","mtime":"2019-10-21T16:41:06+08:00","size":4397437,"digest":"1b5728d94f6bccfbcef452a760d94c3b6f31966bc65d7f89be077fc2ea512bec","integrity":"sha256-G1co2U9rzPvO9FKnYNlMO28xlmvGXX+Jvgd/wupRK+w="},"admin-c8c127fefa5eca98bca19832c246619318164e8f242635c07033e2423cc18a6f.js":{"logical_path":"admin.js","mtime":"2019-10-22T09:53:29+08:00","size":4408150,"digest":"c8c127fefa5eca98bca19832c246619318164e8f242635c07033e2423cc18a6f","integrity":"sha256-yMEn/vpeypi8oZgywkZhkxgWTo8kJjXAcDPiQjzBim8="},"admin-60d200c1fcdf61a60537d29ccf4479c6b1e5e904208870a63b8ee677c96b347e.css":{"logical_path":"admin.css","mtime":"2019-10-22T09:43:20+08:00","size":851150,"digest":"60d200c1fcdf61a60537d29ccf4479c6b1e5e904208870a63b8ee677c96b347e","integrity":"sha256-YNIAwfzfYaYFN9Kcz0R5xrHl6QQgiHCmO47md8lrNH4="},"cooperative-9fb7ac4ad44081fafd5ad2a3a1bfb7f4329ac96f28bc6446d1ff52b1e2e71286.js":{"logical_path":"cooperative.js","mtime":"2019-10-22T09:55:26+08:00","size":4338142,"digest":"9fb7ac4ad44081fafd5ad2a3a1bfb7f4329ac96f28bc6446d1ff52b1e2e71286","integrity":"sha256-n7esStRAgfr9WtKjob+39DKayW8ovGRG0f9SseLnEoY="}},"assets":{"admin.js":"admin-c8c127fefa5eca98bca19832c246619318164e8f242635c07033e2423cc18a6f.js","admin.css":"admin-60d200c1fcdf61a60537d29ccf4479c6b1e5e904208870a63b8ee677c96b347e.css","font-awesome/fontawesome-webfont.eot":"font-awesome/fontawesome-webfont-7bfcab6db99d5cfbf1705ca0536ddc78585432cc5fa41bbd7ad0f009033b2979.eot","font-awesome/fontawesome-webfont.woff2":"font-awesome/fontawesome-webfont-2adefcbc041e7d18fcf2d417879dc5a09997aa64d675b7a3c4b6ce33da13f3fe.woff2","font-awesome/fontawesome-webfont.woff":"font-awesome/fontawesome-webfont-ba0c59deb5450f5cb41b3f93609ee2d0d995415877ddfa223e8a8a7533474f07.woff","font-awesome/fontawesome-webfont.ttf":"font-awesome/fontawesome-webfont-aa58f33f239a0fb02f5c7a6c45c043d7a9ac9a093335806694ecd6d4edc0d6a8.ttf","font-awesome/fontawesome-webfont.svg":"font-awesome/fontawesome-webfont-ad6157926c1622ba4e1d03d478f1541368524bfc46f51e42fe0d945f7ef323e4.svg","college.js":"college-18f5e8400331634e898a35acc2187815c096c25e0ab74aba341ae916166cd287.js","college.css":"college-38f953d6ba5b85d3fab63cb3c2bbf0d057ccc6454d07cfaafac3b06da37b8437.css","logo.png":"logo-7ff112568709bf97f9898fe87249b7a8f200ff1f48d537d85af87215f1870423.png","application.js":"application-9cfbc3d792599a1d0de5c7b84209e1c2b2e60336f0f01e19f0581663918708fb.js","application.css":"application-0e417478d56f42467e857cd186b29cbbc0d6c7c6e85c8a6f42f39ac618943de8.css","cooperative.js":"cooperative-9fb7ac4ad44081fafd5ad2a3a1bfb7f4329ac96f28bc6446d1ff52b1e2e71286.js","cooperative.css":"cooperative-6273b766d6ef11dd56174d868bab55e7f17af17546c888d2ba0dd0a6bcda76c8.css"}} \ No newline at end of file diff --git a/public/assets/admin-534bde871d67f4d6fc8da611917d78be4066fc7593ba53ee92aa17068a199d6d.css b/public/assets/admin-60d200c1fcdf61a60537d29ccf4479c6b1e5e904208870a63b8ee677c96b347e.css similarity index 99% rename from public/assets/admin-534bde871d67f4d6fc8da611917d78be4066fc7593ba53ee92aa17068a199d6d.css rename to public/assets/admin-60d200c1fcdf61a60537d29ccf4479c6b1e5e904208870a63b8ee677c96b347e.css index 1779feb9c..edf0f7f74 100644 --- a/public/assets/admin-534bde871d67f4d6fc8da611917d78be4066fc7593ba53ee92aa17068a199d6d.css +++ b/public/assets/admin-60d200c1fcdf61a60537d29ccf4479c6b1e5e904208870a63b8ee677c96b347e.css @@ -25915,6 +25915,150 @@ input.form-control { color: #6c757d; } +/* line 4, app/assets/stylesheets/admins/weapp_adverts.scss */ +.admins-weapp-adverts-index-page .adverts-card .advert-item > .drag { + cursor: move; + background: #fff; + box-shadow: 1px 2px 5px 3px #f0f0f0; +} + +/* line 10, app/assets/stylesheets/admins/weapp_adverts.scss */ +.admins-weapp-adverts-index-page .adverts-card .advert-item-no { + font-size: 28px; + text-align: center; +} + +/* line 15, app/assets/stylesheets/admins/weapp_adverts.scss */ +.admins-weapp-adverts-index-page .adverts-card .advert-item-img { + cursor: pointer; + width: 100%; + height: 60px; +} + +/* line 20, app/assets/stylesheets/admins/weapp_adverts.scss */ +.admins-weapp-adverts-index-page .adverts-card .advert-item-img > img { + display: block; + width: 100%; + height: 60px; + background: #F5F5F5; +} + +/* line 28, app/assets/stylesheets/admins/weapp_adverts.scss */ +.admins-weapp-adverts-index-page .adverts-card .advert-item .not_active { + background: #F0F0F0; +} + +/* line 32, app/assets/stylesheets/admins/weapp_adverts.scss */ +.admins-weapp-adverts-index-page .adverts-card .advert-item .delete-btn { + font-size: 20px; + color: red; + cursor: pointer; +} + +/* line 38, app/assets/stylesheets/admins/weapp_adverts.scss */ +.admins-weapp-adverts-index-page .adverts-card .advert-item .save-url-btn { + cursor: pointer; +} + +/* line 42, app/assets/stylesheets/admins/weapp_adverts.scss */ +.admins-weapp-adverts-index-page .adverts-card .advert-item .operate-box { + display: -webkit-box; + display: flex; + -webkit-box-pack: justify; + justify-content: space-between; + -webkit-box-align: center; + align-items: center; +} + +/* line 48, app/assets/stylesheets/admins/weapp_adverts.scss */ +.admins-weapp-adverts-index-page .adverts-card .advert-item .online-check-box { + font-size: 20px; +} + +/* line 52, app/assets/stylesheets/admins/weapp_adverts.scss */ +.admins-weapp-adverts-index-page .adverts-card .advert-item .name-input { + -webkit-box-flex: 1; + flex: 1; +} + +/* line 55, app/assets/stylesheets/admins/weapp_adverts.scss */ +.admins-weapp-adverts-index-page .adverts-card .advert-item .link-input { + -webkit-box-flex: 3; + flex: 3; +} + +/* line 4, app/assets/stylesheets/admins/weapp_carousels.scss */ +.admins-weapp-carousels-index-page .carousels-card .custom-carousel-item > .drag { + cursor: move; + background: #fff; + box-shadow: 1px 2px 5px 3px #f0f0f0; +} + +/* line 10, app/assets/stylesheets/admins/weapp_carousels.scss */ +.admins-weapp-carousels-index-page .carousels-card .custom-carousel-item-no { + font-size: 28px; + text-align: center; +} + +/* line 15, app/assets/stylesheets/admins/weapp_carousels.scss */ +.admins-weapp-carousels-index-page .carousels-card .custom-carousel-item-img { + cursor: pointer; + width: 100%; + height: 60px; +} + +/* line 20, app/assets/stylesheets/admins/weapp_carousels.scss */ +.admins-weapp-carousels-index-page .carousels-card .custom-carousel-item-img > img { + display: block; + width: 100%; + height: 60px; + background: #F5F5F5; +} + +/* line 28, app/assets/stylesheets/admins/weapp_carousels.scss */ +.admins-weapp-carousels-index-page .carousels-card .custom-carousel-item .not_active { + background: #F0F0F0; +} + +/* line 32, app/assets/stylesheets/admins/weapp_carousels.scss */ +.admins-weapp-carousels-index-page .carousels-card .custom-carousel-item .delete-btn { + font-size: 20px; + color: red; + cursor: pointer; +} + +/* line 38, app/assets/stylesheets/admins/weapp_carousels.scss */ +.admins-weapp-carousels-index-page .carousels-card .custom-carousel-item .save-url-btn { + cursor: pointer; +} + +/* line 42, app/assets/stylesheets/admins/weapp_carousels.scss */ +.admins-weapp-carousels-index-page .carousels-card .custom-carousel-item .operate-box { + display: -webkit-box; + display: flex; + -webkit-box-pack: justify; + justify-content: space-between; + -webkit-box-align: center; + align-items: center; +} + +/* line 48, app/assets/stylesheets/admins/weapp_carousels.scss */ +.admins-weapp-carousels-index-page .carousels-card .custom-carousel-item .online-check-box { + font-size: 20px; +} + +/* line 52, app/assets/stylesheets/admins/weapp_carousels.scss */ +.admins-weapp-carousels-index-page .carousels-card .custom-carousel-item .name-input { + -webkit-box-flex: 1; + flex: 1; +} + +/* line 55, app/assets/stylesheets/admins/weapp_carousels.scss */ +.admins-weapp-carousels-index-page .carousels-card .custom-carousel-item .link-input { + -webkit-box-flex: 3; + flex: 3; +} + /* line 18, app/assets/stylesheets/admin.scss */ body { width: 100vw; diff --git a/public/assets/admin-534bde871d67f4d6fc8da611917d78be4066fc7593ba53ee92aa17068a199d6d.css.gz b/public/assets/admin-60d200c1fcdf61a60537d29ccf4479c6b1e5e904208870a63b8ee677c96b347e.css.gz similarity index 77% rename from public/assets/admin-534bde871d67f4d6fc8da611917d78be4066fc7593ba53ee92aa17068a199d6d.css.gz rename to public/assets/admin-60d200c1fcdf61a60537d29ccf4479c6b1e5e904208870a63b8ee677c96b347e.css.gz index 26a606a1c..44bb80d0d 100644 Binary files a/public/assets/admin-534bde871d67f4d6fc8da611917d78be4066fc7593ba53ee92aa17068a199d6d.css.gz and b/public/assets/admin-60d200c1fcdf61a60537d29ccf4479c6b1e5e904208870a63b8ee677c96b347e.css.gz differ diff --git a/public/assets/admin-1b5728d94f6bccfbcef452a760d94c3b6f31966bc65d7f89be077fc2ea512bec.js b/public/assets/admin-c8c127fefa5eca98bca19832c246619318164e8f242635c07033e2423cc18a6f.js similarity index 99% rename from public/assets/admin-1b5728d94f6bccfbcef452a760d94c3b6f31966bc65d7f89be077fc2ea512bec.js rename to public/assets/admin-c8c127fefa5eca98bca19832c246619318164e8f242635c07033e2423cc18a6f.js index 1c9d07222..bbc2ec400 100644 --- a/public/assets/admin-1b5728d94f6bccfbcef452a760d94c3b6f31966bc65d7f89be077fc2ea512bec.js +++ b/public/assets/admin-c8c127fefa5eca98bca19832c246619318164e8f242635c07033e2423cc18a6f.js @@ -133857,6 +133857,13 @@ $(document).on('turbolinks:load', function(){ $(document).on('turbolinks:load', function() { if ($('body.admins-carousels-index-page').length > 0) { var laboratoryId = $('#carousels-container').data('laboratoryId'); + var resetNo = function(){ + $('#carousels-container .custom-carousel-item-no').each(function(index, ele){ + $(ele).html(index + 1); + }) + } + // 删除后 + $(document).on('delete_success', resetNo); // ------------ 保存链接 ----------- $('.carousels-card').on('click', '.save-data-btn', function(){ @@ -133923,9 +133930,7 @@ $(document).on('turbolinks:load', function() { dataType: 'json', data: { move_id: moveId, after_id: insertId }, success: function(data){ - $('#carousels-container .custom-carousel-item-no').each(function(index, ele){ - $(ele).html(index + 1); - }) + resetNo(); }, error: function(res){ var data = res.responseJSON; @@ -134056,8 +134061,70 @@ $(document).on('turbolinks:load', function() { $imageElement.attr('src', data.url); $imageElement.show(); $imageElement.next().html('重新上传'); - }) + }); } + + $(".admin-competition-list-form").on("change", '.competitions-hot-select', function () { + var s_value = $(this).get(0).checked ? 1 : 0; + var json = {}; + json["hot"] = s_value; + $.ajax({ + url: "/admins/competitions/hot_setting", + type: "POST", + dataType:'json', + data: json, + success: function(){ + $.notify({ message: '操作成功' }); + } + }); + }); + + // ============== 新增竞赛 =============== + var $modal = $('.modal.admin-create-competition-modal'); + var $form = $modal.find('form.admin-create-competition-form'); + var $competitionNameInput = $form.find('input[name="competition_name"]'); + + $form.validate({ + errorElement: 'span', + errorClass: 'danger text-danger', + rules: { + competition_name: { + required: true + } + } + }); + + // modal ready fire + $modal.on('show.bs.modal', function () { + $competitionNameInput.val(''); + }); + + $modal.on('click', '.submit-btn', function(){ + $form.find('.error').html(''); + + if ($form.valid()) { + var url = $form.data('url'); + + $.ajax({ + method: 'POST', + dataType: 'json', + url: url, + data: $form.serialize(), + success: function(){ + $.notify({ message: '创建成功' }); + $modal.modal('hide'); + + setTimeout(function(){ + window.location.reload(); + }, 500); + }, + error: function(res){ + var data = res.responseJSON; + $form.find('.error').html(data.message); + } + }); + } + }); }); $(document).on('turbolinks:load', function() { @@ -134479,6 +134546,15 @@ $(document).on('turbolinks:load', function() { }) } }); +$(document).on('turbolinks:load', function() { + if($('body.admins-enroll-lists-index-page').length > 0){ + let search_form = $(".search-form"); + //导出 + $(".competition-enroll-list-form").on("click","#enroll-lists-export",function () { + window.location.href = "/admins/competitions/"+$(this).attr("data-competition-id")+"/enroll_lists.xls?" + search_form.serialize(); + }); + } +}); $(document).on('turbolinks:load', function() { if($(".admins-graduation-standards-index-page").length > 0){ $(".admin-body-container").on("click", ".standard-create-modal", function () { @@ -135262,14 +135338,17 @@ $(document).on('turbolinks:load', function() { var $form = $modal.find('form.admin-upload-file-form') var $sourceIdInput = $modal.find('input[name="source_id"]'); var $sourceTypeInput = $modal.find('input[name="source_type"]'); + var $suffixInput = $modal.find('input[name="suffix"]'); $modal.on('show.bs.modal', function(event){ var $link = $(event.relatedTarget); var sourceId = $link.data('sourceId'); var sourceType = $link.data('sourceType'); + var suffix = $link.data('suffix'); $sourceIdInput.val(sourceId); $sourceTypeInput.val(sourceType); + if(suffix != undefined){ $suffixInput.val(suffix); } $modal.find('.upload-file-input').trigger('click'); }); @@ -135306,6 +135385,7 @@ $(document).on('turbolinks:load', function() { contentType: false, success: function(data){ $.notify({ message: '上传成功' }); + $modal.find('.file-names').html(''); $modal.trigger('upload:success', data); $modal.modal('hide'); }, @@ -135597,10 +135677,17 @@ $(document).on('turbolinks:load', function() { }); $('.modal.admin-upload-file-modal').on('upload:success', function(e, data){ - var $imageElement = $('.shixun-image-' + data.source_id); - $imageElement.attr('src', data.url); - $imageElement.show(); - $imageElement.next().html('重新上传'); + if(data.suffix == '_weapp'){ + var $imageElement = $('.shixun-weapp-image-' + data.source_id); + $imageElement.attr('src', data.url); + $imageElement.show(); + $imageElement.next().html('重新上传'); + } else { + var $imageElement = $('.shixun-image-' + data.source_id); + $imageElement.attr('src', data.url); + $imageElement.show(); + $imageElement.next().html('重新上传'); + } }) } }); @@ -136097,6 +136184,255 @@ $(document).on('turbolinks:load', function() { } }) ; +$(document).on('turbolinks:load', function() { + if ($('body.admins-weapp-adverts-index-page').length > 0) { + var resetNo = function(){ + $('#adverts-container .advert-item-no').each(function(index, ele){ + $(ele).html(index + 1); + }) + } + + // ------------ 保存链接 ----------- + $('.adverts-card').on('click', '.save-data-btn', function(){ + var $link = $(this); + var id = $link.data('id'); + var link = $('.advert-item-' + id).find('.link-input').val(); + $link.attr('disabled', true); + + $.ajax({ + url: '/admins/weapp_adverts/' + id, + method: 'PATCH', + dataType: 'json', + data: { link: link }, + success: function(data){ + $.notify({ message: '操作成功' }); + }, + error: ajaxErrorNotifyHandler, + complete: function(){ + $link.removeAttr('disabled'); + } + }) + }); + // -------------- 是否在首页展示 -------------- + $('.adverts-card').on('change', '.online-check-box', function(){ + var $checkbox = $(this); + var id = $checkbox.data('id'); + var checked = $checkbox.is(':checked'); + $checkbox.attr('disabled', true); + + $.ajax({ + url: '/admins/weapp_adverts/' + id, + method: 'PATCH', + dataType: 'json', + data: { online: checked }, + success: function(data){ + $.notify({ message: '保存成功' }); + var box = $('.advert-item-' + id).find('.drag'); + if(checked){ + box.removeClass('not_active'); + }else{ + box.addClass('not_active'); + } + }, + error: ajaxErrorNotifyHandler, + complete: function(){ + $checkbox.removeAttr('disabled'); + } + }) + }); + + // ------------ 拖拽 ------------- + var onDropFunc = function(el, _target, _source, sibling){ + var moveId = $(el).data('id'); + var insertId = $(sibling).data('id') || ''; + + $.ajax({ + url: '/admins/weapp_adverts/drag', + method: 'POST', + dataType: 'json', + data: { move_id: moveId, after_id: insertId }, + success: function(data){ + resetNo(); + }, + error: function(res){ + var data = res.responseJSON; + $.notify({message: '移动失败,原因:' + data.message}, {type: 'danger'}); + } + }) + }; + var ele1 = document.getElementById('adverts-container'); + dragula([ele1], { mirrorContainer: ele1 }).on('drop', onDropFunc); + + + // ----------- 新增 -------------- + var $createModal = $('.modal.admin-add-weapp-advert-modal'); + var $createForm = $createModal.find('form.admin-add-weapp-advert-form'); + + $createForm.validate({ + errorElement: 'span', + errorClass: 'danger text-danger', + rules: { + "weapp_settings_advert[image]": { + required: true + } + } + }); + + $createModal.on('show.bs.modal', function(event){ + resetFileInputFunc($createModal.find('.img-file-input')); + $createModal.find('.file-names').html('选择文件'); + }); + + $createModal.on('click', '.submit-btn', function() { + $createForm.find('.error').html(''); + + if ($createForm.valid()) { + $createForm.submit(); + } else { + $createForm.find('.error').html('请选择图片'); + } + }); + $createModal.on('change', '.img-file-input', function(){ + var file = $(this)[0].files[0]; + $createModal.find('.file-names').html(file ? file.name : '请选择文件'); + }) + + // -------------- 重新上传图片 -------------- + //replace_image_url + $('.modal.admin-upload-file-modal').on('upload:success', function(e, data){ + var $advertItem = $('.advert-item-' + data.source_id); + $advertItem.find('.advert-item-img img').attr('src', data.url); + }) + + // 删除后 + $(document).on('delete_success', resetNo) + } +}) +; +$(document).on('turbolinks:load', function() { + if ($('body.admins-weapp-carousels-index-page').length > 0) { + var resetNo = function(){ + $('#carousels-container .custom-carousel-item-no').each(function(index, ele){ + $(ele).html(index + 1); + }) + } + // ------------ 保存链接 ----------- + $('.carousels-card').on('click', '.save-data-btn', function(){ + var $link = $(this); + var id = $link.data('id'); + var link = $('.custom-carousel-item-' + id).find('.link-input').val(); + $link.attr('disabled', true); + + $.ajax({ + url: '/admins/weapp_carousels/' + id, + method: 'PATCH', + dataType: 'json', + data: { link: link }, + success: function(data){ + $.notify({ message: '操作成功' }); + }, + error: ajaxErrorNotifyHandler, + complete: function(){ + $link.removeAttr('disabled'); + } + }) + }); + // -------------- 是否在首页展示 -------------- + $('.carousels-card').on('change', '.online-check-box', function(){ + var $checkbox = $(this); + var id = $checkbox.data('id'); + var checked = $checkbox.is(':checked'); + $checkbox.attr('disabled', true); + + $.ajax({ + url: '/admins/weapp_carousels/' + id, + method: 'PATCH', + dataType: 'json', + data: { online: checked }, + success: function(data){ + $.notify({ message: '保存成功' }); + var box = $('.custom-carousel-item-' + id).find('.drag'); + if(checked){ + box.removeClass('not_active'); + }else{ + box.addClass('not_active'); + } + }, + error: ajaxErrorNotifyHandler, + complete: function(){ + $checkbox.removeAttr('disabled'); + } + }) + }); + + // ------------ 拖拽 ------------- + var onDropFunc = function(el, _target, _source, sibling){ + var moveId = $(el).data('id'); + var insertId = $(sibling).data('id') || ''; + + $.ajax({ + url: '/admins/weapp_carousels/drag', + method: 'POST', + dataType: 'json', + data: { move_id: moveId, after_id: insertId }, + success: function(data){ + resetNo(); + }, + error: function(res){ + var data = res.responseJSON; + $.notify({message: '移动失败,原因:' + data.message}, {type: 'danger'}); + } + }) + }; + var ele1 = document.getElementById('carousels-container'); + dragula([ele1], { mirrorContainer: ele1 }).on('drop', onDropFunc); + + + // ----------- 新增 -------------- + var $createModal = $('.modal.admin-add-weapp-carousel-modal'); + var $createForm = $createModal.find('form.admin-add-weapp-carousel-form'); + + $createForm.validate({ + errorElement: 'span', + errorClass: 'danger text-danger', + rules: { + "weapp_settings_carousel[image]": { + required: true + } + } + }); + + $createModal.on('show.bs.modal', function(event){ + resetFileInputFunc($createModal.find('.img-file-input')); + $createModal.find('.file-names').html('选择文件'); + }); + + $createModal.on('click', '.submit-btn', function() { + $createForm.find('.error').html(''); + + if ($createForm.valid()) { + $createForm.submit(); + } else { + $createForm.find('.error').html('请选择图片'); + } + }); + $createModal.on('change', '.img-file-input', function(){ + var file = $(this)[0].files[0]; + $createModal.find('.file-names').html(file ? file.name : '请选择文件'); + }) + + // -------------- 重新上传图片 -------------- + //replace_image_url + $('.modal.admin-upload-file-modal').on('upload:success', function(e, data){ + var $carouselItem = $('.custom-carousel-item-' + data.source_id); + $carouselItem.find('.custom-carousel-item-img img').attr('src', data.url); + }) + + // 删除后 + $(document).on('delete_success', resetNo) + } +}) +; diff --git a/public/assets/admin-1b5728d94f6bccfbcef452a760d94c3b6f31966bc65d7f89be077fc2ea512bec.js.gz b/public/assets/admin-c8c127fefa5eca98bca19832c246619318164e8f242635c07033e2423cc18a6f.js.gz similarity index 98% rename from public/assets/admin-1b5728d94f6bccfbcef452a760d94c3b6f31966bc65d7f89be077fc2ea512bec.js.gz rename to public/assets/admin-c8c127fefa5eca98bca19832c246619318164e8f242635c07033e2423cc18a6f.js.gz index 519d4b32f..c89ad5256 100644 Binary files a/public/assets/admin-1b5728d94f6bccfbcef452a760d94c3b6f31966bc65d7f89be077fc2ea512bec.js.gz and b/public/assets/admin-c8c127fefa5eca98bca19832c246619318164e8f242635c07033e2423cc18a6f.js.gz differ diff --git a/public/assets/cooperative-149f47b8675d60a8014ccff50f00f932ff69e2be286ffb74343bc4a3effb135b.js b/public/assets/cooperative-9fb7ac4ad44081fafd5ad2a3a1bfb7f4329ac96f28bc6446d1ff52b1e2e71286.js similarity index 99% rename from public/assets/cooperative-149f47b8675d60a8014ccff50f00f932ff69e2be286ffb74343bc4a3effb135b.js rename to public/assets/cooperative-9fb7ac4ad44081fafd5ad2a3a1bfb7f4329ac96f28bc6446d1ff52b1e2e71286.js index 80b121449..5d30eb714 100644 --- a/public/assets/cooperative-149f47b8675d60a8014ccff50f00f932ff69e2be286ffb74343bc4a3effb135b.js +++ b/public/assets/cooperative-9fb7ac4ad44081fafd5ad2a3a1bfb7f4329ac96f28bc6446d1ff52b1e2e71286.js @@ -133825,6 +133825,13 @@ module.exports = tick; !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/zh-CN",[],function(){return{errorLoading:function(){return"无法载入结果。"},inputTooLong:function(n){return"请删除"+(n.input.length-n.maximum)+"个字符"},inputTooShort:function(n){return"请再输入至少"+(n.minimum-n.input.length)+"个字符"},loadingMore:function(){return"载入更多结果…"},maximumSelected:function(n){return"最多只能选择"+n.maximum+"个项目"},noResults:function(){return"未找到结果"},searching:function(){return"搜索中…"},removeAllItems:function(){return"删除所有项目"}}}),n.define,n.require}(); $(document).on('turbolinks:load', function() { if ($('body.cooperative-carousels-index-page').length > 0) { + var resetNo = function(){ + $('#carousels-container .custom-carousel-item-no').each(function(index, ele){ + $(ele).html(index + 1); + }) + } + // 删除后 + $(document).on('delete_success', resetNo); // ------------ 保存链接 ----------- $('.carousels-card').on('click', '.save-data-btn', function(){ var $link = $(this); @@ -133890,9 +133897,7 @@ $(document).on('turbolinks:load', function() { dataType: 'json', data: { move_id: moveId, after_id: insertId }, success: function(data){ - $('#carousels-container .custom-carousel-item-no').each(function(index, ele){ - $(ele).html(index + 1); - }) + resetNo(); }, error: function(res){ var data = res.responseJSON; diff --git a/public/assets/cooperative-149f47b8675d60a8014ccff50f00f932ff69e2be286ffb74343bc4a3effb135b.js.gz b/public/assets/cooperative-9fb7ac4ad44081fafd5ad2a3a1bfb7f4329ac96f28bc6446d1ff52b1e2e71286.js.gz similarity index 96% rename from public/assets/cooperative-149f47b8675d60a8014ccff50f00f932ff69e2be286ffb74343bc4a3effb135b.js.gz rename to public/assets/cooperative-9fb7ac4ad44081fafd5ad2a3a1bfb7f4329ac96f28bc6446d1ff52b1e2e71286.js.gz index 3f30bd269..4fb78eb9a 100644 Binary files a/public/assets/cooperative-149f47b8675d60a8014ccff50f00f932ff69e2be286ffb74343bc4a3effb135b.js.gz and b/public/assets/cooperative-9fb7ac4ad44081fafd5ad2a3a1bfb7f4329ac96f28bc6446d1ff52b1e2e71286.js.gz differ diff --git a/public/react/src/modules/courses/shixunHomework/Listofworksstudentone.js b/public/react/src/modules/courses/shixunHomework/Listofworksstudentone.js index e074da931..b6f65c45c 100644 --- a/public/react/src/modules/courses/shixunHomework/Listofworksstudentone.js +++ b/public/react/src/modules/courses/shixunHomework/Listofworksstudentone.js @@ -988,6 +988,7 @@ class Listofworksstudentone extends Component {
    已通过{record.completion}关,共{this.state.challenges_count}关
    +
    完成任务评测之前查看了参考答案:{record.view_answer_count}关
    }> {record.completion+"/"+this.state.challenges_count}
    @@ -1101,6 +1102,7 @@ class Listofworksstudentone extends Component { :
    {record.user_name}{record.user_login}
    +
    完成任务评测之前查看了参考答案:{record.view_answer_count}关
    {record.levelscore === "--"?关卡得分:0分 :关卡得分:{record.levelscore}分}
    {record.efficiencyscore === "--"?效率评分:0分 :效率评分:{record.efficiencyscore}分}
    {record.late_penalty === "--"?迟交扣分:0分 :迟交扣分:{record.late_penalty}分}
    @@ -1294,6 +1296,7 @@ class Listofworksstudentone extends Component {
    已通过{record.completion}关,共{this.state.challenges_count}关
    +
    完成任务评测之前查看了参考答案:{record.view_answer_count}关
    }> {record.completion+"/"+this.state.challenges_count}
    @@ -1407,6 +1410,7 @@ class Listofworksstudentone extends Component { :
    {record.user_name}{record.user_login}
    +
    完成任务评测之前查看了参考答案:{record.view_answer_count}关
    {record.levelscore === "--"?关卡得分:0分 :关卡得分:{record.levelscore}分}
    {record.efficiencyscore === "--"?效率评分:0分 :效率评分:{record.efficiencyscore}分}
    {record.late_penalty === "--"?迟交扣分:0分 :迟交扣分:{record.late_penalty}分}
    @@ -1796,6 +1800,7 @@ class Listofworksstudentone extends Component { updatetime: timedata === "Invalid date" ? "--" : timedata, completion: teacherdata.complete_count === null ? "0" :teacherdata.complete_count === undefined ? "0": teacherdata.complete_count, levelscore: teacherdata.final_score, + view_answer_count: teacherdata.view_answer_count, efficiencyscore: teacherdata.eff_score, finalscore: teacherdata.work_score, operating: "查看", @@ -1839,6 +1844,7 @@ class Listofworksstudentone extends Component { levelscore: student_works[i].final_score, efficiencyscore: student_works[i].eff_score==="0.0"?"--":student_works[i].eff_score==="0"?"--":student_works[i].eff_score, finalscore:student_works[i].work_score, + view_answer_count: student_works[i].view_answer_count, operating: "查看", late_penalty: student_works[i].late_penalty=== null?"0":student_works[i].late_penalty === undefined?"0":student_works[i].late_penalty, ultimate_score:student_works[i].ultimate_score, @@ -1980,6 +1986,7 @@ class Listofworksstudentone extends Component { completion: teacherdata.complete_count === null ? "0" :teacherdata.complete_count === undefined ? "0": teacherdata.complete_count, levelscore: teacherdata.final_score, efficiencyscore: teacherdata.eff_score, + view_answer_count: teacherdata.view_answer_count, finalscore: teacherdata.work_score, operating: "查看", late_penalty: teacherdata.late_penalty=== null?"0":teacherdata.late_penalty === undefined?"0":teacherdata.late_penalty, @@ -2328,6 +2335,7 @@ class Listofworksstudentone extends Component { levelscore: student_works[i].final_score, efficiencyscore: student_works[i].eff_score==="0.0"?"--":student_works[i].eff_score==="0"?"--":student_works[i].eff_score, finalscore: student_works[i].work_score, + view_answer_count: student_works[i].view_answer_count, operating: "查看", late_penalty: student_works[i].late_penalty=== null?"0":student_works[i].late_penalty === undefined?"0":student_works[i].late_penalty, ultimate_score:student_works[i].ultimate_score, diff --git a/public/react/src/modules/courses/shixunHomework/shixunreport/OfficialAcademicTranscript.js b/public/react/src/modules/courses/shixunHomework/shixunreport/OfficialAcademicTranscript.js index be99c7035..d115eef45 100644 --- a/public/react/src/modules/courses/shixunHomework/shixunreport/OfficialAcademicTranscript.js +++ b/public/react/src/modules/courses/shixunHomework/shixunreport/OfficialAcademicTranscript.js @@ -1,95 +1,97 @@ import React, {Component} from "react"; import {WordsBtn} from 'educoder'; -import {Table,InputNumber,Tooltip} from "antd"; -import {Link,Switch,Route,Redirect} from 'react-router-dom'; +import {Table, InputNumber, Tooltip} from "antd"; +import {Link, Switch, Route, Redirect} from 'react-router-dom'; import axios from 'axios'; + class OfficialAcademicTranscript extends Component { constructor(props) { super(props); this.state = { - loadingstate:true, - datas:undefined, - customsids:undefined + loadingstate: true, + datas: undefined, + customsids: undefined } } componentDidMount() { } - myjumptopic=(e)=>{ + + myjumptopic = (e) => { console.log("获取到值"); console.log(e); this.props.jumptopic(e); } - editgame_scores=(e,id,maxsum)=>{ - let{datas}=this.state; - let newdatas=datas; - let score=e.target.value; + editgame_scores = (e, id, maxsum) => { + let {datas} = this.state; + let newdatas = datas; + let score = e.target.value; - if(score!=null&&score!=undefined&&score!=""){ - if(score<0){ + if (score != null && score != undefined && score != "") { + if (score < 0) { this.props.showNotification("不能小于0"); this.setState({ - customsids:id + customsids: id }) - }else if(score>maxsum){ + } else if (score > maxsum) { this.props.showNotification(`不能大于关卡分值${maxsum}`); this.setState({ - customsids:id + customsids: id }) - }else{ - let work_id=this.props.data.work_id; - let url=`/student_works/${work_id}/adjust_review_score.json` - axios.post(url,{ - type:"report", - score:score, - challenge_id:id - }).then((result)=>{ - if(result.data.status===0){ + } else { + let work_id = this.props.data.work_id; + let url = `/student_works/${work_id}/adjust_review_score.json` + axios.post(url, { + type: "report", + score: score, + challenge_id: id + }).then((result) => { + if (result.data.status === 0) { // this.props.getdatalist() this.props.showNotification(result.data.message); - this.props.setupdalist(result.data.challenge_score,result.data.overall_appraisal,result.data.work_score) - newdatas.map((item,key)=>{ - if(item.challenge_id.id===id){ - item.game_scores.game_score=score + this.props.setupdalist(result.data.challenge_score, result.data.overall_appraisal, result.data.work_score) + newdatas.map((item, key) => { + if (item.challenge_id.id === id) { + item.game_scores.game_score = score } }) this.setState({ - datas:newdatas, - customsids:undefined + datas: newdatas, + customsids: undefined }) - }else{ + } else { this.props.showNotification(result.data.message); } - }).catch((error)=>{ + }).catch((error) => { }) } - }else{ + } else { this.props.showNotification("调分为空将不会修改之前的分数"); } } render() { - let {customsids}=this.state; - let {data}=this.props; + let {customsids} = this.state; + let {data} = this.props; - let datas=[]; - if(data!=undefined){ - data.stage_list===undefined?"":data.stage_list.forEach((item,key)=>{ + let datas = []; + if (data != undefined) { + data.stage_list === undefined ? "" : data.stage_list.forEach((item, key) => { datas.push({ - customs: key+1, - taskname:{name:item.name,complete_status:item.complete_status}, - openingtime:item.open_time, + customs: key + 1, + taskname: {name: item.name, complete_status: item.complete_status}, + openingtime: item.open_time, evaluating: item.evaluate_count, - finishtime:item.finished_time, - elapsedtime:item.time_consuming, - empvalue:{myself:item.myself_experience,experience:item.experience}, - game_scores:{game_score:item.game_score,game_score_full:item.game_score_full}, - challenge_id:{id:item.challenge_id}, + finishtime: item.finished_time, + elapsedtime: item.time_consuming, + empvalue: {myself: item.myself_experience, experience: item.experience}, + game_scores: {game_score: item.game_score, game_score_full: item.game_score_full}, + challenge_id: {id: item.challenge_id}, challenge_comment: item.challenge_comment, challenge_comment_hidden: item.challenge_comment_hidden, // adjustmentminute:asdasd @@ -97,7 +99,7 @@ class OfficialAcademicTranscript extends Component { }) } - let columns=[{ + let columns = [{ title: '关卡', dataIndex: 'customs', key: 'customs', @@ -110,13 +112,17 @@ class OfficialAcademicTranscript extends Component { title: '任务名称', dataIndex: 'taskname', key: 'taskname', - className:"TaskForms", + className: "TaskForms", render: (text, record) => ( - this.myjumptopic("id"+record.customs)} title={record.taskname.name.length>15?record.taskname.name:""} > + this.myjumptopic("id" + record.customs)} + title={record.taskname.name.length > 15 ? record.taskname.name : ""}> {record.taskname.name} - {record.taskname.complete_status===2?延时:record.taskname.complete_status===3?延时:""} + {record.taskname.complete_status === 2 ? + 延时 : record.taskname.complete_status === 3 ? + 延时 : ""} ), @@ -158,79 +164,101 @@ class OfficialAcademicTranscript extends Component { {record.elapsedtime} ), - }, { - title: '经验值', - key: 'empvalue', - dataIndex: 'empvalue', + }, + { + title: '查看答案', + dataIndex: 'view_answer', + key: 'view_answer', + className: "edu-txt-center", + render: (text, record) => { + return ( + {record.view_answer === true ? + 学生在完成任务评测之前查是否看了参考答案 + + }>已查看 : + 学生在完成任务评测之前查是否看了参考答案 + + }>未查看 } + ) + } + }, + { + title: '经验值', + key: 'empvalue', + dataIndex: 'empvalue', - render: (text, record) => ( - - {record.empvalue.myself}/{record.empvalue.experience} + render: (text, record) => ( + + {record.empvalue.myself}/{record.empvalue.experience} - ), - },{ - title: '关卡得分', - key: 'game_scores', - dataIndex: 'game_scores', - render: (text, record) => ( - + ), + }, { + title: '关卡得分', + key: 'game_scores', + dataIndex: 'game_scores', + render: (text, record) => ( + 关卡得分:{record.game_scores.game_score}/关卡满分:{record.game_scores.game_score_full} }> - {record.game_scores.game_score}/{record.game_scores.game_score_full} + {record.game_scores.game_score}/{record.game_scores.game_score_full} - ), - },{ - title: '调分', - key: 'adjustmentminute', - dataIndex: 'adjustmentminute', + ), + }, { + title: '调分', + key: 'adjustmentminute', + dataIndex: 'adjustmentminute', - render: (text, record) => ( - - this.editgame_scores(e,record.challenge_id.id,record.game_scores.game_score_full)} - // min={0} max={record.game_scores.game_score_full} + render: (text, record) => ( + + this.editgame_scores(e, record.challenge_id.id, record.game_scores.game_score_full)} + // min={0} max={record.game_scores.game_score_full} /> - {/*查看*/} + {/*查看*/} - ), - },{ - title: '操作', - key: 'operation', - dataIndex: 'operation', + ), + }, { + title: '操作', + key: 'operation', + dataIndex: 'operation', - render: (text, record) => ( - + render: (text, record) => ( + this.props.showAppraiseModal("child",record.challenge_id.id,record.challenge_comment,record.challenge_comment_hidden)} + onClick={() => this.props.showAppraiseModal("child", record.challenge_id.id, record.challenge_comment, record.challenge_comment_hidden)} >评阅 - ), - }]; - + ), + }]; - if(this.props.isAdmin()===false){ - columns.some((item,key)=> { - if (item.title === "调分") { - columns.splice(key, 1) - return true - } - } - ) - columns.some((item,key)=> { - if (item.title === "操作") { - columns.splice(key, 1) - return true - } - } - ) - } + if (this.props.isAdmin() === false) { + columns.some((item, key) => { + if (item.title === "调分") { + columns.splice(key, 1) + return true + } + } + ) + columns.some((item, key) => { + if (item.title === "操作") { + columns.splice(key, 1) + return true + } + } + ) + } return (
    {/*{data===undefined?"":""}*/} @@ -301,10 +329,10 @@ class OfficialAcademicTranscript extends Component { } `} - {datas===undefined?"":}