实训配置的修改

dev_aliyun_beta
SylorHuang 6 years ago
commit f167f1ea4b

@ -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();

@ -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');
}
});
}
});

@ -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()
});
}
});
})
});

@ -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);
}
});
}
});
}
});

@ -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) {
}
})
}

@ -46,6 +46,10 @@ label.error {
}
}
input.form-control {
font-size: 14px;
}
.flex-1 {
flex: 1;
}

@ -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;
}
}
}
}
}

@ -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;
}

@ -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

@ -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

@ -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

@ -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)

@ -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

@ -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

@ -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

@ -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

@ -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
# 学校名称

@ -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

@ -5,7 +5,7 @@
<div class="box search-form-container daily-school-statistic-list-form">
<%= 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' %>

@ -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 }) %>")

@ -0,0 +1,2 @@
$.notify({ message: '操作成功' });
$('.department-list-container .department-item-<%= current_department.id %> .member-user-item-<%= @member.user_id %>').remove();

@ -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');

@ -0,0 +1,33 @@
<% define_admin_breadcrumbs do %>
<% add_admin_breadcrumb('部门列表') %>
<% end %>
<div class="box search-form-container department-list-form">
<%= form_tag(admins_departments_path, method: :get, class: 'form-inline search-form flex-1', remote: true) do %>
<div class="form-check mr-3">
<%= hidden_field_tag(:with_member, false) %>
<%= check_box_tag(:with_member, true, params[:with_member].to_s == 'true', class: 'form-check-input') %>
<label class="form-check-label" for="with_member">有部门管理员</label>
</div>
<div class="form-check mr-3">
<%= hidden_field_tag(:with_identifier, false) %>
<%= check_box_tag(:with_identifier, true, params[:with_identifier].to_s == 'true', class: 'form-check-input') %>
<label class="form-check-label" for="with_member">有统计链接</label>
</div>
<%= 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' } %>
</div>
<div class="box department-list-container">
<%= render partial: 'admins/departments/shared/list',
locals: { departments: @departments, users_count: @users_count, professional_auth_count: @professional_auth_count } %>
</div>
<%= render 'admins/departments/shared/create_department_modal' %>
<%= render 'admins/departments/shared/add_department_member_modal' %>
<%= render 'admins/departments/shared/merge_department_modal' %>

@ -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 }) %>");

@ -0,0 +1,30 @@
<div class="modal fade admin-add-department-member-modal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">添加部门管理员</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<form class="admin-add-department-member-form">
<%= hidden_field_tag(:department_id, nil) %>
<div class="form-group d-flex">
<label for="school_id" class="col-form-label">部门管理员:</label>
<div class="d-flex flex-column-reverse w-75">
<select id="user_ids" name="user_ids" class="form-control department-member-select"></select>
</div>
</div>
<div class="error text-danger"></div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary submit-btn">确认</button>
</div>
</div>
</div>
</div>

@ -0,0 +1,35 @@
<div class="modal fade admin-create-department-modal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">新建部门</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<form class="admin-create-department-form" data-url="<%= admins_departments_path %>">
<div class="form-group d-flex">
<label for="school_id" class="col-form-label">所属单位:</label>
<div class="d-flex flex-column-reverse w-75">
<select id="school_id" name="school_id" class="form-control school-select"></select>
</div>
</div>
<div class="form-group d-flex">
<label for="new_mirror_id" class="col-form-label">部门名称:</label>
<div class="w-75 d-flex flex-column">
<%= text_field_tag(:department_name, nil, class: 'form-control', placeholder: '请输入部门名称') %>
</div>
</div>
<div class="error text-danger"></div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary submit-btn">确认</button>
</div>
</div>
</div>
</div>

@ -0,0 +1,28 @@
<% not_list = defined?(:users_count) %>
<td class="text-left"><%= overflow_hidden_span department.name, width: 150 %></td>
<td class="text-left"><%= overflow_hidden_span department.school.name, width: 150 %></td>
<% if not_list %>
<td><%= department.user_extensions.count %></td>
<td><%= department.user_extensions.joins(:user).where(users: { professional_certification: true }).count %></td>
<% else %>
<td><%= users_count.fetch(department.id, 0) %></td>
<td><%= professional_auth_count.fetch(department.id, 0) %></td>
<% end %>
<td class="member-container">
<%= render partial: 'admins/departments/shared/member_users', locals: { department: department } %>
</td>
<td><%= link_to department.identifier.to_s, '#', target: '_blank' %></td>
<td><%= department.host_count %></td>
<td><%= department.created_at&.strftime('%Y-%m-%d %H:%M') %></td>
<td class="action-container">
<%= 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' %>
</td>

@ -0,0 +1,25 @@
<div class="modal fade admin-edit-department-modal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">编辑部门信息</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<%= simple_form_for([:admins, department], html: { class: 'admin-edit-department-form' }, defaults: { wrapper_html: { class: 'offset-md-1 col-md-10' } }) do |f| %>
<%= f.input :name, as: :string, label: '名称' %>
<%= f.input :identifier, as: :string, label: '统计链接' %>
<%= f.input :host_count, as: :integer, label: '云主机数' %>
<div class="error text-danger"></div>
<% end %>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary submit-btn">确认</button>
</div>
</div>
</div>
</div>

@ -0,0 +1,28 @@
<table class="table table-hover text-center department-list-table">
<thead class="thead-light">
<tr>
<th width="14%" class="text-left">部门名称</th>
<th width="14%" class="text-left">单位名称</th>
<th width="6%">用户数</th>
<th width="10%">已职业认证</th>
<th width="20%">部门管理员</th>
<th width="8%">统计链接</th>
<th width="8%">云主机数</th>
<th width="10%"><%= sort_tag('创建时间', name: 'created_at', path: admins_departments_path) %></th>
<th width="14%">操作</th>
</tr>
</thead>
<tbody>
<% if departments.present? %>
<% departments.each do |department| %>
<tr class="department-item-<%= department.id %>">
<%= render 'admins/departments/shared/department_item', department: department %>
</tr>
<% end %>
<% else %>
<%= render 'admins/shared/no_data_for_table' %>
<% end %>
</tbody>
</table>
<%= render partial: 'admins/shared/paginate', locals: { objects: departments } %>

