commit
						b1053cd90e
					
				@ -0,0 +1,54 @@
 | 
				
			||||
$(document).on('turbolinks:load', function() {
 | 
				
			||||
  var $refuseModal = $('.admin-common-refuse-modal');
 | 
				
			||||
  if ($refuseModal.length > 0) {
 | 
				
			||||
    var $form = $refuseModal.find('form.admin-common-refuse-form');
 | 
				
			||||
    var $applyIdInput = $refuseModal.find('.modal-body input[name="apply_id"]');
 | 
				
			||||
 | 
				
			||||
    $form.validate({
 | 
				
			||||
      errorElement: 'span',
 | 
				
			||||
      errorClass: 'danger text-danger',
 | 
				
			||||
      rules: {
 | 
				
			||||
        reason: {
 | 
				
			||||
          required: true,
 | 
				
			||||
          maxlength: 200
 | 
				
			||||
        },
 | 
				
			||||
      }
 | 
				
			||||
    });
 | 
				
			||||
 | 
				
			||||
    // modal ready fire
 | 
				
			||||
    $refuseModal.on('show.bs.modal', function (event) {
 | 
				
			||||
      var $link = $(event.relatedTarget);
 | 
				
			||||
 | 
				
			||||
      var applyId = $link.data('id');
 | 
				
			||||
      var url = $link.data('url');
 | 
				
			||||
 | 
				
			||||
      $applyIdInput.val(applyId);
 | 
				
			||||
      $form.data('url', url);
 | 
				
			||||
    });
 | 
				
			||||
    // modal visited fire
 | 
				
			||||
    $refuseModal.on('shown.bs.modal', function(){
 | 
				
			||||
      $refuseModal.find('.modal-body input[name="reason"]').focus();
 | 
				
			||||
    });
 | 
				
			||||
    $refuseModal.on('hide.bs.modal', function () {
 | 
				
			||||
      $applyIdInput.val('');
 | 
				
			||||
      $form.data('url', '');
 | 
				
			||||
    })
 | 
				
			||||
 | 
				
			||||
    $refuseModal.on('click', '.submit-btn', function(){
 | 
				
			||||
      $form.find('.error').html('');
 | 
				
			||||
 | 
				
			||||
      if ($form.valid()) {
 | 
				
			||||
        var url = $form.data('url');
 | 
				
			||||
 | 
				
			||||
        $.ajax({
 | 
				
			||||
          method: 'POST',
 | 
				
			||||
          dataType: 'script',
 | 
				
			||||
          url: url,
 | 
				
			||||
          data: $form.serialize(),
 | 
				
			||||
        }).done(function(){
 | 
				
			||||
          $refuseModal.modal('hide');
 | 
				
			||||
        });
 | 
				
			||||
      }
 | 
				
			||||
    });
 | 
				
			||||
  }
 | 
				
			||||
});
 | 
				
			||||
@ -0,0 +1,18 @@
 | 
				
			||||
$(document).on('turbolinks:load', function() {
 | 
				
			||||
  if ($('body.admins-identity-authentications-index-page').length > 0) {
 | 
				
			||||
    var $searchFrom = $('.identity-authentication-list-form');
 | 
				
			||||
 | 
				
			||||
    $searchFrom.on('click', '.search-form-tab', function(){
 | 
				
			||||
      var $link = $(this);
 | 
				
			||||
 | 
				
			||||
      $searchFrom.find('input[name="keyword"]').val('');
 | 
				
			||||
      $searchFrom.find('select[name="status"]').val('processed');
 | 
				
			||||
 | 
				
			||||
      if($link.data('value') === 'processed'){
 | 
				
			||||
        $searchFrom.find('.status-filter').show();
 | 
				
			||||
      } else {
 | 
				
			||||
        $searchFrom.find('.status-filter').hide();
 | 
				
			||||
      }
 | 
				
			||||
    });
 | 
				
			||||
  }
 | 
				
			||||
})
 | 
				
			||||
@ -0,0 +1,18 @@
 | 
				
			||||
$(document).on('turbolinks:load', function() {
 | 
				
			||||
  if ($('body.admins-professional-authentications-index-page').length > 0) {
 | 
				
			||||
    var $searchFrom = $('.professional-authentication-list-form');
 | 
				
			||||
 | 
				
			||||
    $searchFrom.on('click', '.search-form-tab', function(){
 | 
				
			||||
      var $link = $(this);
 | 
				
			||||
 | 
				
			||||
      $searchFrom.find('input[name="keyword"]').val('');
 | 
				
			||||
      $searchFrom.find('select[name="status"]').val('processed');
 | 
				
			||||
 | 
				
			||||
      if($link.data('value') === 'processed'){
 | 
				
			||||
        $searchFrom.find('.status-filter').show();
 | 
				
			||||
      } else {
 | 
				
			||||
        $searchFrom.find('.status-filter').hide();
 | 
				
			||||
      }
 | 
				
			||||
    });
 | 
				
			||||
  }
 | 
				
			||||
})
 | 
				
			||||
@ -0,0 +1,10 @@
 | 
				
			||||
$(document).on('turbolinks:load', function() {
 | 
				
			||||
  var $tabs = $('.search-form-container .search-form-tabs');
 | 
				
			||||
  if ($tabs.length > 0) {
 | 
				
			||||
    $tabs.on('click', '.search-form-tab', function(){
 | 
				
			||||
      var $activeTab = $(this);
 | 
				
			||||
      $tabs.find('.search-form-tab').removeClass('active');
 | 
				
			||||
      $activeTab.addClass('active');
 | 
				
			||||
    });
 | 
				
			||||
  }
 | 
				
			||||
});
 | 
				
			||||
@ -0,0 +1,18 @@
 | 
				
			||||
$(document).on('turbolinks:load', function() {
 | 
				
			||||
  if ($('body.admins-shixun-authorizations-index-page').length > 0) {
 | 
				
			||||
    var $searchFrom = $('.shixun-authorization-list-form');
 | 
				
			||||
 | 
				
			||||
    $searchFrom.on('click', '.search-form-tab', function(){
 | 
				
			||||
      var $link = $(this);
 | 
				
			||||
 | 
				
			||||
      $searchFrom.find('input[name="keyword"]').val('');
 | 
				
			||||
      $searchFrom.find('select[name="status"]').val('processed');
 | 
				
			||||
 | 
				
			||||
      if($link.data('value') === 'processed'){
 | 
				
			||||
        $searchFrom.find('.status-filter').show();
 | 
				
			||||
      } else {
 | 
				
			||||
        $searchFrom.find('.status-filter').hide();
 | 
				
			||||
      }
 | 
				
			||||
    });
 | 
				
			||||
  }
 | 
				
			||||
})
 | 
				
			||||
@ -0,0 +1,18 @@
 | 
				
			||||
$(document).on('turbolinks:load', function() {
 | 
				
			||||
  if ($('body.admins-subject-authorizations-index-page').length > 0) {
 | 
				
			||||
    var $searchFrom = $('.subject-authorization-list-form');
 | 
				
			||||
 | 
				
			||||
    $searchFrom.on('click', '.search-form-tab', function(){
 | 
				
			||||
      var $link = $(this);
 | 
				
			||||
 | 
				
			||||
      $searchFrom.find('input[name="keyword"]').val('');
 | 
				
			||||
      $searchFrom.find('select[name="status"]').val('processed');
 | 
				
			||||
 | 
				
			||||
      if($link.data('value') === 'processed'){
 | 
				
			||||
        $searchFrom.find('.status-filter').show();
 | 
				
			||||
      } else {
 | 
				
			||||
        $searchFrom.find('.status-filter').hide();
 | 
				
			||||
      }
 | 
				
			||||
    });
 | 
				
			||||
  }
 | 
				
			||||
})
 | 
				
			||||
											
												
													File diff suppressed because one or more lines are too long
												
											
										
									
								@ -0,0 +1,9 @@
 | 
				
			||||
