diff --git a/app/assets/javascripts/admin.js b/app/assets/javascripts/admin.js index 7d1908547..ee85468c0 100644 --- a/app/assets/javascripts/admin.js +++ b/app/assets/javascripts/admin.js @@ -25,6 +25,12 @@ $.fn.select2.defaults.set('language', 'zh-CN'); Turbolinks.setProgressBarDelay(200); +$.notifyDefaults({ + type: 'success', + z_index: 9999, + delay: 2000 +}); + $(document).on('turbolinks:load', function(){ $('[data-toggle="tooltip"]').tooltip(); $('[data-toggle="popover"]').popover(); diff --git a/app/assets/javascripts/admins/departments/index.js b/app/assets/javascripts/admins/departments/index.js new file mode 100644 index 000000000..eb0fc3a6a --- /dev/null +++ b/app/assets/javascripts/admins/departments/index.js @@ -0,0 +1,173 @@ +$(document).on('turbolinks:load', function() { + if ($('body.admins-departments-index-page').length > 0) { + var $searchContainer = $('.department-list-form'); + var $searchForm = $searchContainer.find('form.search-form'); + var $list = $('.department-list-container'); + + $searchContainer.on('change', '.form-check-input', function(){ + $searchForm.find('input[type="submit"]').trigger('click'); + }); + + // ============== 新建部门 =============== + var $modal = $('.modal.admin-create-department-modal'); + var $form = $modal.find('form.admin-create-department-form'); + var $departmentNameInput = $form.find('input[name="department_name"]'); + var $schoolSelect = $modal.find('.school-select'); + + $form.validate({ + errorElement: 'span', + errorClass: 'danger text-danger', + rules: { + school_id: { + required: true + }, + department_name: { + required: true + } + }, + messages: { + school_id: { + required: '请选择所属单位' + } + } + }); + + // modal ready fire + $modal.on('show.bs.modal', function () { + $departmentNameInput.val(''); + $schoolSelect.select2('val', ' '); + }); + + // ************** 学校选择 ************* + var matcherFunc = function(params, data){ + if ($.trim(params.term) === '') { + return data; + } + if (typeof data.text === 'undefined') { + return null; + } + + if (data.name && data.name.indexOf(params.term) > -1) { + var modifiedData = $.extend({}, data, true); + return modifiedData; + } + + // Return `null` if the term should not be displayed + return null; + }; + + var defineSchoolSelect = function(schools) { + $schoolSelect.select2({ + theme: 'bootstrap4', + placeholder: '请选择所属单位', + minimumInputLength: 1, + data: schools, + templateResult: function (item) { + if(!item.id || item.id === '') return item.text; + return item.name; + }, + templateSelection: function(item){ + if (item.id) { + $('#school_id').val(item.id); + } + return item.name || item.text; + }, + matcher: matcherFunc + }); + } + + $.ajax({ + url: '/api/schools/for_option.json', + dataType: 'json', + type: 'GET', + success: function(data) { + defineSchoolSelect(data.schools); + } + }); + + $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); + } + }); + } + }); + + // ============= 添加部门管理员 ============== + var $addMemberModal = $('.admin-add-department-member-modal'); + var $addMemberForm = $addMemberModal.find('.admin-add-department-member-form'); + var $memberSelect = $addMemberModal.find('.department-member-select'); + var $departmentIdInput = $addMemberForm.find('input[name="department_id"]') + + $addMemberModal.on('show.bs.modal', function(event){ + var $link = $(event.relatedTarget); + var departmentId = $link.data('department-id'); + $departmentIdInput.val(departmentId); + + $memberSelect.select2('val', ' '); + }); + + $memberSelect.select2({ + theme: 'bootstrap4', + placeholder: '请输入要添加的管理员姓名', + multiple: true, + minimumInputLength: 1, + ajax: { + delay: 500, + url: '/admins/users', + dataType: 'json', + data: function(params){ + return { name: params.term }; + }, + processResults: function(data){ + return { results: data.users } + } + }, + templateResult: function (item) { + if(!item.id || item.id === '') return item.text; + return item.real_name; + }, + templateSelection: function(item){ + if (item.id) { + } + return item.real_name || item.text; + } + }); + + $addMemberModal.on('click', '.submit-btn', function(){ + $addMemberForm.find('.error').html(''); + + var departmentId = $departmentIdInput.val(); + var memberIds = $memberSelect.val(); + if (departmentId && memberIds && memberIds.length > 0) { + $.ajax({ + method: 'POST', + dataType: 'script', + url: '/admins/departments/' + departmentId + '/department_member', + data: { user_ids: memberIds } + }); + } else { + $addMemberModal.modal('hide'); + } + }); + } +}); \ No newline at end of file diff --git a/app/assets/javascripts/admins/modals/admin-edit-department-modal.js b/app/assets/javascripts/admins/modals/admin-edit-department-modal.js new file mode 100644 index 000000000..a1df01ba5 --- /dev/null +++ b/app/assets/javascripts/admins/modals/admin-edit-department-modal.js @@ -0,0 +1,34 @@ +$(document).on('turbolinks:load', function() { + $('.admin-modal-container').on('show.bs.modal', '.modal.admin-edit-department-modal', function(){ + var $modal = $('.modal.admin-edit-department-modal'); + var $form = $modal.find('form.admin-edit-department-form'); + + $form.validate({ + errorElement: 'span', + errorClass: 'danger text-danger', + rules: { + 'department[name]': { + required: true, + maxlength: 20 + }, + 'department[host_count]': { + digits: true + } + } + }); + + $modal.on('click', '.submit-btn', function(){ + $form.find('.error').html(''); + var url = $form.attr('action'); + + if ($form.valid()) { + $.ajax({ + method: 'PATCH', + dataType: 'script', + url: url, + data: $form.serialize() + }); + } + }); + }) +}); \ No newline at end of file diff --git a/app/assets/javascripts/admins/modals/admin-merge-department-modal.js b/app/assets/javascripts/admins/modals/admin-merge-department-modal.js new file mode 100644 index 000000000..aead3f485 --- /dev/null +++ b/app/assets/javascripts/admins/modals/admin-merge-department-modal.js @@ -0,0 +1,110 @@ +$(document).on('turbolinks:load', function() { + var $modal = $('.modal.admin-merge-department-modal'); + if ($modal.length > 0) { + var $form = $modal.find('form.admin-merge-department-form'); + var $schoolIdInput = $form.find('input[name="school_id"]'); + var $originDepartmentIdInput = $form.find('input[name="origin_department_id"]'); + var $departmentSelect = $modal.find('.department-select'); + + $form.validate({ + errorElement: 'span', + errorClass: 'danger text-danger', + rules: { + department_id: { + required: true + } + }, + messages: { + department_id: { + required: '请选择部门' + } + } + }); + + // ************** 学校选择 ************* + var matcherFunc = function(params, data){ + if ($.trim(params.term) === '') { + return data; + } + if (typeof data.text === 'undefined') { + return null; + } + + if (data.name && data.name.indexOf(params.term) > -1) { + var modifiedData = $.extend({}, data, true); + return modifiedData; + } + + // Return `null` if the term should not be displayed + return null; + }; + + var defineDepartmentSelect = function(departments) { + $departmentSelect.empty(); + + $departmentSelect.select2({ + theme: 'bootstrap4', + placeholder: '请选择所属部门', + data: departments, + templateResult: function (item) { + if(!item.id || item.id === '') return item.text; + return item.name; + }, + templateSelection: function(item){ + if (item.id) { + $form.find('#department_id').val(item.id); + } + return item.name || item.text; + }, + matcher: matcherFunc + }); + $departmentSelect.select2('val', ' '); + }; + + // modal ready fire + $modal.on('show.bs.modal', function (event) { + var $link = $(event.relatedTarget); + + var schoolId = $link.data('schoolId'); + + $schoolIdInput.val(schoolId); + $originDepartmentIdInput.val($link.data('departmentId')); + + $.ajax({ + url: '/api/schools/' + schoolId + '/departments/for_option.json', + dataType: 'json', + type: 'GET', + success: function(data) { + defineDepartmentSelect(data.departments); + } + }); + }); + + $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); + } + }); + } + }); + } +}); \ No newline at end of file diff --git a/app/assets/javascripts/admins/shixun_settings/shixun_settings.js b/app/assets/javascripts/admins/shixun_settings/shixun_settings.js index 9dd47337d..150d2cc8b 100644 --- a/app/assets/javascripts/admins/shixun_settings/shixun_settings.js +++ b/app/assets/javascripts/admins/shixun_settings/shixun_settings.js @@ -1,41 +1,33 @@ $(document).on('turbolinks:load', function() { if ($('body.admins-shixun-settings-index-page').length > 0) { + $(".shixun-settings-select").on("change", function () { + var s_value = $(this).val(); + var s_name = $(this).attr("name"); + var json = {}; + json[s_name] = s_value; + $.ajax({ + url: "/admins/shixun_settings", + type: "GET", + dataType:'script', + data: json + }) + }); + $(".shixun-setting-form").on("change",function () { + var s_id = $(this).attr("data-id"); + var s_value = $(this).val(); + var s_name = $(this).attr("name"); + var json = {}; + var s_index = $(this).parent("td").siblings(".shixun-line-no").text(); + json[s_name] = s_value; + json["page_no"] = s_index; + $.ajax({ + url: "/admins/shixun_settings/" + s_id, + type: "PUT", + dataType:'script', + data: json + }) + }) } }); -function update_change(target) { - var s_id = $(target).attr("data-id"); - var s_value = $(target).val(); - var s_name = $(target).attr("name"); - var json = {}; - var s_index = $(target).parent("td").siblings(".shixun-line-no").text(); - json[s_name] = s_value; - json["page_no"] = s_index; - $.ajax({ - url: "/admins/shixun_settings/" + s_id, - type: "PUT", - dataType:'script', - data: json, - success: function (data) { - - } - }) -} - - -function select_change(target) { - var s_value = $(target).val(); - var s_name = $(target).attr("name"); - var json = {}; - json[s_name] = s_value; - $.ajax({ - url: "/admins/shixun_settings/", - type: "GET", - dataType:'script', - data: json, - success: function (data) { - - } - }) -} \ No newline at end of file diff --git a/app/assets/stylesheets/admin.scss b/app/assets/stylesheets/admin.scss index 5378034f5..ec9c0fbc7 100644 --- a/app/assets/stylesheets/admin.scss +++ b/app/assets/stylesheets/admin.scss @@ -46,6 +46,10 @@ label.error { } } +input.form-control { + font-size: 14px; +} + .flex-1 { flex: 1; } diff --git a/app/assets/stylesheets/admins/departments.scss b/app/assets/stylesheets/admins/departments.scss new file mode 100644 index 000000000..7d9d078e5 --- /dev/null +++ b/app/assets/stylesheets/admins/departments.scss @@ -0,0 +1,24 @@ +.admins-departments-index-page { + .department-list-table { + .member-container { + .member-user { + display: flex; + justify-content: center; + flex-wrap: wrap; + + .member-user-item { + display: flex; + align-items: center; + height: 22px; + line-height: 22px; + padding: 2px 5px; + margin: 2px 2px; + border: 1px solid #91D5FF; + background-color: #E6F7FF; + color: #91D5FF; + border-radius: 4px; + } + } + } + } +} \ No newline at end of file diff --git a/app/assets/stylesheets/admins/shixun_settings.scss b/app/assets/stylesheets/admins/shixun_settings.scss index a6bba62b4..c38fc0c6d 100644 --- a/app/assets/stylesheets/admins/shixun_settings.scss +++ b/app/assets/stylesheets/admins/shixun_settings.scss @@ -6,4 +6,9 @@ input[type="checkbox"]{ } .select2 .select2-selection__choice{ border: 1px solid #eee !important; +} +.setting-chosen{ + font-weight: 400; + font-size: 10px; + color:#333; } \ No newline at end of file diff --git a/app/controllers/admins/department_members_controller.rb b/app/controllers/admins/department_members_controller.rb new file mode 100644 index 000000000..ba483acef --- /dev/null +++ b/app/controllers/admins/department_members_controller.rb @@ -0,0 +1,20 @@ +class Admins::DepartmentMembersController < Admins::BaseController + + helper_method :current_department + + def create + Admins::AddDepartmentMemberService.call(current_department, params) + current_department.reload + end + + def destroy + @member = current_department.department_members.find_by(user_id: params[:user_id]) + @member.destroy! if @member.present? + end + + private + + def current_department + @_current_department ||= Department.find(params[:department_id]) + end +end \ No newline at end of file diff --git a/app/controllers/admins/departments_controller.rb b/app/controllers/admins/departments_controller.rb new file mode 100644 index 000000000..ed7c3d3db --- /dev/null +++ b/app/controllers/admins/departments_controller.rb @@ -0,0 +1,95 @@ +class Admins::DepartmentsController < Admins::BaseController + + helper_method :current_department + + def index + params[:sort_by] ||= 'created_at' + params[:sort_direction] ||= 'desc' + + departments = Admins::DepartmentQuery.call(params) + + @departments = paginate departments.preload(:school, :member_users) + + department_ids = @departments.map(&:id) + @users_count = UserExtension.where(department_id: department_ids).group(:department_id).count + @professional_auth_count = UserExtension.where(department_id: department_ids) + .joins(:user).where(users: { professional_certification: true }) + .group(:department_id).count + end + + def create + department_name = params[:department_name].to_s.strip + school = School.find(params[:school_id]) + + return render_error('部门名称重复') if school.departments.exists?(name: department_name) + + ActiveRecord::Base.transaction do + department = school.departments.create!(name: department_name, is_auth: 1) + ApplyAddDepartment.create!(school_id: school.id, status: 1, name: department.name, + department_id: department.id, user_id: current_user.id) + end + + render_ok + end + + def edit + end + + def update + identifier = update_params.delete(:identifier).presence + if identifier && Department.where.not(id: current_department.id).exists?(identifier: identifier) + return render_error('统计链接重复', type: :notify) + end + + current_department.update!(update_params.merge(identifier: identifier)) + end + + def destroy + ActiveRecord::Base.transaction do + current_department.apply_add_departments.update_all(status: 2) + + user_ids = current_department.user_extensions.pluck(:user_id) + if user_ids.present? + DeleteDepartmentNotifyJob.perform_later(current_department.id, 0, user_ids) + current_department.soft_delete! + else + current_department.destroy! + end + end + + render_delete_success + end + + def merge + return render_error('请选择其它部门') if params[:origin_department_id].to_s == params[:department_id].to_s + + origin_department = Department.find(params[:origin_department_id]) + to_department = Department.find(params[:department_id]) + + return render_error('部门所属单位不相同') if origin_department.school_id != to_department.school_id + + ActiveRecord::Base.transaction do + origin_department.apply_add_departments.delete_all + + origin_department.user_extensions.update_all(department_id: to_department.id) + + if to_department.identifier.blank? && origin_department.identifier.present? + to_department.update!(identifier: origin_department.identifier) + end + + origin_department.destroy! + end + + render_ok + end + + private + + def current_department + @_current_department ||= Department.find(params[:id]) + end + + def update_params + params.require(:department).permit(:name, :identifier, :host_count) + end +end \ No newline at end of file diff --git a/app/controllers/admins/shixun_settings_controller.rb b/app/controllers/admins/shixun_settings_controller.rb index 42c78ef23..55b0381f1 100644 --- a/app/controllers/admins/shixun_settings_controller.rb +++ b/app/controllers/admins/shixun_settings_controller.rb @@ -9,8 +9,8 @@ class Admins::ShixunSettingsController < Admins::BaseController @pending_shixuns = shixun_settings.where(status:1).size @processed_shixuns = shixun_settings.where(status:2).size @closed_shixuns = shixun_settings.where(status:3).size - @shixuns_type_check = MirrorRepository.select(:id,:type_name).pluck(:type_name,:id) - @shixun_tags = TagRepertoire.order("name asc").select(:id,:name).pluck(:name,:id) + @shixuns_type_check = MirrorRepository.pluck(:type_name,:id) + @shixun_tags = TagRepertoire.order("name asc").pluck(:name,:id) @params_page = params[:page] || 1 @shixun_settings = paginate shixun_settings.preload(:user,:tag_repertoires) @@ -27,7 +27,7 @@ class Admins::ShixunSettingsController < Admins::BaseController def update @shixun = Shixun.find_by(id:params[:id]) @page_no = params[:page_no] || "1" - @shixun_tags = TagRepertoire.order("name asc").select(:id,:name).pluck(:name,:id) + @shixun_tags = TagRepertoire.order("name asc").pluck(:name,:id) tag_ids = params[:tag_repertoires] if tag_ids.present? @shixun&.shixun_tag_repertoires.delete_all @@ -38,26 +38,12 @@ class Admins::ShixunSettingsController < Admins::BaseController tag_repertoire.save end end - respond_to do |format| - format.js - format.json{ - render json: {status: 0} - } - end else - if @shixun.update_attributes(setting_params) - respond_to do |format| - format.js - format.json{ - render json: {status: 0} - } - end - else + unless @shixun.update_attributes(setting_params) redirect_to admins_shixun_settings_path flash[:danger] = "更新失败" end end - end private diff --git a/app/controllers/admins/shixuns_controller.rb b/app/controllers/admins/shixuns_controller.rb index 9b1ac9999..a4aa8a044 100644 --- a/app/controllers/admins/shixuns_controller.rb +++ b/app/controllers/admins/shixuns_controller.rb @@ -8,7 +8,7 @@ class Admins::ShixunsController < Admins::BaseController @pending_shixuns = shixuns.where(status:1).size @processed_shixuns = shixuns.where(status:2).size @closed_shixuns = shixuns.where(status:3).size - @shixuns_type_check = MirrorRepository.select(:id,:type_name).pluck(:type_name,:id) + @shixuns_type_check = MirrorRepository.pluck(:type_name,:id) @params_page = params[:page] || 1 @shixuns = paginate shixuns.preload(:user,:challenges) diff --git a/app/controllers/concerns/admins/render_helper.rb b/app/controllers/concerns/admins/render_helper.rb index 94b7c29cb..0f136b62d 100644 --- a/app/controllers/concerns/admins/render_helper.rb +++ b/app/controllers/concerns/admins/render_helper.rb @@ -17,9 +17,9 @@ module Admins::RenderHelper json: -> { render status: 404, json: { message: '资源未找到' } }) end - def render_unprocessable_entity(message) + def render_unprocessable_entity(message, type: :alert) render_by_format(html: -> { render 'admins/shared/422' }, - js: -> { render_js_error(message) }, + js: -> { render_js_error(message, type: type) }, json: -> { render status: 422, json: { message: message } }) end alias_method :render_error, :render_unprocessable_entity @@ -40,7 +40,11 @@ module Admins::RenderHelper end alias_method :render_success_js, :render_delete_success - def render_js_error(message) - render_js_template 'admins/shared/error', locals: { message: message } + def render_js_error(message, type: :alert) + if type == :notify + render js: "$.notify({ message: '#{message}' },{ type: 'danger', delay: 5000 });" + else + render_js_template 'admins/shared/error', locals: { message: message } + end end end \ No newline at end of file diff --git a/app/jobs/delete_department_notify_job.rb b/app/jobs/delete_department_notify_job.rb new file mode 100644 index 000000000..1da5e2e85 --- /dev/null +++ b/app/jobs/delete_department_notify_job.rb @@ -0,0 +1,21 @@ +# 删除部门 消息通知 +class DeleteDepartmentNotifyJob < ApplicationJob + queue_as :notify + + def perform(department_id, operator_id, user_ids) + department = Department.unscoped.find_by(id: department_id) + return if department.blank? || user_ids.blank? + + attrs = %i[ user_id trigger_user_id container_id container_type tiding_type status created_at updated_at] + + same_attrs = { + trigger_user_id: operator_id, container_id: department.id, container_type: 'Department', + status: 4, tiding_type: 'System' + } + Tiding.bulk_insert(*attrs) do |worker| + user_ids.each do |user_id| + worker.add same_attrs.merge(user_id: user_id) + end + end + end +end diff --git a/app/models/department.rb b/app/models/department.rb index 9c4a0908b..1923cfb33 100644 --- a/app/models/department.rb +++ b/app/models/department.rb @@ -2,6 +2,14 @@ class Department < ApplicationRecord belongs_to :school has_many :department_members, dependent: :destroy + has_many :member_users, through: :department_members, source: :user + + has_many :user_extensions, dependent: :nullify + has_many :apply_add_departments scope :without_deleted, -> { where(is_delete: false) } + + def soft_delete! + update!(is_delete: true) + end end diff --git a/app/queries/admins/department_query.rb b/app/queries/admins/department_query.rb new file mode 100644 index 000000000..b0b5d0118 --- /dev/null +++ b/app/queries/admins/department_query.rb @@ -0,0 +1,32 @@ +class Admins::DepartmentQuery < ApplicationQuery + include CustomSortable + + attr_reader :params + + sort_columns :created_at, default_by: :created_at, default_direction: :desc + + def initialize(params) + @params = params + end + + def call + departments = Department.where(is_auth: true).without_deleted + + keyword = params[:keyword].to_s.strip + if keyword.present? + departments = departments.joins(:school) + .where('schools.name LIKE :keyword OR departments.name LIKE :keyword', keyword: keyword) + end + + if params[:with_member].to_s == 'true' + subquery = DepartmentMember.where('department_id = departments.id').select('1 AS one').to_sql + departments = departments.where("EXISTS(#{subquery})") + end + + if params[:with_identifier].to_s == 'true' + departments = departments.where.not(identifier: nil).where.not(identifier: '') + end + + custom_sort(departments, params[:sort_by], params[:sort_direction]) + end +end \ No newline at end of file diff --git a/app/queries/admins/user_query.rb b/app/queries/admins/user_query.rb index 5a633f059..75e50fc1b 100644 --- a/app/queries/admins/user_query.rb +++ b/app/queries/admins/user_query.rb @@ -28,7 +28,13 @@ class Admins::UserQuery < ApplicationQuery keyword = params[:keyword].to_s.strip.presence if keyword sql = 'CONCAT(lastname, firstname) LIKE :keyword OR login LIKE :keyword OR mail LIKE :keyword OR phone LIKE :keyword' - users = users.where(sql, keyword: keyword) + users = users.where(sql, keyword: "%#{keyword}%") + end + + # 姓名 + name = params[:name].to_s.strip.presence + if name.present? + users = users.where('CONCAT(lastname, firstname) LIKE :name', name: "%#{name}%") end # 学校名称 diff --git a/app/services/admins/add_department_member_service.rb b/app/services/admins/add_department_member_service.rb new file mode 100644 index 000000000..f8331cf4a --- /dev/null +++ b/app/services/admins/add_department_member_service.rb @@ -0,0 +1,20 @@ +class Admins::AddDepartmentMemberService < ApplicationService + + attr_reader :department, :params + + def initialize(department, params) + @department = department + @params = params + end + + def call + columns = %i[] + DepartmentMember.bulk_insert(*columns) do |worker| + Array.wrap(params[:user_ids]).compact.each do |user_id| + next if department.department_members.exists?(user_id: user_id) + + worker.add(department_id: department.id, user_id: user_id) + end + end + end +end \ No newline at end of file diff --git a/app/views/admins/daily_school_statistics/index.html.erb b/app/views/admins/daily_school_statistics/index.html.erb index 054e06fc6..39dcba633 100644 --- a/app/views/admins/daily_school_statistics/index.html.erb +++ b/app/views/admins/daily_school_statistics/index.html.erb @@ -5,7 +5,7 @@
<%= form_tag(admins_daily_school_statistics_path, method: :get, class: 'form-inline search-form', remote: true) do %> <%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: 'ID/单位名称搜索') %> - <%= submit_tag('搜索', class: 'btn btn-primary ml-3') %> + <%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %> <% end %> <%#= link_to '导出Excel', export_admins_daily_school_statistics_path(format: :xlsx), class: 'btn btn-outline-primary export-action' %> diff --git a/app/views/admins/department_members/create.js.erb b/app/views/admins/department_members/create.js.erb new file mode 100644 index 000000000..4355c7432 --- /dev/null +++ b/app/views/admins/department_members/create.js.erb @@ -0,0 +1,4 @@ +$('.modal.admin-add-department-member-modal').modal('hide'); +$.notify({ message: '操作成功' }); + +$('.department-list-table .department-item-<%= current_department.id %>').html("<%= j(render partial: 'admins/departments/shared/department_item', locals: { department: current_department }) %>") \ No newline at end of file diff --git a/app/views/admins/department_members/destroy.js.erb b/app/views/admins/department_members/destroy.js.erb new file mode 100644 index 000000000..d3eb3755b --- /dev/null +++ b/app/views/admins/department_members/destroy.js.erb @@ -0,0 +1,2 @@ +$.notify({ message: '操作成功' }); +$('.department-list-container .department-item-<%= current_department.id %> .member-user-item-<%= @member.user_id %>').remove(); \ No newline at end of file diff --git a/app/views/admins/departments/edit.js.erb b/app/views/admins/departments/edit.js.erb new file mode 100644 index 000000000..dc86d3ae0 --- /dev/null +++ b/app/views/admins/departments/edit.js.erb @@ -0,0 +1,2 @@ +$('.admin-modal-container').html("<%= j( render partial: 'admins/departments/shared/edit_department_modal', locals: { department: current_department } ) %>"); +$('.modal.admin-edit-department-modal').modal('show'); \ No newline at end of file diff --git a/app/views/admins/departments/index.html.erb b/app/views/admins/departments/index.html.erb new file mode 100644 index 000000000..54ca47252 --- /dev/null +++ b/app/views/admins/departments/index.html.erb @@ -0,0 +1,33 @@ +<% define_admin_breadcrumbs do %> + <% add_admin_breadcrumb('部门列表') %> +<% end %> + +
+ <%= form_tag(admins_departments_path, method: :get, class: 'form-inline search-form flex-1', remote: true) do %> +
+ <%= hidden_field_tag(:with_member, false) %> + <%= check_box_tag(:with_member, true, params[:with_member].to_s == 'true', class: 'form-check-input') %> + +
+ +
+ <%= hidden_field_tag(:with_identifier, false) %> + <%= check_box_tag(:with_identifier, true, params[:with_identifier].to_s == 'true', class: 'form-check-input') %> + +
+ + <%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: '部门/单位名称检索') %> + <%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %> + <% end %> + + <%= javascript_void_link '新建部门', class: 'btn btn-primary', data: { toggle: 'modal', target: '.admin-create-department-modal' } %> +
+ +
+ <%= render partial: 'admins/departments/shared/list', + locals: { departments: @departments, users_count: @users_count, professional_auth_count: @professional_auth_count } %> +
+ +<%= render 'admins/departments/shared/create_department_modal' %> +<%= render 'admins/departments/shared/add_department_member_modal' %> +<%= render 'admins/departments/shared/merge_department_modal' %> \ No newline at end of file diff --git a/app/views/admins/departments/index.js.erb b/app/views/admins/departments/index.js.erb new file mode 100644 index 000000000..bd2e4b25d --- /dev/null +++ b/app/views/admins/departments/index.js.erb @@ -0,0 +1 @@ +$('.department-list-container').html("<%= j(render partial: 'admins/departments/shared/list', locals: { departments: @departments, users_count: @users_count, professional_auth_count: @professional_auth_count }) %>"); \ No newline at end of file diff --git a/app/views/admins/departments/shared/_add_department_member_modal.html.erb b/app/views/admins/departments/shared/_add_department_member_modal.html.erb new file mode 100644 index 000000000..5d2707222 --- /dev/null +++ b/app/views/admins/departments/shared/_add_department_member_modal.html.erb @@ -0,0 +1,30 @@ + \ No newline at end of file diff --git a/app/views/admins/departments/shared/_create_department_modal.html.erb b/app/views/admins/departments/shared/_create_department_modal.html.erb new file mode 100644 index 000000000..ae6605eb8 --- /dev/null +++ b/app/views/admins/departments/shared/_create_department_modal.html.erb @@ -0,0 +1,35 @@ + \ No newline at end of file diff --git a/app/views/admins/departments/shared/_department_item.html.erb b/app/views/admins/departments/shared/_department_item.html.erb new file mode 100644 index 000000000..2f39d6248 --- /dev/null +++ b/app/views/admins/departments/shared/_department_item.html.erb @@ -0,0 +1,28 @@ +<% not_list = defined?(:users_count) %> + +<%= overflow_hidden_span department.name, width: 150 %> +<%= overflow_hidden_span department.school.name, width: 150 %> + +<% if not_list %> + <%= department.user_extensions.count %> + <%= department.user_extensions.joins(:user).where(users: { professional_certification: true }).count %> +<% else %> + <%= users_count.fetch(department.id, 0) %> + <%= professional_auth_count.fetch(department.id, 0) %> +<% end %> + + + <%= render partial: 'admins/departments/shared/member_users', locals: { department: department } %> + +<%= link_to department.identifier.to_s, '#', target: '_blank' %> +<%= department.host_count %> +<%= department.created_at&.strftime('%Y-%m-%d %H:%M') %> + + <%= link_to '编辑', edit_admins_department_path(department), remote: true, class: 'action' %> + + <%= javascript_void_link '添加管理员', class: 'action', data: { department_id: department.id, toggle: 'modal', target: '.admin-add-department-member-modal' } %> + + <%= javascript_void_link '更改', class: 'action', data: { school_id: department.school_id, department_id: department.id, toggle: 'modal', target: '.admin-merge-department-modal' } %> + + <%= delete_link '删除', admins_department_path(department, element: ".department-item-#{department.id}"), class: 'delete-department-action' %> + \ No newline at end of file diff --git a/app/views/admins/departments/shared/_edit_department_modal.html.erb b/app/views/admins/departments/shared/_edit_department_modal.html.erb new file mode 100644 index 000000000..38b43bbce --- /dev/null +++ b/app/views/admins/departments/shared/_edit_department_modal.html.erb @@ -0,0 +1,25 @@ + \ No newline at end of file diff --git a/app/views/admins/departments/shared/_list.html.erb b/app/views/admins/departments/shared/_list.html.erb new file mode 100644 index 000000000..6af63d6f4 --- /dev/null +++ b/app/views/admins/departments/shared/_list.html.erb @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + <% if departments.present? %> + <% departments.each do |department| %> + + <%= render 'admins/departments/shared/department_item', department: department %> + + <% end %> + <% else %> + <%= render 'admins/shared/no_data_for_table' %> + <% end %> + +
部门名称单位名称用户数已职业认证部门管理员统计链接云主机数<%= sort_tag('创建时间', name: 'created_at', path: admins_departments_path) %>操作
+ +<%= render partial: 'admins/shared/paginate', locals: { objects: departments } %> \ No newline at end of file diff --git a/app/views/admins/departments/shared/_member_users.html.erb b/app/views/admins/departments/shared/_member_users.html.erb new file mode 100644 index 000000000..8d4d466db --- /dev/null +++ b/app/views/admins/departments/shared/_member_users.html.erb @@ -0,0 +1,12 @@ +
+ <% department.member_users.each do |user| %> + + <%= link_to user.real_name, "/users/#{user.login}", target: '_blank', data: { toggle: 'tooltip', title: '个人主页' } %> + <%= link_to(admins_department_department_member_path(department, user_id: user.id), + method: :delete, remote: true, class: 'ml-1 delete-member-action', + data: { confirm: '确认删除吗?' }) do %> + + <% end %> + + <% end %> +
\ No newline at end of file diff --git a/app/views/admins/departments/shared/_merge_department_modal.html.erb b/app/views/admins/departments/shared/_merge_department_modal.html.erb new file mode 100644 index 000000000..200e75ccd --- /dev/null +++ b/app/views/admins/departments/shared/_merge_department_modal.html.erb @@ -0,0 +1,31 @@ + \ No newline at end of file diff --git a/app/views/admins/departments/update.js.erb b/app/views/admins/departments/update.js.erb new file mode 100644 index 000000000..359bac59c --- /dev/null +++ b/app/views/admins/departments/update.js.erb @@ -0,0 +1,4 @@ +$('.modal.admin-edit-department-modal').modal('hide'); +$.notify({ message: '操作成功' }); + +$('.department-list-table .department-item-<%= current_department.id %>').html("<%= j(render partial: 'admins/departments/shared/department_item', locals: { department: current_department }) %>") \ No newline at end of file diff --git a/app/views/admins/identity_authentications/index.html.erb b/app/views/admins/identity_authentications/index.html.erb index 170a8fc4a..38b7dfd63 100644 --- a/app/views/admins/identity_authentications/index.html.erb +++ b/app/views/admins/identity_authentications/index.html.erb @@ -21,7 +21,7 @@ <%= select_tag(:status, options_for_select(status_options), class: 'form-control') %>
<%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: '姓名/学校/单位检索') %> - <%= submit_tag('搜索', class: 'btn btn-primary ml-3') %> + <%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %> <% end %> diff --git a/app/views/admins/professional_authentications/index.html.erb b/app/views/admins/professional_authentications/index.html.erb index e10d2bd80..32eaa47bd 100644 --- a/app/views/admins/professional_authentications/index.html.erb +++ b/app/views/admins/professional_authentications/index.html.erb @@ -21,7 +21,7 @@ <%= select_tag(:status, options_for_select(status_options), class: 'form-control') %> <%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: '姓名/学校/单位检索') %> - <%= submit_tag('搜索', class: 'btn btn-primary ml-3') %> + <%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %> <% end %> diff --git a/app/views/admins/shared/_sidebar.html.erb b/app/views/admins/shared/_sidebar.html.erb index bbf29e8c8..499b14d23 100644 --- a/app/views/admins/shared/_sidebar.html.erb +++ b/app/views/admins/shared/_sidebar.html.erb @@ -28,6 +28,12 @@ <% end %> +
  • + <%= sidebar_item_group('#schools-submenu', '单位管理', icon: 'building') do %> +
  • <%= sidebar_item(admins_departments_path, '部门列表', icon: 'sitemap', controller: 'admins-departments') %>
  • + <% end %> + + <%#= sidebar_item_group('#course-submenu', '课堂+', icon: 'mortar-board') do %> diff --git a/app/views/admins/shixun_authorizations/index.html.erb b/app/views/admins/shixun_authorizations/index.html.erb index 743f2e1b2..3aaa1ce89 100644 --- a/app/views/admins/shixun_authorizations/index.html.erb +++ b/app/views/admins/shixun_authorizations/index.html.erb @@ -21,7 +21,7 @@ <%= select_tag(:status, options_for_select(status_options), class: 'form-control') %> <%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: '实训名称检索') %> - <%= submit_tag('搜索', class: 'btn btn-primary ml-3') %> + <%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %> <% end %> diff --git a/app/views/admins/shixun_settings/index.html.erb b/app/views/admins/shixun_settings/index.html.erb index aa8ff8874..939ed7d72 100644 --- a/app/views/admins/shixun_settings/index.html.erb +++ b/app/views/admins/shixun_settings/index.html.erb @@ -31,37 +31,37 @@
    diff --git a/app/views/admins/shixun_settings/shared/_list.html.erb b/app/views/admins/shixun_settings/shared/_list.html.erb index 62c67a1ad..14a97d002 100644 --- a/app/views/admins/shixun_settings/shared/_list.html.erb +++ b/app/views/admins/shixun_settings/shared/_list.html.erb @@ -5,7 +5,7 @@ 实训名称 技术平台 权限 - 技术体系 + 技术体系 上传图片 创建者 关闭 @@ -13,6 +13,9 @@ 代码执行时间 操作 +
    + ssh/隐藏/首页/跳关/隐藏目录 +
    diff --git a/app/views/admins/shixun_settings/shared/_td.html.erb b/app/views/admins/shixun_settings/shared/_td.html.erb index a4276f023..8523b682b 100644 --- a/app/views/admins/shixun_settings/shared/_td.html.erb +++ b/app/views/admins/shixun_settings/shared/_td.html.erb @@ -2,7 +2,7 @@ <%= shixun.identifier %> - <%= link_to overflow_hidden_span(shixun.name,width:150), "/shixuns/#{shixun.identifier}", :target => "_blank", :title => shixun.name %> + <%= link_to overflow_hidden_span(shixun.name,width:160), "/shixuns/#{shixun.identifier}", :target => "_blank", :title => shixun.name %> @@ -10,10 +10,10 @@ <% status_options = [['超级管理员', '0'], ["合作团队", "1"]] %> - <%= select_tag(:use_scope, options_for_select(status_options,shixun.use_scope),class:"form-control shixun-setting-form",data:{id:shixun.id},onchange:"update_change(this)") %> + <%= select_tag(:use_scope, options_for_select(status_options,shixun.use_scope),class:"form-control shixun-setting-form",data:{id:shixun.id}) %> - <%= select_tag(:tag_repertoires, options_for_select(@shixun_tags,shixun.tag_repertoires.pluck(:id)),multiple:true,class:"form-control tags-selected_multi",data:{id:shixun.id},onchange: "update_change(this)",id:"tags-chosen-#{shixun.id}") %> + <%= select_tag(:tag_repertoires, options_for_select(@shixun_tags,shixun.tag_repertoires.pluck(:id)),multiple:true,class:"form-control shixun-setting-form",data:{id:shixun.id},id:"tags-chosen-#{shixun.id}") %> @@ -37,22 +37,22 @@ <% end %> - <%= check_box_tag :can_copy,!shixun.can_copy,shixun.can_copy,remote:true,data:{id:shixun.id},onchange:"update_change(this)" %> + <%= check_box_tag :can_copy,!shixun.can_copy,shixun.can_copy,remote:true,data:{id:shixun.id},class:"shixun-setting-form" %> - + - <%= check_box_tag :webssh,(shixun.webssh == 1 ? 0 : 1),(shixun.webssh == 1 ? true : false),remote:true,data:{id:shixun.id,toggle:"tooltip",placement:"top"},onchange:"update_change(this)",title:"ssh" %> - <%= check_box_tag :hidden,!shixun.hidden,shixun.hidden,remote:true,data:{id:shixun.id,toggle:"tooltip",placement:"top"},onchange:"update_change(this)" ,title:"隐藏"%> - <%= check_box_tag :homepage_show,!shixun.homepage_show,shixun.homepage_show,remote:true,data:{id:shixun.id,toggle:"tooltip",placement:"top"},onchange:"update_change(this)",title:"首页" %> - <%= check_box_tag :task_pass,!shixun.task_pass,shixun.task_pass,remote:true,data:{id:shixun.id,toggle:"tooltip",placement:"top"},onchange:"update_change(this)" ,title:"跳关"%> - <%= check_box_tag :code_hidden,!shixun.code_hidden,shixun.code_hidden,remote:true,data:{id:shixun.id,toggle:"tooltip",placement:"top"},onchange:"update_change(this)" ,title:"隐藏文件目录"%> + <%= check_box_tag :webssh,(shixun.webssh == 1 ? 0 : 1),(shixun.webssh == 1 ? true : false),remote:true,data:{id:shixun.id,toggle:"tooltip",placement:"top"},class:"shixun-setting-form",title:"ssh" %> + <%= check_box_tag :hidden,!shixun.hidden,shixun.hidden,remote:true,data:{id:shixun.id,toggle:"tooltip",placement:"top"},class:"shixun-setting-form" ,title:"隐藏"%> + <%= check_box_tag :homepage_show,!shixun.homepage_show,shixun.homepage_show,remote:true,data:{id:shixun.id,toggle:"tooltip",placement:"top"},class:"shixun-setting-form",title:"首页" %> + <%= check_box_tag :task_pass,!shixun.task_pass,shixun.task_pass,remote:true,data:{id:shixun.id,toggle:"tooltip",placement:"top"},class:"shixun-setting-form" ,title:"跳关"%> + <%= check_box_tag :code_hidden,!shixun.code_hidden,shixun.code_hidden,remote:true,data:{id:shixun.id,toggle:"tooltip",placement:"top"},class:"shixun-setting-form" ,title:"隐藏目录"%> - - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/app/views/admins/subject_authorizations/index.html.erb b/app/views/admins/subject_authorizations/index.html.erb index 3d5539663..522278a3d 100644 --- a/app/views/admins/subject_authorizations/index.html.erb +++ b/app/views/admins/subject_authorizations/index.html.erb @@ -21,7 +21,7 @@ <%= select_tag(:status, options_for_select(status_options), class: 'form-control') %>
    <%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: '实训课程名称检索') %> - <%= submit_tag('搜索', class: 'btn btn-primary ml-3') %> + <%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %> <% end %> diff --git a/app/views/admins/users/index.html.erb b/app/views/admins/users/index.html.erb index 5d2af36c3..b145edd24 100644 --- a/app/views/admins/users/index.html.erb +++ b/app/views/admins/users/index.html.erb @@ -24,7 +24,7 @@ <%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: 'ID/姓名/邮箱/手机号检索') %> <%= text_field_tag(:school_name, params[:school_name], class: 'form-control col-sm-2', placeholder: '学校/单位检索') %> - <%= submit_tag('搜索', class: 'btn btn-primary ml-3') %> + <%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %> <% end %> diff --git a/app/views/admins/users/index.json.jbuilder b/app/views/admins/users/index.json.jbuilder new file mode 100644 index 000000000..5591474a4 --- /dev/null +++ b/app/views/admins/users/index.json.jbuilder @@ -0,0 +1,6 @@ +json.count @users.total_count +json.users do + json.array! @users.each do |user| + json.extract! user, :id, :login, :real_name, :identity, :school_name + end +end \ No newline at end of file diff --git a/app/views/admins/users/shared/_reward_grade_modal.html.erb b/app/views/admins/users/shared/_reward_grade_modal.html.erb index 87c74c499..2cf741906 100644 --- a/app/views/admins/users/shared/_reward_grade_modal.html.erb +++ b/app/views/admins/users/shared/_reward_grade_modal.html.erb @@ -2,7 +2,7 @@