Merge branches 'dev_aliyun' and 'dev_ysm' of https://bdgit.educoder.net/Hjqreturn/educoder into dev_ysm
commit
29ba5814af
@ -0,0 +1,125 @@
|
|||||||
|
$(document).on('turbolinks:load', function() {
|
||||||
|
if ($('body.cooperative-carousels-index-page').length > 0) {
|
||||||
|
// ------------ 保存链接 -----------
|
||||||
|
$('.carousels-card').on('click', '.save-data-btn', function(){
|
||||||
|
var $link = $(this);
|
||||||
|
var id = $link.data('id');
|
||||||
|
var link = $('.custom-carousel-item-' + id).find('.link-input').val();
|
||||||
|
var name = $('.custom-carousel-item-' + id).find('.name-input').val();
|
||||||
|
if(!name || name.length == 0){
|
||||||
|
$.notify({ message: '名称不能为空' },{ type: 'danger' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$link.attr('disabled', true);
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: '/cooperative/carousels/' + id,
|
||||||
|
method: 'PATCH',
|
||||||
|
dataType: 'json',
|
||||||
|
data: { link: link, name: name },
|
||||||
|
success: function(data){
|
||||||
|
$.notify({ message: '操作成功' });
|
||||||
|
},
|
||||||
|
error: ajaxErrorNotifyHandler,
|
||||||
|
complete: function(){
|
||||||
|
$link.removeAttr('disabled');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
// -------------- 是否在首页展示 --------------
|
||||||
|
$('.carousels-card').on('change', '.online-check-box', function(){
|
||||||
|
var $checkbox = $(this);
|
||||||
|
var id = $checkbox.data('id');
|
||||||
|
var checked = $checkbox.is(':checked');
|
||||||
|
$checkbox.attr('disabled', true);
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: '/cooperative/carousels/' + id,
|
||||||
|
method: 'PATCH',
|
||||||
|
dataType: 'json',
|
||||||
|
data: { status: checked },
|
||||||
|
success: function(data){
|
||||||
|
$.notify({ message: '保存成功' });
|
||||||
|
var box = $('.custom-carousel-item-' + id).find('.drag');
|
||||||
|
if(checked){
|
||||||
|
box.removeClass('not_active');
|
||||||
|
}else{
|
||||||
|
box.addClass('not_active');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: ajaxErrorNotifyHandler,
|
||||||
|
complete: function(){
|
||||||
|
$checkbox.removeAttr('disabled');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// ------------ 拖拽 -------------
|
||||||
|
var onDropFunc = function(el, _target, _source, sibling){
|
||||||
|
var moveId = $(el).data('id');
|
||||||
|
var insertId = $(sibling).data('id') || '';
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: '/cooperative/carousels/drag',
|
||||||
|
method: 'POST',
|
||||||
|
dataType: 'json',
|
||||||
|
data: { move_id: moveId, after_id: insertId },
|
||||||
|
success: function(data){
|
||||||
|
$('#carousels-container .custom-carousel-item-no').each(function(index, ele){
|
||||||
|
$(ele).html(index + 1);
|
||||||
|
})
|
||||||
|
},
|
||||||
|
error: function(res){
|
||||||
|
var data = res.responseJSON;
|
||||||
|
$.notify({message: '移动失败,原因:' + data.message}, {type: 'danger'});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
var ele1 = document.getElementById('carousels-container');
|
||||||
|
dragula([ele1], { mirrorContainer: ele1 }).on('drop', onDropFunc);
|
||||||
|
|
||||||
|
|
||||||
|
// ----------- 新增 --------------
|
||||||
|
var $createModal = $('.modal.cooperative-add-carousel-modal');
|
||||||
|
var $createForm = $createModal.find('form.cooperative-add-carousel-form');
|
||||||
|
|
||||||
|
$createForm.validate({
|
||||||
|
errorElement: 'span',
|
||||||
|
errorClass: 'danger text-danger',
|
||||||
|
rules: {
|
||||||
|
"portal_image[image]": {
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
"portal_image[name]": {
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$createModal.on('show.bs.modal', function(event){
|
||||||
|
resetFileInputFunc($createModal.find('.img-file-input'));
|
||||||
|
$createModal.find('.file-names').html('选择文件');
|
||||||
|
});
|
||||||
|
|
||||||
|
$createModal.on('click', '.submit-btn', function() {
|
||||||
|
$createForm.find('.error').html('');
|
||||||
|
|
||||||
|
if ($createForm.valid()) {
|
||||||
|
$createForm.submit();
|
||||||
|
} else {
|
||||||
|
$createForm.find('.error').html('请选择图片');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$createModal.on('change', '.img-file-input', function(){
|
||||||
|
var file = $(this)[0].files[0];
|
||||||
|
$createModal.find('.file-names').html(file ? file.name : '请选择文件');
|
||||||
|
})
|
||||||
|
|
||||||
|
// -------------- 重新上传图片 --------------
|
||||||
|
//replace_image_url
|
||||||
|
$('.modal.cooperative-upload-file-modal').on('upload:success', function(e, data){
|
||||||
|
var $carouselItem = $('.custom-carousel-item-' + data.source_id);
|
||||||
|
$carouselItem.find('.custom-carousel-item-img img').attr('src', data.url);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
@ -0,0 +1,62 @@
|
|||||||
|
$(document).on('turbolinks:load', function() {
|
||||||
|
if ($('body.cooperative-laboratory-users-index-page').length > 0) {
|
||||||
|
// ============= 添加管理员 ==============
|
||||||
|
var $addMemberModal = $('.cooperative-add-laboratory-user-modal');
|
||||||
|
var $addMemberForm = $addMemberModal.find('.cooperative-add-laboratory-user-form');
|
||||||
|
var $memberSelect = $addMemberModal.find('.laboratory-user-select');
|
||||||
|
|
||||||
|
$addMemberModal.on('show.bs.modal', function(event){
|
||||||
|
$memberSelect.select2('val', ' ');
|
||||||
|
});
|
||||||
|
|
||||||
|
$memberSelect.select2({
|
||||||
|
theme: 'bootstrap4',
|
||||||
|
placeholder: '请输入要添加的管理员姓名',
|
||||||
|
multiple: true,
|
||||||
|
minimumInputLength: 1,
|
||||||
|
ajax: {
|
||||||
|
delay: 500,
|
||||||
|
url: '/cooperative/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 + "--" + item.identity;
|
||||||
|
},
|
||||||
|
templateSelection: function(item){
|
||||||
|
if (item.id) {
|
||||||
|
}
|
||||||
|
return item.real_name || item.text;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$addMemberModal.on('click', '.submit-btn', function(){
|
||||||
|
$addMemberForm.find('.error').html('');
|
||||||
|
|
||||||
|
var memberIds = $memberSelect.val();
|
||||||
|
if (memberIds && memberIds.length > 0) {
|
||||||
|
$.ajax({
|
||||||
|
method: 'POST',
|
||||||
|
dataType: 'json',
|
||||||
|
url: '/cooperative/laboratory_users',
|
||||||
|
data: { user_ids: memberIds },
|
||||||
|
success: function(data){
|
||||||
|
if(data && data.status == 0){
|
||||||
|
show_success_flash();
|
||||||
|
$addMemberModal.modal('hide');
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$addMemberModal.modal('hide');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,62 @@
|
|||||||
|
$(document).on('turbolinks:load', function() {
|
||||||
|
var $modal = $('.modal.cooperative-upload-file-modal');
|
||||||
|
if ($modal.length > 0) {
|
||||||
|
var $form = $modal.find('form.cooperative-upload-file-form')
|
||||||
|
var $sourceIdInput = $modal.find('input[name="source_id"]');
|
||||||
|
var $sourceTypeInput = $modal.find('input[name="source_type"]');
|
||||||
|
|
||||||
|
$modal.on('show.bs.modal', function(event){
|
||||||
|
var $link = $(event.relatedTarget);
|
||||||
|
var sourceId = $link.data('sourceId');
|
||||||
|
var sourceType = $link.data('sourceType');
|
||||||
|
|
||||||
|
$sourceIdInput.val(sourceId);
|
||||||
|
$sourceTypeInput.val(sourceType);
|
||||||
|
|
||||||
|
$modal.find('.upload-file-input').trigger('click');
|
||||||
|
});
|
||||||
|
|
||||||
|
$modal.find('.upload-file-input').on('change', function(e){
|
||||||
|
var file = $(this)[0].files[0];
|
||||||
|
|
||||||
|
if(file){
|
||||||
|
$modal.find('.file-names').html(file.name);
|
||||||
|
$modal.find('.submit-btn').trigger('click');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
var formValid = function(){
|
||||||
|
if($form.find('input[name="file"]').val() == undefined || $form.find('input[name="file"]').val().length == 0){
|
||||||
|
$form.find('.error').html('请选择文件');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
$modal.on('click', '.submit-btn', function(){
|
||||||
|
$form.find('.error').html('');
|
||||||
|
|
||||||
|
if (formValid()) {
|
||||||
|
var formDataString = $form.serialize();
|
||||||
|
$.ajax({
|
||||||
|
method: 'POST',
|
||||||
|
dataType: 'json',
|
||||||
|
url: '/cooperatives/files?' + formDataString,
|
||||||
|
data: new FormData($form[0]),
|
||||||
|
processData: false,
|
||||||
|
contentType: false,
|
||||||
|
success: function(data){
|
||||||
|
$.notify({ message: '上传成功' });
|
||||||
|
$modal.trigger('upload:success', data);
|
||||||
|
$modal.modal('hide');
|
||||||
|
},
|
||||||
|
error: function(res){
|
||||||
|
var data = res.responseJSON;
|
||||||
|
$form.find('.error').html(data.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,60 @@
|
|||||||
|
.cooperative-carousels-index-page {
|
||||||
|
.carousels-card {
|
||||||
|
.custom-carousel-item {
|
||||||
|
& > .drag {
|
||||||
|
cursor: move;
|
||||||
|
background: #fff;
|
||||||
|
box-shadow: 1px 2px 5px 3px #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-no {
|
||||||
|
font-size: 28px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-img {
|
||||||
|
cursor: pointer;
|
||||||
|
width: 100%;
|
||||||
|
height: 60px;
|
||||||
|
|
||||||
|
& > img {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 60px;
|
||||||
|
background: #F5F5F5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.not_active {
|
||||||
|
background: #F0F0F0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete-btn {
|
||||||
|
font-size: 20px;
|
||||||
|
color: red;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.save-url-btn {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.operate-box {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.online-check-box {
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.name-input {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
.link-input {
|
||||||
|
flex: 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,80 @@
|
|||||||
|
class Cooperative::CarouselsController < Cooperative::BaseController
|
||||||
|
before_action :convert_file!, only: [:create]
|
||||||
|
|
||||||
|
def index
|
||||||
|
@images = current_laboratory.portal_images.order(position: :asc)
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
position = current_laboratory.portal_images.count + 1
|
||||||
|
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
image = current_laboratory.portal_images.create!(create_params.merge(position: position))
|
||||||
|
|
||||||
|
file_path = Util::FileManage.disk_filename('PortalImage', image.id)
|
||||||
|
File.delete(file_path) if File.exist?(file_path) # 删除之前的文件
|
||||||
|
Util.write_file(@file, file_path)
|
||||||
|
end
|
||||||
|
|
||||||
|
flash[:success] = '保存成功'
|
||||||
|
redirect_to cooperative_carousels_path(current_laboratory)
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
current_image.update!(update_params)
|
||||||
|
render_ok
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
current_image.destroy!
|
||||||
|
# 前移
|
||||||
|
current_laboratory.portal_images.where('position > ?', current_image.position)
|
||||||
|
.update_all('position = position - 1')
|
||||||
|
|
||||||
|
file_path = Util::FileManage.disk_filename('PortalImage', current_image.id)
|
||||||
|
File.delete(file_path) if File.exist?(file_path)
|
||||||
|
end
|
||||||
|
render_delete_success
|
||||||
|
end
|
||||||
|
|
||||||
|
def drag
|
||||||
|
move = current_laboratory.portal_images.find_by(id: params[:move_id])
|
||||||
|
after = current_laboratory.portal_images.find_by(id: params[:after_id])
|
||||||
|
|
||||||
|
Admins::DragPortalImageService.call(current_laboratory, move, after)
|
||||||
|
render_ok
|
||||||
|
rescue Admins::DragPortalImageService::Error => e
|
||||||
|
render_error(e.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def current_image
|
||||||
|
@_current_image ||= current_laboratory.portal_images.find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_params
|
||||||
|
params.require(:portal_image).permit(:name, :link)
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_params
|
||||||
|
params.permit(:name, :link, :status)
|
||||||
|
end
|
||||||
|
|
||||||
|
def convert_file!
|
||||||
|
max_size = 10 * 1024 * 1024 # 10M
|
||||||
|
file = params.dig('portal_image', 'image')
|
||||||
|
if file.class == ActionDispatch::Http::UploadedFile
|
||||||
|
@file = file
|
||||||
|
render_error('请上传文件') if @file.size.zero?
|
||||||
|
render_error('文件大小超过限制') if @file.size > max_size
|
||||||
|
else
|
||||||
|
file = file.to_s.strip
|
||||||
|
return render_error('请上传正确的图片') if file.blank?
|
||||||
|
@file = Util.convert_base64_image(file, max_size: max_size)
|
||||||
|
end
|
||||||
|
rescue Base64ImageConverter::Error => ex
|
||||||
|
render_error(ex.message)
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,46 @@
|
|||||||
|
class Cooperative::FilesController < Cooperative::BaseController
|
||||||
|
before_action :convert_file!, only: [:create]
|
||||||
|
|
||||||
|
def create
|
||||||
|
File.delete(file_path) if File.exist?(file_path) # 删除之前的文件
|
||||||
|
|
||||||
|
Util.write_file(@file, file_path)
|
||||||
|
|
||||||
|
render_ok(source_id: params[:source_id], source_type: params[:source_type].to_s, url: file_url + "?t=#{Random.rand}")
|
||||||
|
rescue StandardError => ex
|
||||||
|
logger_error(ex)
|
||||||
|
render_error('上传失败')
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def convert_file!
|
||||||
|
max_size = 10 * 1024 * 1024 # 10M
|
||||||
|
if params[:file].class == ActionDispatch::Http::UploadedFile
|
||||||
|
@file = params[:file]
|
||||||
|
render_error('请上传文件') if @file.size.zero?
|
||||||
|
render_error('文件大小超过限制') if @file.size > max_size
|
||||||
|
else
|
||||||
|
file = params[:file].to_s.strip
|
||||||
|
return render_error('请上传正确的图片') if file.blank?
|
||||||
|
@file = Util.convert_base64_image(file, max_size: max_size)
|
||||||
|
end
|
||||||
|
rescue Base64ImageConverter::Error => ex
|
||||||
|
render_error(ex.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
def file_path
|
||||||
|
@_file_path ||= begin
|
||||||
|
case params[:source_type].to_s
|
||||||
|
when 'Shixun' then
|
||||||
|
Util::FileManage.disk_filename('Shixun', params[:source_id])
|
||||||
|
else
|
||||||
|
Util::FileManage.disk_filename(params[:source_type].to_s, params[:source_id].to_s)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def file_url
|
||||||
|
Util::FileManage.disk_file_url(params[:source_type].to_s, params[:source_id].to_s)
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,24 @@
|
|||||||
|
class Cooperative::LaboratoryUsersController < Cooperative::BaseController
|
||||||
|
def index
|
||||||
|
laboratory_users = current_laboratory.laboratory_users
|
||||||
|
@laboratory_users = paginate laboratory_users.includes(user: { user_extension: [:school, :department] })
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
Admins::AddLaboratoryUserService.call(current_laboratory, params.permit(user_ids: []))
|
||||||
|
render_ok
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
return render_error('不能删除自己', type: :notify) if current_laboratory_user.user_id == current_user.id
|
||||||
|
current_laboratory_user.destroy!
|
||||||
|
|
||||||
|
render_delete_success
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def current_laboratory_user
|
||||||
|
@_current_laboratory_user ||= current_laboratory.laboratory_users.find(params[:id])
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,10 @@
|
|||||||
|
class Cooperative::UsersController < Cooperative::BaseController
|
||||||
|
def index
|
||||||
|
params[:sort_by] = params[:sort_by].presence || 'created_on'
|
||||||
|
params[:sort_direction] = params[:sort_direction].presence || 'desc'
|
||||||
|
params[:school_id] = current_laboratory.school_id
|
||||||
|
|
||||||
|
users = Admins::UserQuery.call(params)
|
||||||
|
@users = paginate users.includes(user_extension: :school)
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,13 @@
|
|||||||
|
class Users::OpenUsersController < Users::BaseAccountController
|
||||||
|
def destroy
|
||||||
|
current_open_users.destroy!
|
||||||
|
|
||||||
|
render_ok
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def current_open_users
|
||||||
|
@_current_third_party ||= observed_user.open_users.find(params[:id])
|
||||||
|
end
|
||||||
|
end
|
@ -1,3 +1,9 @@
|
|||||||
class OpenUsers::QQ < OpenUser
|
class OpenUsers::QQ < OpenUser
|
||||||
|
def nickname
|
||||||
|
extra&.[]('nickname')
|
||||||
|
end
|
||||||
|
|
||||||
|
def en_type
|
||||||
|
'qq'
|
||||||
|
end
|
||||||
end
|
end
|
@ -1,3 +1,9 @@
|
|||||||
class OpenUsers::Wechat < OpenUser
|
class OpenUsers::Wechat < OpenUser
|
||||||
|
def nickname
|
||||||
|
extra&.[]('nickname')
|
||||||
|
end
|
||||||
|
|
||||||
|
def en_type
|
||||||
|
'qq'
|
||||||
|
end
|
||||||
end
|
end
|
@ -0,0 +1,4 @@
|
|||||||
|
class ShixunReview < ApplicationRecord
|
||||||
|
belongs_to :user
|
||||||
|
belongs_to :shixun
|
||||||
|
end
|
@ -0,0 +1,41 @@
|
|||||||
|
<% define_breadcrumbs do %>
|
||||||
|
<% add_breadcrumb('轮播图设置') %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<div class="card mb-5 carousels-card">
|
||||||
|
<div class="card-header d-flex justify-content-between align-items-center">
|
||||||
|
<span class="flex-1">首页轮播图<span class="text-secondary font-12">(拖动排序)</span></span>
|
||||||
|
<%= javascript_void_link '添加', class: 'btn btn-primary btn-sm add-btn', data: { toggle: 'modal', target: '.cooperative-add-carousel-modal' } %>
|
||||||
|
</div>
|
||||||
|
<div class="card-body row" id="carousels-container">
|
||||||
|
<% @images.each_with_index do |image, index| %>
|
||||||
|
<div class="col-12 custom-carousel-item custom-carousel-item-<%= image.id %>" data-id="<%= image.id %>">
|
||||||
|
<div class="border rounded relative p-3 mb-3 drag row align-items-center <%= image.online? ? '' : 'not_active' %>">
|
||||||
|
<div class="col-2 col-md-1 custom-carousel-item-no"><%= index + 1 %></div>
|
||||||
|
<div class="col-10 col-md-3 custom-carousel-item-img" data-source-id="<%= image.id %>" data-source-type="PortalImage" data-toggle="modal" data-target=".admin-upload-file-modal">
|
||||||
|
<img src="<%= Util::FileManage.exist?('PortalImage', image.id) ? Util::FileManage.disk_file_url('PortalImage', image.id) : '' %>" data-toggle="tooltip" data-title="重新上传"/>
|
||||||
|
</div>
|
||||||
|
<div class="col-10 col-md-7">
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="text" value="<%= image.name %>" class="form-control name-input" placeholder="请输入名称" />
|
||||||
|
<input type="text" value="<%= image.link %>" class="form-control link-input" placeholder="请输入跳转地址">
|
||||||
|
<div class="input-group-prepend">
|
||||||
|
<button class="input-group-text save-data-btn" data-id="<%= image.id %>">保存</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-2 col-md-1 operate-box">
|
||||||
|
<%= check_box_tag(:online, 1, image.online?, id: nil, class: 'online-check-box', data: { id: image.id, toggle: 'tooltip', title: '首页展示' }) %>
|
||||||
|
<%= delete_link '删除', cooperative_carousel_path(image, laboratory_id: image.laboratory_id, element: ".custom-carousel-item-#{image.id}", not_refresh: true), class: 'delete-btn' do %>
|
||||||
|
<i class="fa fa-trash-o" data-id="<%= image.id %>"></i>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<%= render partial: 'cooperative/carousels/shared/add_carousel_modal', locals: { laboratory_id: current_laboratory } %>
|
||||||
|
<%= render partial: 'cooperative/shared/modal/upload_file_modal' %>
|
@ -0,0 +1,36 @@
|
|||||||
|
<div class="modal fade cooperative-add-carousel-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">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<%= simple_form_for(PortalImage.new, url: cooperative_carousels_path(laboratory_id: laboratory_id), html: { class: 'cooperative-add-carousel-form', enctype: 'multipart/form-data' }) do |f| %>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="input-group">
|
||||||
|
<div class="input-group-prepend">
|
||||||
|
<span class="input-group-text">图片</span>
|
||||||
|
</div>
|
||||||
|
<div class="custom-file flex-row-reverse">
|
||||||
|
<input type="file" name="portal_image[image]" class="img-file-input" id="img-file-input" accept="image/*">
|
||||||
|
<label class="custom-file-label file-names" for="img-file-input">选择文件</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<%= f.input :name, label: '名称', placeholder: '请输入名称' %>
|
||||||
|
<%= f.input :link, as: :url, label: '跳转地址', placeholder: '请输入跳转地址' %>
|
||||||
|
|
||||||
|
<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,14 @@
|
|||||||
|
<% define_breadcrumbs do %>
|
||||||
|
<% add_breadcrumb('管理员列表', cooperative_laboratory_users_path) %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<div class="box search-form-container laboratory-user-list-form">
|
||||||
|
<div></div>
|
||||||
|
<%= javascript_void_link '添加管理员', class: 'btn btn-primary btn-sm', data: { toggle: 'modal', target: '.cooperative-add-laboratory-user-modal'} %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="box laboratory-user-list-container">
|
||||||
|
<%= render partial: 'cooperative/laboratory_users/shared/list', locals: { laboratory_users: @laboratory_users } %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<%= render 'cooperative/laboratory_users/shared/add_laboratory_user_modal' %>
|
@ -0,0 +1 @@
|
|||||||
|
$('.laboratory-user-list-container').html("<%= j(render partial: 'cooperative/laboratory_users/shared/list', locals: { laboratory_users: @laboratory_users }) %>");
|
@ -0,0 +1,28 @@
|
|||||||
|
<div class="modal fade cooperative-add-laboratory-user-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">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<form class="cooperative-add-laboratory-user-form">
|
||||||
|
<div class="form-group d-flex">
|
||||||
|
<label class="col-form-label">管理员:</label>
|
||||||
|
<div class="d-flex flex-column-reverse w-75">
|
||||||
|
<select id="user_ids" name="user_ids" class="form-control laboratory-user-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,43 @@
|
|||||||
|
<table class="table table-hover laboratory-user-list-table">
|
||||||
|
<thead class="thead-light">
|
||||||
|
<tr>
|
||||||
|
<th width="8%">头像</th>
|
||||||
|
<th width="12%" class="text-left">真实姓名</th>
|
||||||
|
<th width="20%">邮件地址</th>
|
||||||
|
<th width="20%">手机号码</th>
|
||||||
|
<th width="30%">单位部门</th>
|
||||||
|
<th width="10%">操作</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<% if laboratory_users.present? %>
|
||||||
|
<% laboratory_users.each do |laboratory_user| %>
|
||||||
|
<% user = laboratory_user.user %>
|
||||||
|
<tr class="laboratory-user-item-<%= laboratory_user.id %>">
|
||||||
|
<td class="text-left">
|
||||||
|
<%= link_to "/users/#{user.login}", target: '_blank' do %>
|
||||||
|
<img src="/images/<%= url_to_avatar(user) %>" class="rounded-circle" width="40" height="40" />
|
||||||
|
<% end %>
|
||||||
|
</td>
|
||||||
|
<td class="text-left">
|
||||||
|
<%= link_to "/users/#{user.login}", target: '_blank' do %>
|
||||||
|
<%= overflow_hidden_span user.real_name, width: 100 %>
|
||||||
|
<% end %>
|
||||||
|
</td>
|
||||||
|
<td><%= overflow_hidden_span display_text(user.mail), width: 150 %></td>
|
||||||
|
<td><%= overflow_hidden_span display_text(user.phone), width: 100 %></td>
|
||||||
|
<td><%= [user.school_name.presence, user.department_name.presence].compact.join('-') %></td>
|
||||||
|
<td class="action-container">
|
||||||
|
<% if current_user.id != laboratory_user.user_id %>
|
||||||
|
<%= delete_link '删除', cooperative_laboratory_user_path(laboratory_user, element: ".laboratory-user-item-#{laboratory_user.id}"), class: 'delete-laboratory-user-action' %>
|
||||||
|
<% end %>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
<% else %>
|
||||||
|
<%= render 'admins/shared/no_data_for_table' %>
|
||||||
|
<% end %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<%= render partial: 'cooperative/shared/paginate', locals: { objects: laboratory_users } %>
|
@ -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
|
@ -0,0 +1,16 @@
|
|||||||
|
if @content_record
|
||||||
|
json.content_info @content_record do
|
||||||
|
json.status @content_record.status
|
||||||
|
json.time format_time(@content_record.created_at)
|
||||||
|
json.username @content_record.user&.real_name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if @perfer_record
|
||||||
|
json.perference_info @perfer_record do
|
||||||
|
json.status @perfer_record.status
|
||||||
|
json.time format_time(@perfer_record.created_at)
|
||||||
|
json.username @perfer_record.user&.real_name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
|||||||
|
class AddExtraToOpenUsers < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
add_column :open_users, :extra, :text
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,12 @@
|
|||||||
|
class CreateShixunReviews < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
create_table :shixun_reviews do |t|
|
||||||
|
t.references :user
|
||||||
|
t.references :shixun
|
||||||
|
t.string :evaluate_content
|
||||||
|
t.integer :status
|
||||||
|
t.string :review_type
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
@ -0,0 +1,5 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe ShixunReview, type: :model do
|
||||||
|
pending "add some examples to (or delete) #{__FILE__}"
|
||||||
|
end
|
Loading…
Reference in new issue