.admins-identity-authentications-index-page {
 | 
				
			||||
  .identity-authentication-list-container {
 | 
				
			||||
    span {
 | 
				
			||||
      &.apply-status-1 { color: #28a745; }
 | 
				
			||||
      &.apply-status-2 { color: #dc3545; }
 | 
				
			||||
      &.apply-status-3 { color: #6c757d; }
 | 
				
			||||
    }
 | 
				
			||||
  }
 | 
				
			||||
}
 | 
				
			||||
@ -0,0 +1,9 @@
 | 
				
			||||
.admins-professional-authentications-index-page {
 | 
				
			||||
  .professional-authentication-list-container {
 | 
				
			||||
    span {
 | 
				
			||||
      &.apply-status-1 { color: #28a745; }
 | 
				
			||||
      &.apply-status-2 { color: #dc3545; }
 | 
				
			||||
      &.apply-status-3 { color: #6c757d; }
 | 
				
			||||
    }
 | 
				
			||||
  }
 | 
				
			||||
}
 | 
				
			||||
@ -0,0 +1,9 @@
 | 
				
			||||
.admins-shixun-authorizations-index-page {
 | 
				
			||||
  .shixun-authorization-list-container {
 | 
				
			||||
    span {
 | 
				
			||||
      &.apply-status-1 { color: #28a745; }
 | 
				
			||||
      &.apply-status-2 { color: #dc3545; }
 | 
				
			||||
      &.apply-status-3 { color: #6c757d; }
 | 
				
			||||
    }
 | 
				
			||||
  }
 | 
				
			||||
}
 | 
				
			||||
@ -0,0 +1,9 @@
 | 
				
			||||
.admins-subject-authorizations-index-page {
 | 
				
			||||
  .subject-authorization-list-container {
 | 
				
			||||
    span {
 | 
				
			||||
      &.apply-status-1 { color: #28a745; }
 | 
				
			||||
      &.apply-status-2 { color: #dc3545; }
 | 
				
			||||
      &.apply-status-3 { color: #6c757d; }
 | 
				
			||||
    }
 | 
				
			||||
  }
 | 
				
			||||
}
 | 
				
			||||
@ -0,0 +1,26 @@
 | 
				
			||||
class Admins::IdentityAuthenticationsController < Admins::BaseController
 | 
				
			||||
  def index
 | 
				
			||||
    params[:status] ||= 'pending'
 | 
				
			||||
 | 
				
			||||
    applies = Admins::ApplyUserAuthenticationQuery.call(params.merge(type: 1))
 | 
				
			||||
 | 
				
			||||
    @applies = paginate applies.preload(user: { user_extension: [:school, :department] })
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def agree
 | 
				
			||||
    Admins::IdentityAuths::AgreeApplyService.call(current_apply)
 | 
				
			||||
    render_success_js
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def refuse
 | 
				
			||||
    Admins::IdentityAuths::RefuseApplyService.call(current_apply, params)
 | 
				
			||||
 | 
				
			||||
    render_success_js
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  private
 | 
				
			||||
 | 
				
			||||
  def current_apply
 | 
				
			||||
    @_current_apply ||= ApplyUserAuthentication.real_name_auth.find(params[:id])
 | 
				
			||||
  end
 | 
				
			||||
end
 | 
				
			||||
@ -0,0 +1,26 @@
 | 
				
			||||
class Admins::ProfessionalAuthenticationsController < Admins::BaseController
 | 
				
			||||
  def index
 | 
				
			||||
    params[:status] ||= 'pending'
 | 
				
			||||
 | 
				
			||||
    applies = Admins::ApplyUserAuthenticationQuery.call(params.merge(type: 2))
 | 
				
			||||
 | 
				
			||||
    @applies = paginate applies.preload(user: { user_extension: [:school, :department] })
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def agree
 | 
				
			||||
    Admins::ProfessionalAuths::AgreeApplyService.call(current_apply)
 | 
				
			||||
    render_success_js
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def refuse
 | 
				
			||||
    Admins::ProfessionalAuths::RefuseApplyService.call(current_apply, params)
 | 
				
			||||
 | 
				
			||||
    render_success_js
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  private
 | 
				
			||||
 | 
				
			||||
  def current_apply
 | 
				
			||||
    @_current_apply ||= ApplyUserAuthentication.professional_auth.find(params[:id])
 | 
				
			||||
  end
 | 
				
			||||
end
 | 
				
			||||
@ -0,0 +1,48 @@
 | 
				
			||||
class Admins::ShixunAuthorizationsController < Admins::BaseController
 | 
				
			||||
  def index
 | 
				
			||||
    params[:status] ||= 'pending'
 | 
				
			||||
 | 
				
			||||
    applies = ApplyAction.where(container_type: 'ApplyShixun')
 | 
				
			||||
 | 
				
			||||
    status =
 | 
				
			||||
      case params[:status]
 | 
				
			||||
      when 'pending'   then 0
 | 
				
			||||
      when 'processed' then [1, 2]
 | 
				
			||||
      when 'agreed'    then 1
 | 
				
			||||
      when 'refused'   then 2
 | 
				
			||||
      else 0
 | 
				
			||||
      end
 | 
				
			||||
    applies = applies.where(status: status) if status.present?
 | 
				
			||||
 | 
				
			||||
    # 关键字模糊查询
 | 
				
			||||
    keyword = params[:keyword].to_s.strip
 | 
				
			||||
    if keyword.present?
 | 
				
			||||
      applies = applies.joins('JOIN shixuns ON shixuns.id = apply_actions.container_id')
 | 
				
			||||
                  .where('shixuns.name LIKE :keyword', keyword: "%#{keyword}%")
 | 
				
			||||
    end
 | 
				
			||||
 | 
				
			||||
    applies = applies.order(updated_at: :desc)
 | 
				
			||||
 | 
				
			||||
    @applies = paginate applies.includes(user: :user_extension)
 | 
				
			||||
 | 
				
			||||
    shixun_ids = @applies.map(&:container_id)
 | 
				
			||||
    @shixun_map = Shixun.where(id: shixun_ids).each_with_object({}) { |s, h| h[s.id] = s }
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def agree
 | 
				
			||||
    Admins::ShixunAuths::AgreeApplyService.call(current_apply, current_user)
 | 
				
			||||
    render_success_js
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def refuse
 | 
				
			||||
    Admins::ShixunAuths::RefuseApplyService.call(current_apply, current_user, params)
 | 
				
			||||
 | 
				
			||||
    render_success_js
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  private
 | 
				
			||||
 | 
				
			||||
  def current_apply
 | 
				
			||||
    @_current_apply ||= ApplyAction.where(container_type: 'ApplyShixun').find(params[:id])
 | 
				
			||||
  end
 | 
				
			||||
end
 | 
				
			||||
@ -0,0 +1,49 @@
 | 
				
			||||
class Admins::SubjectAuthorizationsController < Admins::BaseController
 | 
				
			||||
  def index
 | 
				
			||||
    params[:status] ||= 'pending'
 | 
				
			||||
 | 
				
			||||
    applies = ApplyAction.where(container_type: 'ApplySubject')
 | 
				
			||||
 | 
				
			||||
    status =
 | 
				
			||||
      case params[:status]
 | 
				
			||||
      when 'pending'   then 0
 | 
				
			||||
      when 'processed' then [1, 2]
 | 
				
			||||
      when 'agreed'    then 1
 | 
				
			||||
      when 'refused'   then 2
 | 
				
			||||
      else 0
 | 
				
			||||
      end
 | 
				
			||||
    applies = applies.where(status: status) if status.present?
 | 
				
			||||
 | 
				
			||||
    # 关键字模糊查询
 | 
				
			||||
    keyword = params[:keyword].to_s.strip
 | 
				
			||||
    if keyword.present?
 | 
				
			||||
      applies = applies.joins('JOIN subjects ON subjects.id = apply_actions.container_id')
 | 
				
			||||
                  .where('subjects.name LIKE :keyword', keyword: "%#{keyword}%")
 | 
				
			||||
    end
 | 
				
			||||
 | 
				
			||||
    applies = applies.order(updated_at: :desc)
 | 
				
			||||
 | 
				
			||||
    @applies = paginate applies.includes(user: :user_extension)
 | 
				
			||||
 | 
				
			||||
    subject_ids = @applies.map(&:container_id)
 | 
				
			||||
    @subject_map = Subject.where(id: subject_ids).each_with_object({}) { |s, h| h[s.id] = s }
 | 
				
			||||
    @challenge_count_map = Challenge.joins(shixun: :stage_shixuns).where(st: 0, stage_shixuns: { subject_id: subject_ids}).group('subject_id').count
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def agree
 | 
				
			||||
    Admins::SubjectAuths::AgreeApplyService.call(current_apply, current_user)
 | 
				
			||||
    render_success_js
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def refuse
 | 
				
			||||
    Admins::SubjectAuths::RefuseApplyService.call(current_apply, current_user, params)
 | 
				
			||||
 | 
				
			||||
    render_success_js
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  private
 | 
				
			||||
 | 
				
			||||
  def current_apply
 | 
				
			||||
    @_current_apply ||= ApplyAction.where(container_type: 'ApplySubject').find(params[:id])
 | 
				
			||||
  end
 | 
				
			||||
end
 | 
				
			||||
@ -0,0 +1,102 @@
 | 
				
			||||
module Admins::BaseHelper
 | 
				
			||||
  def sidebar_item_group(url, text, **opts)
 | 
				
			||||
    link_opts = url.start_with?('/') ? {} : { 'data-toggle': 'collapse', 'aria-expanded': false }
 | 
				
			||||
    content =
 | 
				
			||||
      link_to url, link_opts do
 | 
				
			||||
        content_tag(:i, '', class: "fa fa-#{opts[:icon]}", 'data-toggle': 'tooltip', 'data-placement': 'right', 'data-boundary': 'window', title: text) +
 | 
				
			||||
          content_tag(:span, text)
 | 
				
			||||
      end
 | 
				
			||||
 | 
				
			||||
    content +=
 | 
				
			||||
      content_tag(:ul, id: url[1..-1], class: 'collapse list-unstyled', "data-parent": '#sidebar') do
 | 
				
			||||
        yield
 | 
				
			||||
      end
 | 
				
			||||
 | 
				
			||||
    raw content
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def sidebar_item(url, text, **opts)
 | 
				
			||||
    content =
 | 
				
			||||
      link_to url, 'data-controller': opts[:controller] do
 | 
				
			||||
        content_tag(:i, '', class: "fa fa-#{opts[:icon]}", 'data-toggle': 'tooltip', 'data-placement': 'right', 'data-boundary': 'window', title: text) +
 | 
				
			||||
          content_tag(:span, text)
 | 
				
			||||
      end
 | 
				
			||||
 | 
				
			||||
    raw content
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def admin_sidebar_controller
 | 
				
			||||
    key = params[:controller].to_s.gsub(/\//, '-')
 | 
				
			||||
    SidebarUtil.controller_name(key) || key
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def define_admin_breadcrumbs(&block)
 | 
				
			||||
    content_for(:setup_admin_breadcrumb, &block)
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def add_admin_breadcrumb(text, url = nil)
 | 
				
			||||
    @_admin_breadcrumbs ||= []
 | 
				
			||||
    @_admin_breadcrumbs << OpenStruct.new(text: text, url: url)
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def display_text(str, default = '--')
 | 
				
			||||
    str.presence || default
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def overflow_hidden_span(text, width: 300)
 | 
				
			||||
    opts = { class: 'd-inline-block text-truncate', style: "max-width: #{width}px" }
 | 
				
			||||
    opts.merge!('data-toggle': 'tooltip', title: text) if text != '--'
 | 
				
			||||
 | 
				
			||||
    content_tag(:span, text, opts)
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def sort_tag(content = '', **opts)
 | 
				
			||||
    options = {}
 | 
				
			||||
    options[:sort_by] = opts.delete(:name)
 | 
				
			||||
    is_current_sort = params[:sort_by].to_s == options[:sort_by]
 | 
				
			||||
    options[:sort_direction] = is_current_sort && params[:sort_direction].to_s == 'desc' ? 'asc' : 'desc'
 | 
				
			||||
 | 
				
			||||
    path = opts.delete(:path) + "?" + unsafe_params.merge(options).to_query
 | 
				
			||||
    arrow_class = case params[:sort_direction].to_s
 | 
				
			||||
                  when 'desc' then 'fa-sort-amount-desc'
 | 
				
			||||
                  when 'asc' then 'fa-sort-amount-asc'
 | 
				
			||||
                  else ''
 | 
				
			||||
                  end
 | 
				
			||||
    opts[:style] = "#{opts[:style]} ;position: relative;"
 | 
				
			||||
 | 
				
			||||
    content_tag(:span, opts) do
 | 
				
			||||
      link_to path, remote: true do
 | 
				
			||||
        content = content_tag(:span) { yield } if block_given?
 | 
				
			||||
 | 
				
			||||
        content += content_tag(:i, '', class: "fa color-light-green ml-1 #{arrow_class}", style: 'position: absolute;top:0;') if is_current_sort
 | 
				
			||||
        raw content
 | 
				
			||||
      end
 | 
				
			||||
    end
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def javascript_void_link(name, **opts)
 | 
				
			||||
    raw link_to(name, 'javascript:void(0)', opts)
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def agree_link(name, url, **opts)
 | 
				
			||||
    klass = ['action agree-action', opts.delete(:class)].compact.join(' ')
 | 
				
			||||
 | 
				
			||||
    refresh_url_data = "refresh_url=#{CGI::escape(request.fullpath)}"
 | 
				
			||||
    url = url + (url.index('?') ? '&' : '?') + refresh_url_data
 | 
				
			||||
 | 
				
			||||
    raw link_to(name, url, { method: :post, remote: true, class: klass, 'data-confirm': '确认审核通过?'}.merge(opts))
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def delete_link(name, url, **opts)
 | 
				
			||||
    klass = ['action delete-action', opts.delete(:class)].compact.join(' ')
 | 
				
			||||
 | 
				
			||||
    refresh_url_data = "refresh_url=#{CGI::escape(request.fullpath)}"
 | 
				
			||||
    url = url + (url.index('?') ? '&' : '?') + refresh_url_data
 | 
				
			||||
 | 
				
			||||
    raw link_to(name, url, { method: :delete, remote: true, class: klass, 'data-confirm': '确认删除?'}.merge(opts))
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def unsafe_params
 | 
				
			||||
    params.except(:controller, :action).to_unsafe_h
 | 
				
			||||
  end
 | 
				
			||||
end
 | 
				
			||||
@ -0,0 +1,40 @@
 | 
				
			||||
module Util::FileManage
 | 
				
			||||
  module_function
 | 
				
			||||
 | 
				
			||||
  # 不同的类型扩展不同的目录
 | 
				
			||||
  def relative_path
 | 
				
			||||
    "avatars"
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def storage_path
 | 
				
			||||
    File.join(Rails.root, "public", "images", relative_path)
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def disk_filename(source_type,source_id,image_file=nil)
 | 
				
			||||
    File.join(storage_path, "#{source_type}", "#{source_id}")
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def disk_auth_filename(source_type, source_id, type)
 | 
				
			||||
    File.join(storage_path, "#{source_type}", "#{source_id}#{type}")
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def disk_real_name_auth_filename(source_id)
 | 
				
			||||
    disk_auth_filename('UserAuthentication', source_id, 'ID')
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def auth_file_url(source_type, source_id, type)
 | 
				
			||||
    File.join('/images', relative_path, source_type, "#{source_id}#{type}")
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def real_name_auth_file_url(source_id)
 | 
				
			||||
    auth_file_url('UserAuthentication', source_id, 'ID')
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def disk_professional_auth_filename(source_id)
 | 
				
			||||
    disk_auth_filename('UserAuthentication', source_id, 'PRO')
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def professional_auth_file_url(source_id)
 | 
				
			||||
    auth_file_url('UserAuthentication', source_id, 'PRO')
 | 
				
			||||
  end
 | 
				
			||||
end
 | 
				
			||||
@ -1,3 +1,6 @@
 | 
				
			||||
class Inform < ApplicationRecord
 | 
				
			||||
  belongs_to :container, polymorphic: true, optional: true
 | 
				
			||||
 | 
				
			||||
  validates :name, length: { maximum: 60 }
 | 
				
			||||
  validates :description, length: { maximum: 5000 }
 | 
				
			||||
end
 | 
				
			||||
 | 
				
			||||
@ -0,0 +1,34 @@
 | 
				
			||||
class Admins::ApplyUserAuthenticationQuery < ApplicationQuery
 | 
				
			||||
  include CustomSortable
 | 
				
			||||
 | 
				
			||||
  attr_reader :params
 | 
				
			||||
 | 
				
			||||
  sort_columns :updated_at, default_by: :updated_at, default_direction: :desc
 | 
				
			||||
 | 
				
			||||
  def initialize(params)
 | 
				
			||||
    @params = params
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def call
 | 
				
			||||
    applies = ApplyUserAuthentication.where(auth_type: params[:type].presence || 1)
 | 
				
			||||
 | 
				
			||||
    status =
 | 
				
			||||
      case params[:status]
 | 
				
			||||
      when 'pending'   then 0
 | 
				
			||||
      when 'processed' then [1, 2]
 | 
				
			||||
      when 'agreed'    then 1
 | 
				
			||||
      when 'refused'   then 2
 | 
				
			||||
      else 0
 | 
				
			||||
      end
 | 
				
			||||
    applies = applies.where(status: status) if status.present?
 | 
				
			||||
 | 
				
			||||
    # 关键字模糊查询
 | 
				
			||||
    keyword = params[:keyword].to_s.strip
 | 
				
			||||
    if keyword.present?
 | 
				
			||||
      applies = applies.joins(user: { user_extension: :school })
 | 
				
			||||
                  .where('CONCAT(lastname,firstname) LIKE :keyword OR schools.name LIKE :keyword', keyword: "%#{keyword}%")
 | 
				
			||||
    end
 | 
				
			||||
 | 
				
			||||
    custom_sort(applies, params[:sort_by], params[:sort_direction])
 | 
				
			||||
  end
 | 
				
			||||
end
 | 
				
			||||
@ -0,0 +1,38 @@
 | 
				
			||||
class Admins::IdentityAuths::AgreeApplyService < ApplicationService
 | 
				
			||||
  attr_reader :apply, :user
 | 
				
			||||
 | 
				
			||||
  def initialize(apply)
 | 
				
			||||
    @apply = apply
 | 
				
			||||
    @user  = apply.user
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def call
 | 
				
			||||
    ActiveRecord::Base.transaction do
 | 
				
			||||
      apply.update!(status: 1)
 | 
				
			||||
      user.update!(authentication: true)
 | 
				
			||||
 | 
				
			||||
      RewardGradeService.call(user, container_id: user.id, container_type: 'Authentication', score: 500)
 | 
				
			||||
 | 
				
			||||
      deal_tiding!
 | 
				
			||||
      delete_auth_file!
 | 
				
			||||
    end
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  private
 | 
				
			||||
 | 
				
			||||
  def deal_tiding!
 | 
				
			||||
    apply.tidings.where(tiding_type: 'Apply').update_all(status: 1)
 | 
				
			||||
 | 
				
			||||
    Tiding.create!(user_id: apply.user_id, trigger_user_id: 0,
 | 
				
			||||
                   container_id: apply.id, container_type: 'ApplyUserAuthentication',
 | 
				
			||||
                   belong_container_id: apply.user_id, belong_container_type: 'User',
 | 
				
			||||
                   status: 1, tiding_type: 'System')
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def delete_auth_file!
 | 
				
			||||
    path = Util::FileManage.disk_real_name_auth_filename(user.id)
 | 
				
			||||
    File.delete(path) if File.exists?(path)
 | 
				
			||||
 | 
				
			||||
    apply.update!(is_delete: true)
 | 
				
			||||
  end
 | 
				
			||||
end
 | 
				
			||||
@ -0,0 +1,40 @@
 | 
				
			||||
class Admins::IdentityAuths::RefuseApplyService < ApplicationService
 | 
				
			||||
  attr_reader :apply, :user, :params
 | 
				
			||||
 | 
				
			||||
  def initialize(apply, params)
 | 
				
			||||
    @apply  = apply
 | 
				
			||||
    @user   = apply.user
 | 
				
			||||
    @params = params
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def call
 | 
				
			||||
    ActiveRecord::Base.transaction do
 | 
				
			||||
      apply.update!(status: 2, remarks: reason)
 | 
				
			||||
 | 
				
			||||
      deal_tiding!
 | 
				
			||||
      delete_auth_file!
 | 
				
			||||
    end
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  private
 | 
				
			||||
 | 
				
			||||
  def reason
 | 
				
			||||
    params[:reason].to_s.strip
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def deal_tiding!
 | 
				
			||||
    apply.tidings.where(tiding_type: 'Apply').update_all(status: 1)
 | 
				
			||||
 | 
				
			||||
    Tiding.create!(user_id: apply.user_id, trigger_user_id: 0,
 | 
				
			||||
                   container_id: apply.id, container_type: 'ApplyUserAuthentication',
 | 
				
			||||
                   belong_container_id: apply.user_id, belong_container_type: 'User',
 | 
				
			||||
                   status: 2, tiding_type: 'System')
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def delete_auth_file!
 | 
				
			||||
    path = Util::FileManage.disk_real_name_auth_filename(user.id)
 | 
				
			||||
    File.delete(path) if File.exists?(path)
 | 
				
			||||
 | 
				
			||||
    apply.update!(is_delete: true)
 | 
				
			||||
  end
 | 
				
			||||
end
 | 
				
			||||
@ -0,0 +1,38 @@
 | 
				
			||||
class Admins::ProfessionalAuths::AgreeApplyService < ApplicationService
 | 
				
			||||
  attr_reader :apply, :user
 | 
				
			||||
 | 
				
			||||
  def initialize(apply)
 | 
				
			||||
    @apply = apply
 | 
				
			||||
    @user  = apply.user
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def call
 | 
				
			||||
    ActiveRecord::Base.transaction do
 | 
				
			||||
      apply.update!(status: 1)
 | 
				
			||||
      user.update!(professional_certification: true)
 | 
				
			||||
 | 
				
			||||
      RewardGradeService.call(user, container_id: user.id, container_type: 'Professional', score: 500)
 | 
				
			||||
 | 
				
			||||
      deal_tiding!
 | 
				
			||||
      delete_auth_file!
 | 
				
			||||
    end
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  private
 | 
				
			||||
 | 
				
			||||
  def deal_tiding!
 | 
				
			||||
    apply.tidings.where(tiding_type: 'Apply').update_all(status: 1)
 | 
				
			||||
 | 
				
			||||
    Tiding.create!(user_id: apply.user_id, trigger_user_id: 0,
 | 
				
			||||
                   container_id: apply.id, container_type: 'ApplyUserAuthentication',
 | 
				
			||||
                   belong_container_id: apply.user_id, belong_container_type: 'User',
 | 
				
			||||
                   status: 1, tiding_type: 'System')
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def delete_auth_file!
 | 
				
			||||
    path = Util::FileManage.disk_professional_auth_filename(user.id)
 | 
				
			||||
    File.delete(path) if File.exists?(path)
 | 
				
			||||
 | 
				
			||||
    apply.update!(is_delete: true)
 | 
				
			||||
  end
 | 
				
			||||
end
 | 
				
			||||
@ -0,0 +1,40 @@
 | 
				
			||||
class Admins::ProfessionalAuths::RefuseApplyService < ApplicationService
 | 
				
			||||
  attr_reader :apply, :user, :params
 | 
				
			||||
 | 
				
			||||
  def initialize(apply, params)
 | 
				
			||||
    @apply  = apply
 | 
				
			||||
    @user   = apply.user
 | 
				
			||||
    @params = params
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def call
 | 
				
			||||
    ActiveRecord::Base.transaction do
 | 
				
			||||
      apply.update!(status: 2, remarks: reason)
 | 
				
			||||
 | 
				
			||||
      deal_tiding!
 | 
				
			||||
      delete_auth_file!
 | 
				
			||||
    end
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  private
 | 
				
			||||
 | 
				
			||||
  def reason
 | 
				
			||||
    params[:reason].to_s.strip
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def deal_tiding!
 | 
				
			||||
    apply.tidings.where(tiding_type: 'Apply').update_all(status: 1)
 | 
				
			||||
 | 
				
			||||
    Tiding.create!(user_id: apply.user_id, trigger_user_id: 0,
 | 
				
			||||
                   container_id: apply.id, container_type: 'ApplyUserAuthentication',
 | 
				
			||||
                   belong_container_id: apply.user_id, belong_container_type: 'User',
 | 
				
			||||
                   status: 2, tiding_type: 'System')
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def delete_auth_file!
 | 
				
			||||
    path = Util::FileManage.disk_professional_auth_filename(user.id)
 | 
				
			||||
    File.delete(path) if File.exists?(path)
 | 
				
			||||
 | 
				
			||||
    apply.update!(is_delete: true)
 | 
				
			||||
  end
 | 
				
			||||
end
 | 
				
			||||
@ -0,0 +1,43 @@
 | 
				
			||||
class Admins::ShixunAuths::AgreeApplyService < ApplicationService
 | 
				
			||||
  attr_reader :apply, :user, :shixun
 | 
				
			||||
 | 
				
			||||
  def initialize(apply, user)
 | 
				
			||||
    @apply  = apply
 | 
				
			||||
    @user   = user
 | 
				
			||||
    @shixun = Shixun.find(apply.container_id)
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def call
 | 
				
			||||
    ActiveRecord::Base.transaction do
 | 
				
			||||
      apply.update!(status: 1, dealer_id: user.id)
 | 
				
			||||
      shixun.update!(status: 2, publish_time: Time.now)
 | 
				
			||||
 | 
				
			||||
      # 奖励金币、经验
 | 
				
			||||
      reward_grade_and_experience!
 | 
				
			||||
 | 
				
			||||
      deal_tiding!
 | 
				
			||||
    end
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  private
 | 
				
			||||
 | 
				
			||||
  def reward_grade_and_experience!
 | 
				
			||||
    score = shixun.all_score
 | 
				
			||||
    shixun_creator = shixun.user
 | 
				
			||||
 | 
				
			||||
    RewardGradeService.call(shixun_creator, container_id: shixun.id, container_type: 'shixunPublish', score: score)
 | 
				
			||||
 | 
				
			||||
    Experience.create!(user_id: shixun_creator.id, container_id: shixun.id, container_type: 'shixunPublish', score: score)
 | 
				
			||||
    shixun_creator.update_column(:experience, shixun_creator.experience.to_i + score)
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def deal_tiding!
 | 
				
			||||
    apply.tidings.where(tiding_type: 'Apply', status: 0).update_all(status: 1)
 | 
				
			||||
 | 
				
			||||
    Tiding.create!(user_id: apply.user_id, trigger_user_id: 0,
 | 
				
			||||
                   container_id: apply.id, container_type: 'ApplyAction',
 | 
				
			||||
                   parent_container_id: apply.container_id, parent_container_type: apply.container_type,
 | 
				
			||||
                   belong_container_id: apply.container_id, belong_container_type: 'Shixun',
 | 
				
			||||
                   status: 1, tiding_type: 'System')
 | 
				
			||||
  end
 | 
				
			||||
end
 | 
				
			||||
@ -0,0 +1,35 @@
 | 
				
			||||
class Admins::ShixunAuths::RefuseApplyService < ApplicationService
 | 
				
			||||
  attr_reader :apply, :user, :shixun, :params
 | 
				
			||||
 | 
				
			||||
  def initialize(apply, user, params)
 | 
				
			||||
    @apply  = apply
 | 
				
			||||
    @user   = user
 | 
				
			||||
    @shixun = Shixun.find(apply.container_id)
 | 
				
			||||
    @params = params
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def call
 | 
				
			||||
    ActiveRecord::Base.transaction do
 | 
				
			||||
      shixun.update!(status: 0)
 | 
				
			||||
      apply.update!(status: 2, reason: reason, dealer_id: user.id)
 | 
				
			||||
 | 
				
			||||
      deal_tiding!
 | 
				
			||||
    end
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  private
 | 
				
			||||
 | 
				
			||||
  def reason
 | 
				
			||||
    params[:reason].to_s.strip
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def deal_tiding!
 | 
				
			||||
    apply.tidings.where(tiding_type: 'Apply', status: 0).update_all(status: 1)
 | 
				
			||||
 | 
				
			||||
    Tiding.create!(user_id: apply.user_id, trigger_user_id: 0,
 | 
				
			||||
                   container_id: apply.id, container_type: 'ApplyAction',
 | 
				
			||||
                   parent_container_id: apply.container_id, parent_container_type: apply.container_type,
 | 
				
			||||
                   belong_container_id: apply.container_id, belong_container_type: 'Shixun',
 | 
				
			||||
                   status: 2, tiding_type: 'System')
 | 
				
			||||
  end
 | 
				
			||||
end
 | 
				
			||||
@ -0,0 +1,30 @@
 | 
				
			||||
class Admins::SubjectAuths::AgreeApplyService < ApplicationService
 | 
				
			||||
  attr_reader :apply, :user, :subject
 | 
				
			||||
 | 
				
			||||
  def initialize(apply, user)
 | 
				
			||||
    @apply   = apply
 | 
				
			||||
    @user    = user
 | 
				
			||||
    @subject = Subject.find(apply.container_id)
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def call
 | 
				
			||||
    ActiveRecord::Base.transaction do
 | 
				
			||||
      apply.update!(status: 1, dealer_id: user.id)
 | 
				
			||||
      subject.update!(status: 2, publish_time: Time.now)
 | 
				
			||||
 | 
				
			||||
      deal_tiding!
 | 
				
			||||
    end
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  private
 | 
				
			||||
 | 
				
			||||
  def deal_tiding!
 | 
				
			||||
    apply.tidings.where(tiding_type: 'Apply', status: 0).update_all(status: 1)
 | 
				
			||||
 | 
				
			||||
    Tiding.create!(user_id: apply.user_id, trigger_user_id: 0,
 | 
				
			||||
                   container_id: apply.id, container_type: 'ApplyAction',
 | 
				
			||||
                   parent_container_id: apply.container_id, parent_container_type: apply.container_type,
 | 
				
			||||
                   belong_container_id: apply.container_id, belong_container_type: 'Subject',
 | 
				
			||||
                   status: 1, tiding_type: 'System')
 | 
				
			||||
  end
 | 
				
			||||
end
 | 
				
			||||
@ -0,0 +1,35 @@
 | 
				
			||||
class Admins::SubjectAuths::RefuseApplyService < ApplicationService
 | 
				
			||||
  attr_reader :apply, :user, :subject, :params
 | 
				
			||||
 | 
				
			||||
  def initialize(apply, user, params)
 | 
				
			||||
    @apply   = apply
 | 
				
			||||
    @user    = user
 | 
				
			||||
    @subject = Subject.find(apply.container_id)
 | 
				
			||||
    @params  = params
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def call
 | 
				
			||||
    ActiveRecord::Base.transaction do
 | 
				
			||||
      subject.update!(status: 0)
 | 
				
			||||
      apply.update!(status: 2, reason: reason, dealer_id: user.id)
 | 
				
			||||
 | 
				
			||||
      deal_tiding!
 | 
				
			||||
    end
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  private
 | 
				
			||||
 | 
				
			||||
  def reason
 | 
				
			||||
    params[:reason].to_s.strip
 | 
				
			||||
  end
 | 
				
			||||
 | 
				
			||||
  def deal_tiding!
 | 
				
			||||
    apply.tidings.where(tiding_type: 'Apply', status: 0).update_all(status: 1)
 | 
				
			||||
 | 
				
			||||
    Tiding.create!(user_id: apply.user_id, trigger_user_id: 0,
 | 
				
			||||
                   container_id: apply.id, container_type: 'ApplyAction',
 | 
				
			||||
                   parent_container_id: apply.container_id, parent_container_type: apply.container_type,
 | 
				
			||||
                   belong_container_id: apply.container_id, belong_container_type: 'Subject',
 | 
				
			||||
                   status: 2, tiding_type: 'System')
 | 
				
			||||
  end
 | 
				
			||||
end
 | 
				
			||||
@ -0,0 +1,32 @@
 | 
				
			||||
<% define_admin_breadcrumbs do %>
 | 
				
			||||
  <% add_admin_breadcrumb('实名认证') %>
 | 
				
			||||
<% end %>
 | 
				
			||||
 | 
				
			||||
<div class="box search-form-container flex-column mb-0 pb-0 identity-authentication-list-form">
 | 
				
			||||
  <ul class="nav nav-tabs w-100 search-form-tabs">
 | 
				
			||||
    <li class="nav-item">
 | 
				
			||||
      <%= link_to '待审批', admins_identity_authentications_path(status: :pending), remote: true, 'data-value': 'pending',
 | 
				
			||||
                  class: "nav-link search-form-tab #{params[:status] == 'pending' ? 'active' : ''}" %>
 | 
				
			||||
    </li>
 | 
				
			||||
    <li class="nav-item">
 | 
				
			||||
      <%= link_to '已审批', admins_identity_authentications_path(status: :processed), remote: true, 'data-value': 'processed',
 | 
				
			||||
                  class: "nav-link search-form-tab #{params[:status] != 'pending' ? 'active' : ''}" %>
 | 
				
			||||
    </li>
 | 
				
			||||
  </ul>
 | 
				
			||||
 | 
				
			||||
  <%= form_tag(admins_identity_authentications_path(unsafe_params), method: :get, class: 'form-inline search-form justify-content-end mt-3', remote: true) do %>
 | 
				
			||||
    <div class="form-group status-filter" style="<%= params[:status] != 'pending' ? '' : 'display: none;' %>">
 | 
				
			||||
      <label for="status">审核状态:</label>
 | 
				
			||||
      <% status_options = [['全部', 'processed'], ['已同意', 'agreed'], ['已拒绝', 'refused']] %>
 | 
				
			||||
      <%= select_tag(:status, options_for_select(status_options), class: 'form-control') %>
 | 
				
			||||
    </div>
 | 
				
			||||
    <%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: '姓名/学校/单位检索') %>
 | 
				
			||||
    <%= submit_tag('搜索', class: 'btn btn-primary ml-3') %>
 | 
				
			||||
  <% end %>
 | 
				
			||||
</div>
 | 
				
			||||
 | 
				
			||||
<div class="box identity-authentication-list-container">
 | 
				
			||||
  <%= render(partial: 'admins/identity_authentications/shared/list', locals: { applies: @applies }) %>
 | 
				
			||||
</div>
 | 
				
			||||
 | 
				
			||||
<%= render(partial: 'admins/shared/admin_common_refuse_modal') %>
 | 
				
			||||
@ -0,0 +1 @@
 | 
				
			||||
$('.identity-authentication-list-container').html("<%= j( render partial: 'admins/identity_authentications/shared/list', locals: { applies: @applies } ) %>");
 | 
				
			||||
@ -0,0 +1,74 @@
 | 
				
			||||
<% is_processed = params[:status].to_s != 'pending' %>
 | 
				
			||||
 | 
				
			||||
<table class="table table-hover text-center identity-authentication-list-table">
 | 
				
			||||
  <thead class="thead-light">
 | 
				
			||||
  <tr>
 | 
				
			||||
    <th width="8%">头像</th>
 | 
				
			||||
    <th width="10%">姓名</th>
 | 
				
			||||
    <th width="14%">身份证号</th>
 | 
				
			||||
    <th width="20%">学校/单位</th>
 | 
				
			||||
    <th width="12%">职称</th>
 | 
				
			||||
    <% unless is_processed %>
 | 
				
			||||
      <th width="8%">
 | 
				
			||||
        照片
 | 
				
			||||
        <i class="fa fa-question-circle" data-toggle="tooltip" data-html="true" data-placement="top" title="审核完成后自动删除图片"></i>
 | 
				
			||||
      </th>
 | 
				
			||||
    <% end %>
 | 
				
			||||
    <th width="16%">时间</th>
 | 
				
			||||
    <% if is_processed %>
 | 
				
			||||
      <th width="14%">拒绝原因</th>
 | 
				
			||||
      <th width="8%">状态</th>
 | 
				
			||||
    <% else %>
 | 
				
			||||
      <th width="20%">操作</th>
 | 
				
			||||
    <% end %>
 | 
				
			||||
  </tr>
 | 
				
			||||
  </thead>
 | 
				
			||||
  <tbody>
 | 
				
			||||
  <% if applies.present? %>
 | 
				
			||||
    <% applies.each do |apply| %>
 | 
				
			||||
      <% user = apply.user %>
 | 
				
			||||
      <tr class="identity-authentication-item identity-authentication-<%= apply.id %>">
 | 
				
			||||
        <td>
 | 
				
			||||
          <%= link_to "/users/#{user.login}", class: 'identity-authentication-avatar', target: '_blank', data: { toggle: 'tooltip', title: '个人主页' } do %>
 | 
				
			||||
            <img src="/images/<%= url_to_avatar(user) %>" class="rounded-circle" width="40" height="40" />
 | 
				
			||||
          <% end %>
 | 
				
			||||
        </td>
 | 
				
			||||
        <td><%= user.real_name %></td>
 | 
				
			||||
        <td><%= user.ID_number %></td>
 | 
				
			||||
        <td><%= raw [user.school_name.presence, user.department_name.presence].compact.join('<br/>') %></td>
 | 
				
			||||
        <td><%= user.identity %> <%= raw user.user_extension.student? && user.student_id ? "<br/>#{user.student_id}" : '' %></td>
 | 
				
			||||
 | 
				
			||||
        <% unless is_processed %>
 | 
				
			||||
          <td>
 | 
				
			||||
            <% if File.exists?(disk_real_name_auth_filename(user.id)) %>
 | 
				
			||||
              <%= image_tag(real_name_auth_file_url(user.id).to_s + "?#{Time.now.to_i}", width: 40, height: 40, class: 'preview-image auth-image', data: { toggle: 'tooltip', title: '点击预览' }) %>
 | 
				
			||||
            <% else %>
 | 
				
			||||
              <%= content_tag(:span, '图片已删除', class: 'text-secondary') %>
 | 
				
			||||
            <% end %>
 | 
				
			||||
          </td>
 | 
				
			||||
        <% end %>
 | 
				
			||||
 | 
				
			||||
        <td><%= apply.updated_at.strftime('%Y-%m-%d %H:%M') %></td>
 | 
				
			||||
 | 
				
			||||
        <% if is_processed %>
 | 
				
			||||
          <td class="text-secondary"><%= overflow_hidden_span apply.remarks, width: 140 %></td>
 | 
				
			||||
          <td><span class="apply-status-<%= apply.status %>"><%= apply.status_text %></span></td>
 | 
				
			||||
        <% else %>
 | 
				
			||||
          <td class="action-container">
 | 
				
			||||
            <%= agree_link '同意', agree_admins_identity_authentication_path(apply, element: ".identity-authentication-#{apply.id}"), 'data-confirm': '确认审核通过?' %>
 | 
				
			||||
            <%= javascript_void_link('拒绝', class: 'action refuse-action',
 | 
				
			||||
                                     data: {
 | 
				
			||||
                                         toggle: 'modal', target: '.admin-common-refuse-modal', id: apply.id,
 | 
				
			||||
                                         url: refuse_admins_identity_authentication_path(apply, element: ".identity-authentication-#{apply.id}")
 | 
				
			||||
                                     }) %>
 | 
				
			||||
          </td>
 | 
				
			||||
        <% end %>
 | 
				
			||||
      </tr>
 | 
				
			||||
    <% end %>
 | 
				
			||||
  <% else %>
 | 
				
			||||
    <%= render 'admins/shared/no_data_for_table' %>
 | 
				
			||||
  <% end %>
 | 
				
			||||
  </tbody>
 | 
				
			||||
</table>
 | 
				
			||||
 | 
				
			||||
<%= render partial: 'admins/shared/paginate', locals: { objects: applies } %>
 | 
				
			||||
@ -0,0 +1,32 @@
 | 
				
			||||
<% define_admin_breadcrumbs do %>
 | 
				
			||||
  <% add_admin_breadcrumb('职业认证') %>
 | 
				
			||||
<% end %>
 | 
				
			||||
 | 
				
			||||
<div class="box search-form-container flex-column mb-0 pb-0 professional-authentication-list-form">
 | 
				
			||||
  <ul class="nav nav-tabs w-100 search-form-tabs">
 | 
				
			||||
    <li class="nav-item">
 | 
				
			||||
      <%= link_to '待审批', admins_professional_authentications_path(status: :pending), remote: true, 'data-value': 'pending',
 | 
				
			||||
                  class: "nav-link search-form-tab #{params[:status] == 'pending' ? 'active' : ''}" %>
 | 
				
			||||
    </li>
 | 
				
			||||
    <li class="nav-item">
 | 
				
			||||
      <%= link_to '已审批', admins_professional_authentications_path(status: :processed), remote: true, 'data-value': 'processed',
 | 
				
			||||
                  class: "nav-link search-form-tab #{params[:status] != 'pending' ? 'active' : ''}" %>
 | 
				
			||||
    </li>
 | 
				
			||||
  </ul>
 | 
				
			||||
 | 
				
			||||
  <%= form_tag(admins_professional_authentications_path(unsafe_params), method: :get, class: 'form-inline search-form justify-content-end mt-3', remote: true) do %>
 | 
				
			||||
    <div class="form-group status-filter" style="<%= params[:status] != 'pending' ? '' : 'display: none;' %>">
 | 
				
			||||
      <label for="status">审核状态:</label>
 | 
				
			||||
      <% status_options = [['全部', 'processed'], ['已同意', 'agreed'], ['已拒绝', 'refused']] %>
 | 
				
			||||
      <%= select_tag(:status, options_for_select(status_options), class: 'form-control') %>
 | 
				
			||||
    </div>
 | 
				
			||||
    <%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: '姓名/学校/单位检索') %>
 | 
				
			||||
    <%= submit_tag('搜索', class: 'btn btn-primary ml-3') %>
 | 
				
			||||
  <% end %>
 | 
				
			||||
</div>
 | 
				
			||||
 | 
				
			||||
<div class="box professional-authentication-list-container">
 | 
				
			||||
  <%= render(partial: 'admins/professional_authentications/shared/list', locals: { applies: @applies }) %>
 | 
				
			||||
</div>
 | 
				
			||||
 | 
				
			||||
<%= render(partial: 'admins/shared/admin_common_refuse_modal') %>
 | 
				
			||||
@ -0,0 +1 @@
 | 
				
			||||
$('.professional-authentication-list-container').html("<%= j( render partial: 'admins/professional_authentications/shared/list', locals: { applies: @applies } ) %>");
 | 
				
			||||
@ -0,0 +1,72 @@
 | 
				
			||||
<% is_processed = params[:status].to_s != 'pending' %>
 | 
				
			||||
 | 
				
			||||
<table class="table table-hover text-center professional-authentication-list-table">
 | 
				
			||||
  <thead class="thead-light">
 | 
				
			||||
  <tr>
 | 
				
			||||
    <th width="8%">头像</th>
 | 
				
			||||
    <th width="14%">姓名</th>
 | 
				
			||||
    <th width="28%">学校/单位</th>
 | 
				
			||||
    <th width="12%">职称</th>
 | 
				
			||||
    <% unless is_processed %>
 | 
				
			||||
      <th width="10%">
 | 
				
			||||
        照片
 | 
				
			||||
        <i class="fa fa-question-circle" data-toggle="tooltip" data-html="true" data-placement="top" title="审核完成后自动删除图片"></i>
 | 
				
			||||
      </th>
 | 
				
			||||
    <% end %>
 | 
				
			||||
    <th width="16%">时间</th>
 | 
				
			||||
    <% if is_processed %>
 | 
				
			||||
      <th width="14%">拒绝原因</th>
 | 
				
			||||
      <th width="8%">状态</th>
 | 
				
			||||
    <% else %>
 | 
				
			||||
      <th width="18%">操作</th>
 | 
				
			||||
    <% end %>
 | 
				
			||||
  </tr>
 | 
				
			||||
  </thead>
 | 
				
			||||
  <tbody>
 | 
				
			||||
  <% if applies.present? %>
 | 
				
			||||
    <% applies.each do |apply| %>
 | 
				
			||||
      <% user = apply.user %>
 | 
				
			||||
      <tr class="professional-authentication-item professional-authentication-<%= apply.id %>">
 | 
				
			||||
        <td>
 | 
				
			||||
          <%= link_to "/users/#{user.login}", class: 'professional-authentication-avatar', target: '_blank', data: { toggle: 'tooltip', title: '个人主页' } do %>
 | 
				
			||||
            <img src="/images/<%= url_to_avatar(user) %>" class="rounded-circle" width="40" height="40" />
 | 
				
			||||
          <% end %>
 | 
				
			||||
        </td>
 | 
				
			||||
        <td><%= user.real_name %></td>
 | 
				
			||||
        <td><%= raw [user.school_name.presence, user.department_name.presence].compact.join('<br/>') %></td>
 | 
				
			||||
        <td><%= user.identity %> <%= raw user.user_extension.student? && user.student_id ? "<br/>#{user.student_id}" : '' %></td>
 | 
				
			||||
 | 
				
			||||
        <% unless is_processed %>
 | 
				
			||||
          <td>
 | 
				
			||||
            <% if File.exists?(disk_professional_auth_filename(user.id)) %>
 | 
				
			||||
              <%= image_tag(professional_auth_file_url(user.id).to_s + "?#{Time.now.to_i}", width: 40, height: 40, class: 'preview-image auth-image', data: { toggle: 'tooltip', title: '点击预览' }) %>
 | 
				
			||||
            <% else %>
 | 
				
			||||
              <%= content_tag(:span, '图片已删除', class: 'text-secondary') %>
 | 
				
			||||
            <% end %>
 | 
				
			||||
          </td>
 | 
				
			||||
        <% end %>
 | 
				
			||||
 | 
				
			||||
        <td><%= apply.updated_at.strftime('%Y-%m-%d %H:%M') %></td>
 | 
				
			||||
 | 
				
			||||
        <% if is_processed %>
 | 
				
			||||
          <td class="text-secondary"><%= overflow_hidden_span apply.remarks, width: 140 %></td>
 | 
				
			||||
          <td><span class="apply-status-<%= apply.status %>"><%= apply.status_text %></span></td>
 | 
				
			||||
        <% else %>
 | 
				
			||||
          <td class="action-container">
 | 
				
			||||
            <%= agree_link '同意', agree_admins_professional_authentication_path(apply, element: ".professional-authentication-#{apply.id}"), 'data-confirm': '确认审核通过?' %>
 | 
				
			||||
            <%= javascript_void_link('拒绝', class: 'action refuse-action',
 | 
				
			||||
                                     data: {
 | 
				
			||||
                                         toggle: 'modal', target: '.admin-common-refuse-modal', id: apply.id,
 | 
				
			||||
                                         url: refuse_admins_professional_authentication_path(apply, element: ".professional-authentication-#{apply.id}")
 | 
				
			||||
                                     }) %>
 | 
				
			||||
          </td>
 | 
				
			||||
        <% end %>
 | 
				
			||||
      </tr>
 | 
				
			||||
    <% end %>
 | 
				
			||||
  <% else %>
 | 
				
			||||
    <%= render 'admins/shared/no_data_for_table' %>
 | 
				
			||||
  <% end %>
 | 
				
			||||
  </tbody>
 | 
				
			||||
</table>
 | 
				
			||||
 | 
				
			||||
<%= render partial: 'admins/shared/paginate', locals: { objects: applies } %>
 | 
				
			||||
@ -1,3 +1,4 @@
 | 
				
			||||
;
 | 
				
			||||
$('[data-toggle="tooltip"]').tooltip();
 | 
				
			||||
$('[data-toggle="popover"]').popover();
 | 
				
			||||
$('[data-toggle="popover"]').popover();
 | 
				
			||||
$('img.preview-image').bootstrapViewer();
 | 
				
			||||
@ -0,0 +1,32 @@
 | 
				
			||||
<% define_admin_breadcrumbs do %>
 | 
				
			||||
  <% add_admin_breadcrumb('实训发布') %>
 | 
				
			||||
<% end %>
 | 
				
			||||
 | 
				
			||||
<div class="box search-form-container flex-column mb-0 pb-0 shixun-authorization-list-form">
 | 
				
			||||
  <ul class="nav nav-tabs w-100 search-form-tabs">
 | 
				
			||||
    <li class="nav-item">
 | 
				
			||||
      <%= link_to '待审批', admins_shixun_authorizations_path(status: :pending), remote: true, 'data-value': 'pending',
 | 
				
			||||
                  class: "nav-link search-form-tab #{params[:status] == 'pending' ? 'active' : ''}" %>
 | 
				
			||||
    </li>
 | 
				
			||||
    <li class="nav-item">
 | 
				
			||||
      <%= link_to '已审批', admins_shixun_authorizations_path(status: :processed), remote: true, 'data-value': 'processed',
 | 
				
			||||
                  class: "nav-link search-form-tab #{params[:status] != 'pending' ? 'active' : ''}" %>
 | 
				
			||||
    </li>
 | 
				
			||||
  </ul>
 | 
				
			||||
 | 
				
			||||
  <%= form_tag(admins_shixun_authorizations_path(unsafe_params), method: :get, class: 'form-inline search-form justify-content-end mt-3', remote: true) do %>
 | 
				
			||||
    <div class="form-group status-filter" style="<%= params[:status] != 'pending' ? '' : 'display: none;' %>">
 | 
				
			||||
      <label for="status">审核状态:</label>
 | 
				
			||||
      <% status_options = [['全部', 'processed'], ['已同意', 'agreed'], ['已拒绝', 'refused']] %>
 | 
				
			||||
      <%= select_tag(:status, options_for_select(status_options), class: 'form-control') %>
 | 
				
			||||
    </div>
 | 
				
			||||
    <%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: '实训名称检索') %>
 | 
				
			||||
    <%= submit_tag('搜索', class: 'btn btn-primary ml-3') %>
 | 
				
			||||
  <% end %>
 | 
				
			||||
</div>
 | 
				
			||||
 | 
				
			||||
<div class="box shixun-authorization-list-container">
 | 
				
			||||
  <%= render(partial: 'admins/shixun_authorizations/shared/list', locals: { applies: @applies, shixun_map: @shixun_map }) %>
 | 
				
			||||
</div>
 | 
				
			||||
 | 
				
			||||
<%= render(partial: 'admins/shared/admin_common_refuse_modal') %>
 | 
				
			||||
@ -0,0 +1 @@
 | 
				
			||||
$('.shixun-authorization-list-container').html("<%= j( render partial: 'admins/shixun_authorizations/shared/list', locals: { applies: @applies, shixun_map: @shixun_map } ) %>");
 | 
				
			||||
@ -0,0 +1,60 @@
 | 
				
			||||
<% is_processed = params[:status].to_s != 'pending' %>
 | 
				
			||||
 | 
				
			||||
<table class="table table-hover text-center shixun-authorization-list-table">
 | 
				
			||||
  <thead class="thead-light">
 | 
				
			||||
  <tr>
 | 
				
			||||
    <th width="8%">头像</th>
 | 
				
			||||
    <th width="14%">创建者</th>
 | 
				
			||||
    <th width="28%" class="text-left">实训名称</th>
 | 
				
			||||
    <th width="12%">任务数</th>
 | 
				
			||||
    <th width="16%">时间</th>
 | 
				
			||||
    <% if is_processed %>
 | 
				
			||||
      <th width="14%">拒绝原因</th>
 | 
				
			||||
      <th width="8%">状态</th>
 | 
				
			||||
    <% else %>
 | 
				
			||||
      <th width="22%">操作</th>
 | 
				
			||||
    <% end %>
 | 
				
			||||
  </tr>
 | 
				
			||||
  </thead>
 | 
				
			||||
  <tbody>
 | 
				
			||||
  <% if applies.present? %>
 | 
				
			||||
    <% applies.each do |apply| %>
 | 
				
			||||
      <% user = apply.user %>
 | 
				
			||||
      <% shixun = shixun_map[apply.container_id] %>
 | 
				
			||||
      <tr class="shixun-authorization-item shixun-authorization-<%= apply.id %>">
 | 
				
			||||
        <td>
 | 
				
			||||
          <%= link_to "/users/#{user.login}", class: 'shixun-authorization-avatar', target: '_blank', data: { toggle: 'tooltip', title: '个人主页' } do %>
 | 
				
			||||
            <img src="/images/<%= url_to_avatar(user) %>" class="rounded-circle" width="40" height="40" />
 | 
				
			||||
          <% end %>
 | 
				
			||||
        </td>
 | 
				
			||||
        <td><%= user.real_name %></td>
 | 
				
			||||
        <td class="text-left">
 | 
				
			||||
          <%= link_to "/shixuns/#{shixun.identifier}", target: '_blank' do %>
 | 
				
			||||
            <%= overflow_hidden_span shixun.name, width: 300 %>
 | 
				
			||||
          <% end %>
 | 
				
			||||
        </td>
 | 
				
			||||
        <td><%= shixun.challenges_count %></td>
 | 
				
			||||
        <td><%= apply.updated_at.strftime('%Y-%m-%d %H:%M') %></td>
 | 
				
			||||
 | 
				
			||||
        <% if is_processed %>
 | 
				
			||||
          <td class="text-secondary"><%= overflow_hidden_span apply.reason, width: 140 %></td>
 | 
				
			||||
          <td><span class="apply-status-<%= apply.status %>"><%= apply.status_text %></span></td>
 | 
				
			||||
        <% else %>
 | 
				
			||||
          <td class="action-container">
 | 
				
			||||
            <%= agree_link '同意', agree_admins_shixun_authorization_path(apply, element: ".shixun-authorization-#{apply.id}"), 'data-confirm': '确认审核通过?' %>
 | 
				
			||||
            <%= javascript_void_link('拒绝', class: 'action refuse-action',
 | 
				
			||||
                                     data: {
 | 
				
			||||
                                         toggle: 'modal', target: '.admin-common-refuse-modal', id: apply.id,
 | 
				
			||||
                                         url: refuse_admins_shixun_authorization_path(apply, element: ".shixun-authorization-#{apply.id}")
 | 
				
			||||
                                     }) %>
 | 
				
			||||
          </td>
 | 
				
			||||
        <% end %>
 | 
				
			||||
      </tr>
 | 
				
			||||
    <% end %>
 | 
				
			||||
  <% else %>
 | 
				
			||||
    <%= render 'admins/shared/no_data_for_table' %>
 | 
				
			||||
  <% end %>
 | 
				
			||||
  </tbody>
 | 
				
			||||
</table>
 | 
				
			||||
 | 
				
			||||
<%= render partial: 'admins/shared/paginate', locals: { objects: applies } %>
 | 
				
			||||
@ -0,0 +1,33 @@
 | 
				
			||||
<% define_admin_breadcrumbs do %>
 | 
				
			||||
  <% add_admin_breadcrumb('实践课程发布') %>
 | 
				
			||||
<% end %>
 | 
				
			||||
 | 
				
			||||
<div class="box search-form-container flex-column mb-0 pb-0 subject-authorization-list-form">
 | 
				
			||||
  <ul class="nav nav-tabs w-100 search-form-tabs">
 | 
				
			||||
    <li class="nav-item">
 | 
				
			||||
      <%= link_to '待审批', admins_subject_authorizations_path(status: :pending), remote: true, 'data-value': 'pending',
 | 
				
			||||
                  class: "nav-link search-form-tab #{params[:status] == 'pending' ? 'active' : ''}" %>
 | 
				
			||||
    </li>
 | 
				
			||||
    <li class="nav-item">
 | 
				
			||||
      <%= link_to '已审批', admins_subject_authorizations_path(status: :processed), remote: true, 'data-value': 'processed',
 | 
				
			||||
                  class: "nav-link search-form-tab #{params[:status] != 'pending' ? 'active' : ''}" %>
 | 
				
			||||
    </li>
 | 
				
			||||
  </ul>
 | 
				
			||||
 | 
				
			||||
  <%= form_tag(admins_subject_authorizations_path(unsafe_params), method: :get, class: 'form-inline search-form justify-content-end mt-3', remote: true) do %>
 | 
				
			||||
    <div class="form-group status-filter" style="<%= params[:status] != 'pending' ? '' : 'display: none;' %>">
 | 
				
			||||
      <label for="status">审核状态:</label>
 | 
				
			||||
      <% status_options = [['全部', 'processed'], ['已同意', 'agreed'], ['已拒绝', 'refused']] %>
 | 
				
			||||
      <%= select_tag(:status, options_for_select(status_options), class: 'form-control') %>
 | 
				
			||||
    </div>
 | 
				
			||||
    <%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: '实训课程名称检索') %>
 | 
				
			||||
    <%= submit_tag('搜索', class: 'btn btn-primary ml-3') %>
 | 
				
			||||
  <% end %>
 | 
				
			||||
</div>
 | 
				
			||||
 | 
				
			||||
<div class="box subject-authorization-list-container">
 | 
				
			||||
  <%= render(partial: 'admins/subject_authorizations/shared/list',
 | 
				
			||||
             locals: { applies: @applies, subject_map: @subject_map, challenge_count_map: @challenge_count_map }) %>
 | 
				
			||||
</div>
 | 
				
			||||
 | 
				
			||||
<%= render(partial: 'admins/shared/admin_common_refuse_modal') %>
 | 
				
			||||
@ -0,0 +1 @@
 | 
				
			||||
$('.subject-authorization-list-container').html("<%= j( render partial: 'admins/subject_authorizations/shared/list', locals: { applies: @applies, subject_map: @subject_map, challenge_count_map: @challenge_count_map } ) %>");
 | 
				
			||||
@ -0,0 +1,64 @@
 | 
				
			||||
<% is_processed = params[:status].to_s != 'pending' %>
 | 
				
			||||
 | 
				
			||||
<table class="table table-hover text-center subject-authorization-list-table">
 | 
				
			||||
  <thead class="thead-light">
 | 
				
			||||
  <tr>
 | 
				
			||||
    <th width="8%">头像</th>
 | 
				
			||||
    <th width="10%">创建者</th>
 | 
				
			||||
    <th width="28%" class="text-left">实践课程名称</th>
 | 
				
			||||
    <th width="6%">阶段数</th>
 | 
				
			||||
    <th width="6%">实训数</th>
 | 
				
			||||
    <th width="6%">关卡数</th>
 | 
				
			||||
    <th width="14%">时间</th>
 | 
				
			||||
    <% if is_processed %>
 | 
				
			||||
      <th width="14%">拒绝原因</th>
 | 
				
			||||
      <th width="8%">状态</th>
 | 
				
			||||
    <% else %>
 | 
				
			||||
      <th width="22%">操作</th>
 | 
				
			||||
    <% end %>
 | 
				
			||||
  </tr>
 | 
				
			||||
  </thead>
 | 
				
			||||
  <tbody>
 | 
				
			||||
  <% if applies.present? %>
 | 
				
			||||
    <% applies.each do |apply| %>
 | 
				
			||||
      <% user = apply.user %>
 | 
				
			||||
      <% subject = subject_map[apply.container_id] %>
 | 
				
			||||
      <tr class="subject-authorization-item subject-authorization-<%= apply.id %>">
 | 
				
			||||
        <td>
 | 
				
			||||
          <%= link_to "/users/#{user.login}", class: 'subject-authorization-avatar', target: '_blank', data: { toggle: 'tooltip', title: '个人主页' } do %>
 | 
				
			||||
            <img src="/images/<%= url_to_avatar(user) %>" class="rounded-circle" width="40" height="40" />
 | 
				
			||||
          <% end %>
 | 
				
			||||
        </td>
 | 
				
			||||
        <td><%= user.real_name %></td>
 | 
				
			||||
        <td class="text-left">
 | 
				
			||||
          <%= link_to "/paths/#{subject.id}", target: '_blank' do %>
 | 
				
			||||
            <%= overflow_hidden_span subject.name, width: 300 %>
 | 
				
			||||
          <% end %>
 | 
				
			||||
        </td>
 | 
				
			||||
        <td><%= subject.stages_count %></td>
 | 
				
			||||
        <td><%= subject.shixuns_count %></td>
 | 
				
			||||
        <td><%= challenge_count_map.fetch(subject.id, 0) %></td>
 | 
				
			||||
        <td><%= apply.updated_at.strftime('%Y-%m-%d %H:%M') %></td>
 | 
				
			||||
 | 
				
			||||
        <% if is_processed %>
 | 
				
			||||
          <td class="text-secondary"><%= overflow_hidden_span apply.reason, width: 140 %></td>
 | 
				
			||||
          <td><span class="apply-status-<%= apply.status %>"><%= apply.status_text %></span></td>
 | 
				
			||||
        <% else %>
 | 
				
			||||
          <td class="action-container">
 | 
				
			||||
            <%= agree_link '同意', agree_admins_subject_authorization_path(apply, element: ".subject-authorization-#{apply.id}"), 'data-confirm': '确认审核通过?' %>
 | 
				
			||||
            <%= javascript_void_link('拒绝', class: 'action refuse-action',
 | 
				
			||||
                                     data: {
 | 
				
			||||
                                         toggle: 'modal', target: '.admin-common-refuse-modal', id: apply.id,
 | 
				
			||||
                                         url: refuse_admins_subject_authorization_path(apply, element: ".subject-authorization-#{apply.id}")
 | 
				
			||||
                                     }) %>
 | 
				
			||||
          </td>
 | 
				
			||||
        <% end %>
 | 
				
			||||
      </tr>
 | 
				
			||||
    <% end %>
 | 
				
			||||
  <% else %>
 | 
				
			||||
    <%= render 'admins/shared/no_data_for_table' %>
 | 
				
			||||
  <% end %>
 | 
				
			||||
  </tbody>
 | 
				
			||||
</table>
 | 
				
			||||
 | 
				
			||||
<%= render partial: 'admins/shared/paginate', locals: { objects: applies } %>
 | 
				
			||||
@ -1 +1,5 @@
 | 
				
			||||
json.description @course.inform&.description
 | 
				
			||||
json.informs @informs do |inform|
 | 
				
			||||
  json.id inform.id
 | 
				
			||||
  json.name inform.name
 | 
				
			||||
  json.description inform.description
 | 
				
			||||
end
 | 
				
			||||
@ -0,0 +1,7 @@
 | 
				
			||||
zh-CN:
 | 
				
			||||
  apply_action:
 | 
				
			||||
    status:
 | 
				
			||||
      '0': '待处理'
 | 
				
			||||
      '1': '已同意'
 | 
				
			||||
      '2': '已拒绝'
 | 
				
			||||
      '3': '已撤销'
 | 
				
			||||
@ -0,0 +1,7 @@
 | 
				
			||||
zh-CN:
 | 
				
			||||
  apply_user_authentication:
 | 
				
			||||
    status:
 | 
				
			||||
      '0': '待处理'
 | 
				
			||||
      '1': '已同意'
 | 
				
			||||
      '2': '已拒绝'
 | 
				
			||||
      '3': '已撤销'
 | 
				
			||||
@ -1,4 +1,4 @@
 | 
				
			||||
class ChangeExericse1936Scores < ActiveRecord::Migration[5.2]
 | 
				
			||||
class RechangeExercise1936Scores < ActiveRecord::Migration[5.2]
 | 
				
			||||
  include ExercisesHelper
 | 
				
			||||
  def change
 | 
				
			||||
    #1936的试卷成绩有问题。
 | 
				
			||||
@ -0,0 +1,9 @@
 | 
				
			||||
class MigrateSubjectShixunCount < ActiveRecord::Migration[5.2]
 | 
				
			||||
  def change
 | 
				
			||||
    Subject.reset_column_information
 | 
				
			||||
    Subject.all.each do |subject|
 | 
				
			||||
      Subject.reset_counters subject.id, :stage_shixuns
 | 
				
			||||
      Subject.reset_counters subject.id, :shixuns
 | 
				
			||||
    end
 | 
				
			||||
  end
 | 
				
			||||
end
 | 
				
			||||
@ -0,0 +1 @@
 | 
				
			||||
{"files":{"admin-6575f1399953fb1935c037a7b8bd28c4aff07b70bed9b41faf6899a89af4b57d.js":{"logical_path":"admin.js","mtime":"2019-08-26T15:21:11+08:00","size":907839,"digest":"6575f1399953fb1935c037a7b8bd28c4aff07b70bed9b41faf6899a89af4b57d","integrity":"sha256-ZXXxOZlT+xk1wDenuL0oxK/we3C+2bQfr2iZqJr0tX0="},"admin-8a2b03cb8a055dc63f45443b304cae77382331beba55b1570b3d3c8aa42442d5.css":{"logical_path":"admin.css","mtime":"2019-08-26T15:21:47+08:00","size":655571,"digest":"8a2b03cb8a055dc63f45443b304cae77382331beba55b1570b3d3c8aa42442d5","integrity":"sha256-iisDy4oFXcY/RUQ7MEyudzgjMb66VbFXCz08iqQkQtU="},"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="},"logo-7ff112568709bf97f9898fe87249b7a8f200ff1f48d537d85af87215f1870423.png":{"logical_path":"logo.png","mtime":"2019-08-21T15:10:12+08:00","size":2816,"digest":"7ff112568709bf97f9898fe87249b7a8f200ff1f48d537d85af87215f1870423","integrity":"sha256-f/ESVocJv5f5iY/ockm3qPIA/x9I1TfYWvhyFfGHBCM="},"application-a3a4f3549d68670572bb07700c85a9ac11e536edc73fef6e7489723bf535e533.js":{"logical_path":"application.js","mtime":"2019-08-26T15:21:11+08:00","size":1042232,"digest":"a3a4f3549d68670572bb07700c85a9ac11e536edc73fef6e7489723bf535e533","integrity":"sha256-o6TzVJ1oZwVyuwdwDIWprBHlNu3HP+9udIlyO/U15TM="},"application-a7508b88eb6a69a5b301602bddc14745cec09853ea7d91c6fae856b96e788f46.css":{"logical_path":"application.css","mtime":"2019-08-26T15:21:47+08:00","size":1182859,"digest":"a7508b88eb6a69a5b301602bddc14745cec09853ea7d91c6fae856b96e788f46","integrity":"sha256-p1CLiOtqaaWzAWAr3cFHRc7AmFPqfZHG+uhWuW54j0Y="}},"assets":{"admin.js":"admin-6575f1399953fb1935c037a7b8bd28c4aff07b70bed9b41faf6899a89af4b57d.js","admin.css":"admin-8a2b03cb8a055dc63f45443b304cae77382331beba55b1570b3d3c8aa42442d5.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","logo.png":"logo-7ff112568709bf97f9898fe87249b7a8f200ff1f48d537d85af87215f1870423.png","application.js":"application-a3a4f3549d68670572bb07700c85a9ac11e536edc73fef6e7489723bf535e533.js","application.css":"application-a7508b88eb6a69a5b301602bddc14745cec09853ea7d91c6fae856b96e788f46.css"}}
 | 
				
			||||
											
												
													File diff suppressed because one or more lines are too long
												
											
										
									
								
											
												Binary file not shown.
											
										
									
								
											
												
													File diff suppressed because it is too large
													Load Diff
												
											
										
									
								
											
												Binary file not shown.
											
										
									
								
											
												
													File diff suppressed because one or more lines are too long
												
											
										
									
								
											
												Binary file not shown.
											
										
									
								
											
												
													File diff suppressed because it is too large
													Load Diff
												
											
										
									
								
											
												Binary file not shown.
											
										
									
								
											
												Binary file not shown.
											
										
									
								
											
												Binary file not shown.
											
										
									
								
											
												Binary file not shown.
											
										
									
								
											
												Binary file not shown.
											
										
									
								
											
												Binary file not shown.
											
										
									
								| 
		 After Width: | Height: | Size: 434 KiB  | 
											
												Binary file not shown.
											
										
									
								
											
												Binary file not shown.
											
										
									
								Some files were not shown because too many files have changed in this diff Show More
					Loading…
					
					
				
		Reference in new issue