@ -0,0 +1,12 @@
<div class="member-user">
<% department.member_users.each do |user| %>
<span class="member-user-item member-user-item-<%= user.id %>">
<%= 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 %>
<i class="fa fa-close"></i>
<% end %>
</span>
<% end %>
</div>

@ -0,0 +1,31 @@
<div class="modal fade admin-merge-department-modal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">更改部门</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<form class="admin-merge-department-form" data-url="<%= merge_admins_departments_path %>">
<%= hidden_field_tag(:school_id, nil) %>
<%= hidden_field_tag(:origin_department_id, nil) %>
<div class="form-group d-flex">
<label for="school_id" class="col-form-label">更改为:</label>
<div class="d-flex flex-column-reverse w-75">
<select id="department_id" name="department_id" class="form-control department-select"></select>
</div>
</div>
<div class="error text-danger"></div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary submit-btn">确认</button>
</div>
</div>
</div>
</div>

@ -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 }) %>")

@ -21,7 +21,7 @@
<%= 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') %>
<%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %>
<% end %>
</div>

@ -21,7 +21,7 @@
<%= 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') %>
<%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %>
<% end %>
</div>

@ -28,6 +28,12 @@
<% end %>
</li>
<li>
<%= sidebar_item_group('#schools-submenu', '单位管理', icon: 'building') do %>
<li><%= sidebar_item(admins_departments_path, '部门列表', icon: 'sitemap', controller: 'admins-departments') %></li>
<% end %>
</li>
<!-- <li>-->
<%#= sidebar_item_group('#course-submenu', '课堂+', icon: 'mortar-board') do %>
<!-- <li><%#= sidebar_item('#', '课程列表', icon: 'calendar', controller: '') %></li>-->

@ -21,7 +21,7 @@
<%= 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') %>
<%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %>
<% end %>
</div>

@ -31,37 +31,37 @@
<div class="d-flex mt-3">
<div class="mr-5">
<label for="can_copy">
<%= check_box_tag :can_copy,true,false,remote:true,onchange:"select_change(this)" %>
<%= check_box_tag :can_copy,true,false,remote:true,class:"shixun-settings-select" %>
<span class="only_view">只看可复制</span>
</label>
</div>
<div class="mr-5">
<label for="webssh">
<%= check_box_tag :webssh,1,false,remote:true,onchange:"select_change(this)" %>
<%= check_box_tag :webssh,1,false,remote:true, class:"shixun-settings-select" %>
<span class="only_view">只看可ssh</span>
</label>
</div>
<div class="mr-5">
<label for="hidden">
<%= check_box_tag :hidden,true,false,remote:true,onchange:"select_change(this)" %>
<%= check_box_tag :hidden,true,false,remote:true, class:"shixun-settings-select" %>
<span class="only_view">只看已隐藏</span>
</label>
</div>
<div class="mr-5">
<label for="homepage_show">
<%= check_box_tag :homepage_show,true,false,remote:true,onchange:"select_change(this)" %>
<%= check_box_tag :homepage_show,true,false,remote:true, class:"shixun-settings-select" %>
<span class="only_view">只看首页显示</span>
</label>
</div>
<div class="mr-5">
<label for="task_pass">
<%= check_box_tag :task_pass,true,false,remote:true,onchange:"select_change(this)" %>
<%= check_box_tag :task_pass, true, false, remote:true, class:"shixun-settings-select" %>
<span class="only_view">只看可跳关</span>
</label>
</div>
<div class="mr-5">
<label for="code_hidden">
<%= check_box_tag :code_hidden,true,false,remote:true,onchange:"select_change(this)" %>
<%= check_box_tag :code_hidden, true, false, remote:true, class:"shixun-settings-select" %>
<span class="only_view">只看已隐藏文件目录</span>
</label>
</div>

@ -5,7 +5,7 @@
<th width="12%" class="text-left">实训名称</th>
<th width="8%">技术平台</th>
<th width="8%">权限</th>
<th width="16%">技术体系</th>
<th width="15%">技术体系</th>
<th width="12%">上传图片</th>
<th width="5%">创建者</th>
<th width="5%">关闭</th>
@ -13,6 +13,9 @@
<th width="7%">代码执行时间</th>
<th>
操作
<div class="setting-chosen">
ssh/隐藏/首页/跳关/隐藏目录
</div>
</th>
</thead>
<tbody>

@ -2,7 +2,7 @@
<td><%= shixun.identifier %></td>
<td class="text-left">
<span>
<%= 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 %>
</span>
</td>
<td>
@ -10,10 +10,10 @@
</td>
<td>
<% 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}) %>
</td>
<td>
<%= 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}") %>
</td>
<td>
<!-- 图片上传,稍后添加-->
@ -37,22 +37,22 @@
<% end %>
</td>
<td>
<%= 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" %>
</td>
<td>
<input name="excute_time" value="<%= shixun.excute_time %>" class="form-control" data-id="<%= shixun.id %>" onchange="update_change(this)">
<input name="excute_time" value="<%= shixun.excute_time %>" class="form-control shixun-setting-form" data-id="<%= shixun.id %>">
</td>
<td class="operate">
<%= 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:"隐藏目录"%>
</td>
<!--<script>-->
<!-- $("#tags-chosen-<%= shixun.id %>").select2({-->
<!-- multiple: true,-->
<!-- maximumSelectionLength: 3,-->
<!-- placeholder: '请选择技术体系'});-->
<!--</script>-->
<script>
$("#tags-chosen-<%= shixun.id %>").select2({
multiple: true,
maximumSelectionLength: 3,
placeholder: '请选择技术体系'});
</script>

@ -21,7 +21,7 @@
<%= 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') %>
<%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %>
<% end %>
</div>

@ -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 %>
</div>

@ -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

@ -2,7 +2,7 @@
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLongTitle">奖励金币</h5>
<h5 class="modal-title">奖励金币</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>

@ -823,6 +823,11 @@ Rails.application.routes.draw do
resources :mirror_scripts, only: [:index, :new, :create, :edit, :update, :destroy]
end
resources :choose_mirror_repositories, only: [:new, :create]
resources :departments, only: [:index, :create, :edit, :update, :destroy] do
resource :department_member, only: [:create, :update, :destroy]
post :merge, on: :collection
end
end
#git 认证回调

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -17816,6 +17816,607 @@ form.was-validated select:valid ~ .select2-container--bootstrap4 .select2-select
.datepicker.datepicker-inline td {
padding: 4px 5px;
}
/* BASICS */
/* line 3, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror {
/* Set height, width, borders, and global font properties here */
font-family: monospace;
height: 300px;
color: black;
direction: ltr;
}
/* PADDING */
/* line 13, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-lines {
padding: 4px 0;
/* Vertical padding around content */
}
/* line 16, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror pre.CodeMirror-line,
.CodeMirror pre.CodeMirror-line-like {
padding: 0 4px;
/* Horizontal padding of content */
}
/* line 21, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
background-color: white;
/* The little square between H and V scrollbars */
}
/* GUTTER */
/* line 27, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-gutters {
border-right: 1px solid #ddd;
background-color: #f7f7f7;
white-space: nowrap;
}
/* line 33, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-linenumber {
padding: 0 3px 0 5px;
min-width: 20px;
text-align: right;
color: #999;
white-space: nowrap;
}
/* line 41, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-guttermarker {
color: black;
}
/* line 42, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-guttermarker-subtle {
color: #999;
}
/* CURSOR */
/* line 46, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-cursor {
border-left: 1px solid black;
border-right: none;
width: 0;
}
/* Shown when moving in bi-directional text */
/* line 52, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror div.CodeMirror-secondarycursor {
border-left: 1px solid silver;
}
/* line 55, vendor/assets/codemirror/lib/codemirror.css */
.cm-fat-cursor .CodeMirror-cursor {
width: auto;
border: 0 !important;
background: #7e7;
}
/* line 60, vendor/assets/codemirror/lib/codemirror.css */
.cm-fat-cursor div.CodeMirror-cursors {
z-index: 1;
}
/* line 63, vendor/assets/codemirror/lib/codemirror.css */
.cm-fat-cursor-mark {
background-color: rgba(20, 255, 20, 0.5);
-webkit-animation: blink 1.06s steps(1) infinite;
animation: blink 1.06s steps(1) infinite;
}
/* line 69, vendor/assets/codemirror/lib/codemirror.css */
.cm-animate-fat-cursor {
width: auto;
border: 0;
-webkit-animation: blink 1.06s steps(1) infinite;
animation: blink 1.06s steps(1) infinite;
background-color: #7e7;
}
@-webkit-keyframes blink {
0% {
}
50% {
background-color: transparent;
}
100% {
}
}
@keyframes blink {
0% {
}
50% {
background-color: transparent;
}
100% {
}
}
/* Can style cursor different in overwrite (non-insert) mode */
/* line 96, vendor/assets/codemirror/lib/codemirror.css */
.cm-tab {
display: inline-block;
text-decoration: inherit;
}
/* line 98, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-rulers {
position: absolute;
left: 0;
right: 0;
top: -50px;
bottom: 0;
overflow: hidden;
}
/* line 103, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-ruler {
border-left: 1px solid #ccc;
top: 0;
bottom: 0;
position: absolute;
}
/* DEFAULT THEME */
/* line 111, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-header {
color: blue;
}
/* line 112, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-quote {
color: #090;
}
/* line 113, vendor/assets/codemirror/lib/codemirror.css */
.cm-negative {
color: #d44;
}
/* line 114, vendor/assets/codemirror/lib/codemirror.css */
.cm-positive {
color: #292;
}
/* line 115, vendor/assets/codemirror/lib/codemirror.css */
.cm-header, .cm-strong {
font-weight: bold;
}
/* line 116, vendor/assets/codemirror/lib/codemirror.css */
.cm-em {
font-style: italic;
}
/* line 117, vendor/assets/codemirror/lib/codemirror.css */
.cm-link {
text-decoration: underline;
}
/* line 118, vendor/assets/codemirror/lib/codemirror.css */
.cm-strikethrough {
text-decoration: line-through;
}
/* line 120, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-keyword {
color: #708;
}
/* line 121, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-atom {
color: #219;
}
/* line 122, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-number {
color: #164;
}
/* line 123, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-def {
color: #00f;
}
/* line 128, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-variable-2 {
color: #05a;
}
/* line 129, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-variable-3, .cm-s-default .cm-type {
color: #085;
}
/* line 130, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-comment {
color: #a50;
}
/* line 131, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-string {
color: #a11;
}
/* line 132, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-string-2 {
color: #f50;
}
/* line 133, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-meta {
color: #555;
}
/* line 134, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-qualifier {
color: #555;
}
/* line 135, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-builtin {
color: #30a;
}
/* line 136, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-bracket {
color: #997;
}
/* line 137, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-tag {
color: #170;
}
/* line 138, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-attribute {
color: #00c;
}
/* line 139, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-hr {
color: #999;
}
/* line 140, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-link {
color: #00c;
}
/* line 142, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-error {
color: #f00;
}
/* line 143, vendor/assets/codemirror/lib/codemirror.css */
.cm-invalidchar {
color: #f00;
}
/* line 145, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-composing {
border-bottom: 2px solid;
}
/* Default styles for common addons */
/* line 149, vendor/assets/codemirror/lib/codemirror.css */
div.CodeMirror span.CodeMirror-matchingbracket {
color: #0b0;
}
/* line 150, vendor/assets/codemirror/lib/codemirror.css */
div.CodeMirror span.CodeMirror-nonmatchingbracket {
color: #a22;
}
/* line 151, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-matchingtag {
background: rgba(255, 150, 0, 0.3);
}
/* line 152, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-activeline-background {
background: #e8f2ff;
}
/* STOP */
/* The rest of this file contains styles related to the mechanics of
the editor. You probably shouldn't touch them. */
/* line 159, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror {
position: relative;
overflow: hidden;
background: white;
}
/* line 165, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-scroll {
overflow: scroll !important;
/* Things will break if this is overridden */
/* 30px is the magic margin used to hide the element's real scrollbars */
/* See overflow: hidden in .CodeMirror */
margin-bottom: -30px;
margin-right: -30px;
padding-bottom: 30px;
height: 100%;
outline: none;
/* Prevent dragging from highlighting the element */
position: relative;
}
/* line 175, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-sizer {
position: relative;
border-right: 30px solid transparent;
}
/* The fake, visible scrollbars. Used to force redraw during scrolling
before actual scrolling happens, thus preventing shaking and
flickering artifacts. */
/* line 183, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
position: absolute;
z-index: 6;
display: none;
}
/* line 188, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-vscrollbar {
right: 0;
top: 0;
overflow-x: hidden;
overflow-y: scroll;
}
/* line 193, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-hscrollbar {
bottom: 0;
left: 0;
overflow-y: hidden;
overflow-x: scroll;
}
/* line 198, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-scrollbar-filler {
right: 0;
bottom: 0;
}
/* line 201, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-gutter-filler {
left: 0;
bottom: 0;
}
/* line 205, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-gutters {
position: absolute;
left: 0;
top: 0;
min-height: 100%;
z-index: 3;
}
/* line 210, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-gutter {
white-space: normal;
height: 100%;
display: inline-block;
vertical-align: top;
margin-bottom: -30px;
}
/* line 217, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-gutter-wrapper {
position: absolute;
z-index: 4;
background: none !important;
border: none !important;
}
/* line 223, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-gutter-background {
position: absolute;
top: 0;
bottom: 0;
z-index: 4;
}
/* line 228, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-gutter-elt {
position: absolute;
cursor: default;
z-index: 4;
}
/* line 233, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-gutter-wrapper ::-moz-selection {
background-color: transparent;
}
.CodeMirror-gutter-wrapper ::selection {
background-color: transparent;
}
/* line 234, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-gutter-wrapper ::-moz-selection {
background-color: transparent;
}
/* line 236, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-lines {
cursor: text;
min-height: 1px;
/* prevents collapsing before first draw */
}
/* line 240, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror pre.CodeMirror-line,
.CodeMirror pre.CodeMirror-line-like {
/* Reset some styles that the rest of the page might have set */
border-radius: 0;
border-width: 0;
background: transparent;
font-family: inherit;
font-size: inherit;
margin: 0;
white-space: pre;
word-wrap: normal;
line-height: inherit;
color: inherit;
z-index: 2;
position: relative;
overflow: visible;
-webkit-tap-highlight-color: transparent;
-webkit-font-variant-ligatures: contextual;
font-variant-ligatures: contextual;
}
/* line 260, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-wrap pre.CodeMirror-line,
.CodeMirror-wrap pre.CodeMirror-line-like {
word-wrap: break-word;
white-space: pre-wrap;
word-break: normal;
}
/* line 267, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-linebackground {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
z-index: 0;
}
/* line 273, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-linewidget {
position: relative;
z-index: 2;
padding: 0.1px;
/* Force widget margins to stay inside of the container */
}
/* line 281, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-rtl pre {
direction: rtl;
}
/* line 283, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-code {
outline: none;
}
/* Force content-box sizing for the elements where we expect it */
/* line 288, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-scroll,
.CodeMirror-sizer,
.CodeMirror-gutter,
.CodeMirror-gutters,
.CodeMirror-linenumber {
box-sizing: content-box;
}
/* line 297, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-measure {
position: absolute;
width: 100%;
height: 0;
overflow: hidden;
visibility: hidden;
}
/* line 305, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-cursor {
position: absolute;
pointer-events: none;
}
/* line 309, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-measure pre {
position: static;
}
/* line 311, vendor/assets/codemirror/lib/codemirror.css */
div.CodeMirror-cursors {
visibility: hidden;
position: relative;
z-index: 3;
}
/* line 316, vendor/assets/codemirror/lib/codemirror.css */
div.CodeMirror-dragcursors {
visibility: visible;
}
/* line 320, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-focused div.CodeMirror-cursors {
visibility: visible;
}
/* line 324, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-selected {
background: #d9d9d9;
}
/* line 325, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-focused .CodeMirror-selected {
background: #d7d4f0;
}
/* line 326, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-crosshair {
cursor: crosshair;
}
/* line 327, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection {
background: #d7d4f0;
}
.CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection {
background: #d7d4f0;
}
/* line 328, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection {
background: #d7d4f0;
}
/* line 330, vendor/assets/codemirror/lib/codemirror.css */
.cm-searching {
background-color: #ffa;
background-color: rgba(255, 255, 0, 0.4);
}
/* Used to force a border model for a node */
/* line 336, vendor/assets/codemirror/lib/codemirror.css */
.cm-force-border {
padding-right: .1px;
}
@media print {
/* Hide the cursor when printing */
/* line 340, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror div.CodeMirror-cursors {
visibility: hidden;
}
}
/* See issue #2901 */
/* line 346, vendor/assets/codemirror/lib/codemirror.css */
.cm-tab-wrap-hack:after {
content: '';
}
/* Help users use markselection to safely style text background */
/* line 349, vendor/assets/codemirror/lib/codemirror.css */
span.CodeMirror-selectedtext {
background: none;
}
/* line 1, app/assets/stylesheets/admins/common.scss */
.admin-body-container {
padding: 20px;
@ -17952,11 +18553,41 @@ form.was-validated select:valid ~ .select2-container--bootstrap4 .select2-select
padding: 0.5rem 2rem;
}
/* line 110, app/assets/stylesheets/admins/common.scss */
.admin-body-container .CodeMirror {
border: 1px solid #ced4da;
}
/* line 2, app/assets/stylesheets/admins/daily_school_statistics.scss */
.admins-daily-school-statistics-index-page .daily-school-statistic-list-container {
text-align: center;
}
/* line 4, app/assets/stylesheets/admins/departments.scss */
.admins-departments-index-page .department-list-table .member-container .member-user {
display: -webkit-box;
display: flex;
-webkit-box-pack: center;
justify-content: center;
flex-wrap: wrap;
}
/* line 9, app/assets/stylesheets/admins/departments.scss */
.admins-departments-index-page .department-list-table .member-container .member-user .member-user-item {
display: -webkit-box;
display: flex;
-webkit-box-align: center;
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;
}
/* line 4, app/assets/stylesheets/admins/identity_authentications.scss */
.admins-identity-authentications-index-page .identity-authentication-list-container span.apply-status-1 {
color: #28a745;
@ -18080,6 +18711,21 @@ form.was-validated select:valid ~ .select2-container--bootstrap4 .select2-select
color: #6c757d;
}
/* line 1, app/assets/stylesheets/admins/shixun_settings.scss */
input[type="checkbox"] {
font-size: 18px;
}
/* line 4, app/assets/stylesheets/admins/shixun_settings.scss */
.select2 input::-webkit-input-placeholder {
color: #ccc;
}
/* line 7, app/assets/stylesheets/admins/shixun_settings.scss */
.select2 .select2-selection__choice {
border: 1px solid #eee !important;
}
/* line 1, app/assets/stylesheets/admins/sidebar.scss */
#sidebar {
min-width: 200px;
@ -18389,7 +19035,7 @@ form.was-validated select:valid ~ .select2-container--bootstrap4 .select2-select
text-align: center;
}
/* line 11, app/assets/stylesheets/admin.scss */
/* line 12, app/assets/stylesheets/admin.scss */
body {
width: 100vw;
height: 100vh;
@ -18403,50 +19049,75 @@ body {
background: #efefef;
}
/* line 23, app/assets/stylesheets/admin.scss */
/* line 24, app/assets/stylesheets/admin.scss */
a:hover {
text-decoration: unset;
}
/* line 28, app/assets/stylesheets/admin.scss */
/* line 29, app/assets/stylesheets/admin.scss */
textarea.danger, input.danger {
border-color: #dc3545 !important;
}
/* line 32, app/assets/stylesheets/admin.scss */
/* line 33, app/assets/stylesheets/admin.scss */
label.error {
color: #dc3545 !important;
}
/* line 38, app/assets/stylesheets/admin.scss */
/* line 39, app/assets/stylesheets/admin.scss */
.simple_form .form-group .collection_radio_buttons {
margin-bottom: 0px;
}
/* line 42, app/assets/stylesheets/admin.scss */
/* line 43, app/assets/stylesheets/admin.scss */
.simple_form .form-group .form-check-inline {
height: calc(1.5em + 0.75rem + 2px);
}
/* line 48, app/assets/stylesheets/admin.scss */
/* line 49, app/assets/stylesheets/admin.scss */
input.form-control {
font-size: 14px;
}
/* line 53, app/assets/stylesheets/admin.scss */
.flex-1 {
-webkit-box-flex: 1;
flex: 1;
}
/* line 51, app/assets/stylesheets/admin.scss */
/* line 56, app/assets/stylesheets/admin.scss */
.btn-default {
color: #666;
background: #e1e1e1 !important;
}
/* line 55, app/assets/stylesheets/admin.scss */
/* line 60, app/assets/stylesheets/admin.scss */
.export-absolute {
right: 20px;
position: absolute;
}
/* line 59, app/assets/stylesheets/admin.scss */
/* line 64, app/assets/stylesheets/admin.scss */
.position-r {
position: relative;
}
/* line 66, app/assets/stylesheets/admin.scss */
.font-12 {
font-size: 12px !important;
}
/* line 67, app/assets/stylesheets/admin.scss */
.font-14 {
font-size: 14px !important;
}
/* line 68, app/assets/stylesheets/admin.scss */
.font-16 {
font-size: 16px !important;
}
/* line 69, app/assets/stylesheets/admin.scss */
.font-18 {
font-size: 18px !important;
}

@ -37635,6 +37635,179 @@ $(document).on('turbolinks:load', function(){
}
})
;
$(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');
}
});
}
});
$(document).on('turbolinks:load', function() {
if ($('body.admins-identity-authentications-index-page').length > 0) {
var $searchFrom = $('.identity-authentication-list-form');
@ -37656,6 +37829,28 @@ $(document).on('turbolinks:load', function() {
}
})
;
$(document).on('turbolinks:load', function() {
if ($('body.admins-library-applies-index-page').length > 0) {
var $searchFrom = $('.library-applies-list-form');
$searchFrom.find('select[name="status"]').val('pending');
$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();
$searchFrom.find('select[name="status"]').val('pending');
}
});
}
})
;
$(document).on('turbolinks:load', function() {
if ($('body.admins-mirror-repositories-edit-page, body.admins-mirror-repositories-update-page').length > 0) {
var $form = $('form.edit-mirror');
@ -37744,6 +37939,150 @@ $(document).on('turbolinks:load', function() {
});
})
});
$(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()
});
}
});
})
});
$(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);
}
});
}
});
}
});
$(document).on('turbolinks:load', function() {
var $modal = $('.modal.admin-replace-mirror-modal');
if ($modal.length > 0) {
@ -38021,6 +38360,54 @@ $(document).on('turbolinks:load', function() {
}
})
;
$(document).on('turbolinks:load', function() {
if ($('body.admins-shixun-settings-index-page').length > 0) {
}
});
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) {
}
})
}
;
$(document).on('turbolinks:load', function() {
$('select#tag-choosed').select2({
placeholder: "请选择分类",
allowClear: true
});
});
$(document).on('turbolinks:load', function(){
$('#sidebarCollapse').on('click', function () {
$(this).toggleClass('active');
@ -38362,6 +38749,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();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -17816,6 +17816,607 @@ form.was-validated select:valid ~ .select2-container--bootstrap4 .select2-select
.datepicker.datepicker-inline td {
padding: 4px 5px;
}
/* BASICS */
/* line 3, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror {
/* Set height, width, borders, and global font properties here */
font-family: monospace;
height: 300px;
color: black;
direction: ltr;
}
/* PADDING */
/* line 13, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-lines {
padding: 4px 0;
/* Vertical padding around content */
}
/* line 16, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror pre.CodeMirror-line,
.CodeMirror pre.CodeMirror-line-like {
padding: 0 4px;
/* Horizontal padding of content */
}
/* line 21, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
background-color: white;
/* The little square between H and V scrollbars */
}
/* GUTTER */
/* line 27, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-gutters {
border-right: 1px solid #ddd;
background-color: #f7f7f7;
white-space: nowrap;
}
/* line 33, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-linenumber {
padding: 0 3px 0 5px;
min-width: 20px;
text-align: right;
color: #999;
white-space: nowrap;
}
/* line 41, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-guttermarker {
color: black;
}
/* line 42, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-guttermarker-subtle {
color: #999;
}
/* CURSOR */
/* line 46, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-cursor {
border-left: 1px solid black;
border-right: none;
width: 0;
}
/* Shown when moving in bi-directional text */
/* line 52, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror div.CodeMirror-secondarycursor {
border-left: 1px solid silver;
}
/* line 55, vendor/assets/codemirror/lib/codemirror.css */
.cm-fat-cursor .CodeMirror-cursor {
width: auto;
border: 0 !important;
background: #7e7;
}
/* line 60, vendor/assets/codemirror/lib/codemirror.css */
.cm-fat-cursor div.CodeMirror-cursors {
z-index: 1;
}
/* line 63, vendor/assets/codemirror/lib/codemirror.css */
.cm-fat-cursor-mark {
background-color: rgba(20, 255, 20, 0.5);
-webkit-animation: blink 1.06s steps(1) infinite;
animation: blink 1.06s steps(1) infinite;
}
/* line 69, vendor/assets/codemirror/lib/codemirror.css */
.cm-animate-fat-cursor {
width: auto;
border: 0;
-webkit-animation: blink 1.06s steps(1) infinite;
animation: blink 1.06s steps(1) infinite;
background-color: #7e7;
}
@-webkit-keyframes blink {
0% {
}
50% {
background-color: transparent;
}
100% {
}
}
@keyframes blink {
0% {
}
50% {
background-color: transparent;
}
100% {
}
}
/* Can style cursor different in overwrite (non-insert) mode */
/* line 96, vendor/assets/codemirror/lib/codemirror.css */
.cm-tab {
display: inline-block;
text-decoration: inherit;
}
/* line 98, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-rulers {
position: absolute;
left: 0;
right: 0;
top: -50px;
bottom: 0;
overflow: hidden;
}
/* line 103, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-ruler {
border-left: 1px solid #ccc;
top: 0;
bottom: 0;
position: absolute;
}
/* DEFAULT THEME */
/* line 111, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-header {
color: blue;
}
/* line 112, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-quote {
color: #090;
}
/* line 113, vendor/assets/codemirror/lib/codemirror.css */
.cm-negative {
color: #d44;
}
/* line 114, vendor/assets/codemirror/lib/codemirror.css */
.cm-positive {
color: #292;
}
/* line 115, vendor/assets/codemirror/lib/codemirror.css */
.cm-header, .cm-strong {
font-weight: bold;
}
/* line 116, vendor/assets/codemirror/lib/codemirror.css */
.cm-em {
font-style: italic;
}
/* line 117, vendor/assets/codemirror/lib/codemirror.css */
.cm-link {
text-decoration: underline;
}
/* line 118, vendor/assets/codemirror/lib/codemirror.css */
.cm-strikethrough {
text-decoration: line-through;
}
/* line 120, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-keyword {
color: #708;
}
/* line 121, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-atom {
color: #219;
}
/* line 122, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-number {
color: #164;
}
/* line 123, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-def {
color: #00f;
}
/* line 128, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-variable-2 {
color: #05a;
}
/* line 129, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-variable-3, .cm-s-default .cm-type {
color: #085;
}
/* line 130, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-comment {
color: #a50;
}
/* line 131, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-string {
color: #a11;
}
/* line 132, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-string-2 {
color: #f50;
}
/* line 133, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-meta {
color: #555;
}
/* line 134, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-qualifier {
color: #555;
}
/* line 135, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-builtin {
color: #30a;
}
/* line 136, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-bracket {
color: #997;
}
/* line 137, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-tag {
color: #170;
}
/* line 138, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-attribute {
color: #00c;
}
/* line 139, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-hr {
color: #999;
}
/* line 140, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-link {
color: #00c;
}
/* line 142, vendor/assets/codemirror/lib/codemirror.css */
.cm-s-default .cm-error {
color: #f00;
}
/* line 143, vendor/assets/codemirror/lib/codemirror.css */
.cm-invalidchar {
color: #f00;
}
/* line 145, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-composing {
border-bottom: 2px solid;
}
/* Default styles for common addons */
/* line 149, vendor/assets/codemirror/lib/codemirror.css */
div.CodeMirror span.CodeMirror-matchingbracket {
color: #0b0;
}
/* line 150, vendor/assets/codemirror/lib/codemirror.css */
div.CodeMirror span.CodeMirror-nonmatchingbracket {
color: #a22;
}
/* line 151, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-matchingtag {
background: rgba(255, 150, 0, 0.3);
}
/* line 152, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-activeline-background {
background: #e8f2ff;
}
/* STOP */
/* The rest of this file contains styles related to the mechanics of
the editor. You probably shouldn't touch them. */
/* line 159, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror {
position: relative;
overflow: hidden;
background: white;
}
/* line 165, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-scroll {
overflow: scroll !important;
/* Things will break if this is overridden */
/* 30px is the magic margin used to hide the element's real scrollbars */
/* See overflow: hidden in .CodeMirror */
margin-bottom: -30px;
margin-right: -30px;
padding-bottom: 30px;
height: 100%;
outline: none;
/* Prevent dragging from highlighting the element */
position: relative;
}
/* line 175, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-sizer {
position: relative;
border-right: 30px solid transparent;
}
/* The fake, visible scrollbars. Used to force redraw during scrolling
before actual scrolling happens, thus preventing shaking and
flickering artifacts. */
/* line 183, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
position: absolute;
z-index: 6;
display: none;
}
/* line 188, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-vscrollbar {
right: 0;
top: 0;
overflow-x: hidden;
overflow-y: scroll;
}
/* line 193, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-hscrollbar {
bottom: 0;
left: 0;
overflow-y: hidden;
overflow-x: scroll;
}
/* line 198, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-scrollbar-filler {
right: 0;
bottom: 0;
}
/* line 201, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-gutter-filler {
left: 0;
bottom: 0;
}
/* line 205, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-gutters {
position: absolute;
left: 0;
top: 0;
min-height: 100%;
z-index: 3;
}
/* line 210, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-gutter {
white-space: normal;
height: 100%;
display: inline-block;
vertical-align: top;
margin-bottom: -30px;
}
/* line 217, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-gutter-wrapper {
position: absolute;
z-index: 4;
background: none !important;
border: none !important;
}
/* line 223, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-gutter-background {
position: absolute;
top: 0;
bottom: 0;
z-index: 4;
}
/* line 228, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-gutter-elt {
position: absolute;
cursor: default;
z-index: 4;
}
/* line 233, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-gutter-wrapper ::-moz-selection {
background-color: transparent;
}
.CodeMirror-gutter-wrapper ::selection {
background-color: transparent;
}
/* line 234, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-gutter-wrapper ::-moz-selection {
background-color: transparent;
}
/* line 236, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-lines {
cursor: text;
min-height: 1px;
/* prevents collapsing before first draw */
}
/* line 240, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror pre.CodeMirror-line,
.CodeMirror pre.CodeMirror-line-like {
/* Reset some styles that the rest of the page might have set */
border-radius: 0;
border-width: 0;
background: transparent;
font-family: inherit;
font-size: inherit;
margin: 0;
white-space: pre;
word-wrap: normal;
line-height: inherit;
color: inherit;
z-index: 2;
position: relative;
overflow: visible;
-webkit-tap-highlight-color: transparent;
-webkit-font-variant-ligatures: contextual;
font-variant-ligatures: contextual;
}
/* line 260, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-wrap pre.CodeMirror-line,
.CodeMirror-wrap pre.CodeMirror-line-like {
word-wrap: break-word;
white-space: pre-wrap;
word-break: normal;
}
/* line 267, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-linebackground {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
z-index: 0;
}
/* line 273, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-linewidget {
position: relative;
z-index: 2;
padding: 0.1px;
/* Force widget margins to stay inside of the container */
}
/* line 281, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-rtl pre {
direction: rtl;
}
/* line 283, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-code {
outline: none;
}
/* Force content-box sizing for the elements where we expect it */
/* line 288, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-scroll,
.CodeMirror-sizer,
.CodeMirror-gutter,
.CodeMirror-gutters,
.CodeMirror-linenumber {
box-sizing: content-box;
}
/* line 297, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-measure {
position: absolute;
width: 100%;
height: 0;
overflow: hidden;
visibility: hidden;
}
/* line 305, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-cursor {
position: absolute;
pointer-events: none;
}
/* line 309, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-measure pre {
position: static;
}
/* line 311, vendor/assets/codemirror/lib/codemirror.css */
div.CodeMirror-cursors {
visibility: hidden;
position: relative;
z-index: 3;
}
/* line 316, vendor/assets/codemirror/lib/codemirror.css */
div.CodeMirror-dragcursors {
visibility: visible;
}
/* line 320, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-focused div.CodeMirror-cursors {
visibility: visible;
}
/* line 324, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-selected {
background: #d9d9d9;
}
/* line 325, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-focused .CodeMirror-selected {
background: #d7d4f0;
}
/* line 326, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-crosshair {
cursor: crosshair;
}
/* line 327, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection {
background: #d7d4f0;
}
.CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection {
background: #d7d4f0;
}
/* line 328, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection {
background: #d7d4f0;
}
/* line 330, vendor/assets/codemirror/lib/codemirror.css */
.cm-searching {
background-color: #ffa;
background-color: rgba(255, 255, 0, 0.4);
}
/* Used to force a border model for a node */
/* line 336, vendor/assets/codemirror/lib/codemirror.css */
.cm-force-border {
padding-right: .1px;
}
@media print {
/* Hide the cursor when printing */
/* line 340, vendor/assets/codemirror/lib/codemirror.css */
.CodeMirror div.CodeMirror-cursors {
visibility: hidden;
}
}
/* See issue #2901 */
/* line 346, vendor/assets/codemirror/lib/codemirror.css */
.cm-tab-wrap-hack:after {
content: '';
}
/* Help users use markselection to safely style text background */
/* line 349, vendor/assets/codemirror/lib/codemirror.css */
span.CodeMirror-selectedtext {
background: none;
}
/* line 1, app/assets/stylesheets/admins/common.scss */
.admin-body-container {
padding: 20px;
@ -17952,11 +18553,41 @@ form.was-validated select:valid ~ .select2-container--bootstrap4 .select2-select
padding: 0.5rem 2rem;
}
/* line 110, app/assets/stylesheets/admins/common.scss */
.admin-body-container .CodeMirror {
border: 1px solid #ced4da;
}
/* line 2, app/assets/stylesheets/admins/daily_school_statistics.scss */
.admins-daily-school-statistics-index-page .daily-school-statistic-list-container {
text-align: center;
}
/* line 4, app/assets/stylesheets/admins/departments.scss */
.admins-departments-index-page .department-list-table .member-container .member-user {
display: -webkit-box;
display: flex;
-webkit-box-pack: center;
justify-content: center;
flex-wrap: wrap;
}
/* line 9, app/assets/stylesheets/admins/departments.scss */
.admins-departments-index-page .department-list-table .member-container .member-user .member-user-item {
display: -webkit-box;
display: flex;
-webkit-box-align: center;
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;
}
/* line 4, app/assets/stylesheets/admins/identity_authentications.scss */
.admins-identity-authentications-index-page .identity-authentication-list-container span.apply-status-1 {
color: #28a745;
@ -18080,6 +18711,21 @@ form.was-validated select:valid ~ .select2-container--bootstrap4 .select2-select
color: #6c757d;
}
/* line 1, app/assets/stylesheets/admins/shixun_settings.scss */
input[type="checkbox"] {
font-size: 18px;
}
/* line 4, app/assets/stylesheets/admins/shixun_settings.scss */
.select2 input::-webkit-input-placeholder {
color: #ccc;
}
/* line 7, app/assets/stylesheets/admins/shixun_settings.scss */
.select2 .select2-selection__choice {
border: 1px solid #eee !important;
}
/* line 1, app/assets/stylesheets/admins/sidebar.scss */
#sidebar {
min-width: 200px;
@ -18389,7 +19035,7 @@ form.was-validated select:valid ~ .select2-container--bootstrap4 .select2-select
text-align: center;
}
/* line 11, app/assets/stylesheets/admin.scss */
/* line 12, app/assets/stylesheets/admin.scss */
body {
width: 100vw;
height: 100vh;
@ -18403,53 +19049,78 @@ body {
background: #efefef;
}
/* line 23, app/assets/stylesheets/admin.scss */
/* line 24, app/assets/stylesheets/admin.scss */
a:hover {
text-decoration: unset;
}
/* line 28, app/assets/stylesheets/admin.scss */
/* line 29, app/assets/stylesheets/admin.scss */
textarea.danger, input.danger {
border-color: #dc3545 !important;
}
/* line 32, app/assets/stylesheets/admin.scss */
/* line 33, app/assets/stylesheets/admin.scss */
label.error {
color: #dc3545 !important;
}
/* line 38, app/assets/stylesheets/admin.scss */
/* line 39, app/assets/stylesheets/admin.scss */
.simple_form .form-group .collection_radio_buttons {
margin-bottom: 0px;
}
/* line 42, app/assets/stylesheets/admin.scss */
/* line 43, app/assets/stylesheets/admin.scss */
.simple_form .form-group .form-check-inline {
height: calc(1.5em + 0.75rem + 2px);
}
/* line 48, app/assets/stylesheets/admin.scss */
/* line 49, app/assets/stylesheets/admin.scss */
input.form-control {
font-size: 14px;
}
/* line 53, app/assets/stylesheets/admin.scss */
.flex-1 {
-webkit-box-flex: 1;
flex: 1;
}
/* line 51, app/assets/stylesheets/admin.scss */
/* line 56, app/assets/stylesheets/admin.scss */
.btn-default {
color: #666;
background: #e1e1e1 !important;
}
/* line 55, app/assets/stylesheets/admin.scss */
/* line 60, app/assets/stylesheets/admin.scss */
.export-absolute {
right: 20px;
position: absolute;
}
/* line 59, app/assets/stylesheets/admin.scss */
/* line 64, app/assets/stylesheets/admin.scss */
.position-r {
position: relative;
}
/* line 66, app/assets/stylesheets/admin.scss */
.font-12 {
font-size: 12px !important;
}
/* line 67, app/assets/stylesheets/admin.scss */
.font-14 {
font-size: 14px !important;
}
/* line 68, app/assets/stylesheets/admin.scss */
.font-16 {
font-size: 16px !important;
}
/* line 69, app/assets/stylesheets/admin.scss */
.font-18 {
font-size: 18px !important;
}
@charset "UTF-8";
/* line 1, app/assets/stylesheets/admins/common.scss */
.admin-body-container {
@ -18586,10 +19257,39 @@ label.error {
.admin-body-container .nav-tabs .nav-link {
padding: 0.5rem 2rem;
}
/* line 110, app/assets/stylesheets/admins/common.scss */
.admin-body-container .CodeMirror {
border: 1px solid #ced4da;
}
/* line 2, app/assets/stylesheets/admins/daily_school_statistics.scss */
.admins-daily-school-statistics-index-page .daily-school-statistic-list-container {
text-align: center;
}
/* line 4, app/assets/stylesheets/admins/departments.scss */
.admins-departments-index-page .department-list-table .member-container .member-user {
display: -webkit-box;
display: flex;
-webkit-box-pack: center;
justify-content: center;
flex-wrap: wrap;
}
/* line 9, app/assets/stylesheets/admins/departments.scss */
.admins-departments-index-page .department-list-table .member-container .member-user .member-user-item {
display: -webkit-box;
display: flex;
-webkit-box-align: center;
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;
}
/* line 4, app/assets/stylesheets/admins/identity_authentications.scss */
.admins-identity-authentications-index-page .identity-authentication-list-container span.apply-status-1 {
color: #28a745;
@ -18707,6 +19407,20 @@ label.error {
.admins-shixun-authorizations-index-page .shixun-authorization-list-container span.apply-status-3 {
color: #6c757d;
}
/* line 1, app/assets/stylesheets/admins/shixun_settings.scss */
input[type="checkbox"] {
font-size: 18px;
}
/* line 4, app/assets/stylesheets/admins/shixun_settings.scss */
.select2 input::-webkit-input-placeholder {
color: #ccc;
}
/* line 7, app/assets/stylesheets/admins/shixun_settings.scss */
.select2 .select2-selection__choice {
border: 1px solid #eee !important;
}
/* line 1, app/assets/stylesheets/admins/sidebar.scss */
#sidebar {
min-width: 200px;

@ -53,7 +53,7 @@ class ShiXunPostItem extends Component
</div>
<p className="clearfix mt5">
<span className="fl color-grey-9">{memo.username}</span>
<span className="fl color-grey-9 ml40">{moment(memo.updated_at).fromNow()}</span>
{/* <span className="fl color-grey-9 ml40">{moment(memo.updated_at).fromNow()}</span> */}
{ !!tagStr && <span className="fl color-grey-9 ml40">来自 {tagStr}</span>}
{ !!memo.praises_count && <span className="fr color-grey-6 ml20 font-12">{memo.praises_count} </span>}
{ !!memo.replies_count && <span className="fr color-grey-6 font-12">{memo.replies_count} 回复</span>}

@ -550,7 +550,7 @@ class AccountBasic extends Component {
)}
<span>{ showRealName ? '(显示:平台将显示您的真实姓名)' : '(隐藏:平台将显示你的昵称)' }</span>
</React.Fragment> :
<div className="df" style={{ 'justify-content': 'center' }}>
<div className="df" style={{}}>
<Tooltip title="已完成实名认证,不能修改">
<span className="mr8" >{showRealName ? this.props.basicInfo.name : getHiddenName(this.props.basicInfo.name)}</span>
</Tooltip>

@ -3763,6 +3763,6 @@ a.singlepublishtwo{
/*}*/
.topicsItem{
max-width: 1138px;
height: 110px;
max-height: 110px;
overflow-y: auto;
}
Loading…
Cancel
Save