Merge remote-tracking branch 'origin/dev_aliyun' into dev_aliyun

dev_aliyun_beta
杨树明 5 years ago
commit dc32a349e6

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

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

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

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

@ -26,6 +26,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>

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

@ -809,6 +809,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

@ -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');
@ -37744,6 +37917,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) {
@ -38362,6 +38679,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();

@ -18563,6 +18563,31 @@ span.CodeMirror-selectedtext {
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;
@ -19005,27 +19030,32 @@ label.error {
}
/* 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 53, app/assets/stylesheets/admin.scss */
/* line 57, app/assets/stylesheets/admin.scss */
.font-12 {
font-size: 12px !important;
}
/* line 54, app/assets/stylesheets/admin.scss */
/* line 58, app/assets/stylesheets/admin.scss */
.font-14 {
font-size: 14px !important;
}
/* line 55, app/assets/stylesheets/admin.scss */
/* line 59, app/assets/stylesheets/admin.scss */
.font-16 {
font-size: 16px !important;
}
/* line 56, app/assets/stylesheets/admin.scss */
/* line 60, app/assets/stylesheets/admin.scss */
.font-18 {
font-size: 18px !important;
}

@ -18563,6 +18563,31 @@ span.CodeMirror-selectedtext {
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;
@ -19005,27 +19030,32 @@ label.error {
}
/* 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 53, app/assets/stylesheets/admin.scss */
/* line 57, app/assets/stylesheets/admin.scss */
.font-12 {
font-size: 12px !important;
}
/* line 54, app/assets/stylesheets/admin.scss */
/* line 58, app/assets/stylesheets/admin.scss */
.font-14 {
font-size: 14px !important;
}
/* line 55, app/assets/stylesheets/admin.scss */
/* line 59, app/assets/stylesheets/admin.scss */
.font-16 {
font-size: 16px !important;
}
/* line 56, app/assets/stylesheets/admin.scss */
/* line 60, app/assets/stylesheets/admin.scss */
.font-18 {
font-size: 18px !important;
}
@ -19174,6 +19204,30 @@ label.error {
.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;

File diff suppressed because one or more lines are too long

@ -26,12 +26,13 @@ const env = getClientEnvironment(publicUrl);
// This is the development configuration.
// It is focused on developer experience and fast rebuilds.
// The production configuration is different and lives in a separate file.
// 测试用的
module.exports = {
// You may want 'eval' instead if you prefer to see the compiled output in DevTools.
// See the discussion in https://github.com/facebookincubator/create-react-app/issues/343.s
// devtool: "cheap-module-eval-source-map",
// 开启调试
devtool: "source-map", // 开启调试
// devtool: "source-map", // 开启调试
// These are the "entry points" to our application.
// This means they will be the "root" imports that are included in JS bundle.
// The first two entry points enable "hot" CSS and auto-refreshes for JS.

@ -51,9 +51,12 @@ const extractTextPluginOptions = shouldUseRelativeAssetPaths
// This is the production configuration.
// It compiles slowly and is focused on producing a fast and minimal bundle.
// The development configuration is different and lives in a separate file.
// 上线用的
// console.log('publicPath ', publicPath)
module.exports = {
// externals: {
// 'react': 'window.React'
// },
// Don't attempt to continue if there are any errors.
bail: true,
// We generate sourcemaps in production. This is slow but gives good results.

@ -3453,4 +3453,4 @@ a.singlepublishtwo{
/*.ant-notification{*/
/*width: auto !important;*/
/*max-width: 600px !important;*/
/*}*/
/*}*/

@ -15,17 +15,10 @@ class AttachmentsList extends Component{
<p key={key} className="clearfix mb3">
<a className="color-grey fl">
<i className="font-14 color-green iconfont icon-fujian mr8"></i>
</a>
{
item.is_pdf && item.is_pdf == true ?
<ConditionToolTip title={item.title} condition={item.title && item.title.length > 30 }>
<a href={item.url} className="mr12 fl task-hide" length="58" target="_blank" style={{"maxWidth":"432px"}}>{item.title}</a>
</ConditionToolTip>
:
<ConditionToolTip title={item.title} condition={item.title && item.title.length > 30 }>
<a href={item.url} className="mr12 fl task-hide" length="58" style={{"maxWidth":"432px"}}>{item.title}</a>
</ConditionToolTip>
}
</a>
<ConditionToolTip title={item.title} condition={item.title && item.title.length > 30 }>
<a href={item.url} className="mr12 fl task-hide" length="58" target={ item.is_pdf && item.is_pdf == true ? "_blank" : "_self" } style={{"maxWidth":"432px"}}>{item.title}</a>
</ConditionToolTip>
<span className="color-grey mt2 color-grey-6 font-12">{item.filesize}</span>
</p>
)

@ -7,7 +7,6 @@ import axios from 'axios';
import { TPMIndexHOC } from '../tpm/TPMIndexHOC';
import { CNotificationHOC } from './common/CNotificationHOC'
import {ImageLayerOfCommentHOC} from '../page/layers/ImageLayerOfCommentHOC'
import "./css/Courses.css"
//引入对应跳转的组件
@ -264,9 +263,26 @@ const GraduationTasksSubmiteditApp=Loadable({
loader: () => import('./graduation/tasks/GraduationTasksSubmitedit'),
loading: Loading,
})
//普通作业题库详情
const Generaljobbankdetails =Loadable({
loader: () => import('../../modules/courses/questionbank/Generaljobbankdetails'),
loading: Loading,
});
//分组作业题库详情
const GroupjobbankPage =Loadable({
loader: () => import('../../modules/courses/groupjobbank/GroupjobbankPage'),
loading: Loading,
});
//毕设选题详情
const CompletetopicdePage =Loadable({
loader: () => import('../../modules/courses/comtopicdetails/CompletetopicdePage'),
loading: Loading,
});
//毕设任务详情
const Completetaskpage =Loadable({
loader: () => import('../../modules/courses/completetaskdetails/Completetaskpage'),
loading: Loading,
});
class CoursesIndex extends Component{
constructor(props) {
super(props)
@ -445,7 +461,32 @@ class CoursesIndex extends Component{
// console.log(commons)
return (
<Switch {...this.props}>
{/*毕设任务题库详情*/}
<Route path="/courses/completetask/:workid"
render={
(props) => (<Completetaskpage {...this.props} {...props} {...this.state} />)
}
></Route>
{/*毕设内容题库详情*/}
<Route path="/courses/completetopic/:workid"
render={
(props) => (<CompletetopicdePage {...this.props} {...props} {...this.state} />)
}
></Route>
{/*GroupjobbankPage*/}
{/*分组作业题库详情*/}
<Route path="/courses/groupingwork/:workid"
render={
(props) => (<GroupjobbankPage {...this.props} {...props} {...this.state} />)
}
></Route>
{/*Generaljobbankdetails*/}
{/* 普通作业题库详情*/}
<Route path="/courses/ordinarywork/:workid"
render={
(props) => (<Generaljobbankdetails {...this.props} {...props} {...this.state} />)
}
></Route>
{/* 资源列表页 */}
<Route path="/courses/:coursesId/file/:Id" exact
render={

@ -177,6 +177,7 @@ class CommonWorkItem extends Component{
} */}
</p>
<p className="color-grey-9 clearfix">
{ item.author && <span className="mr20 fl">{item.author}</span> }
{item.commit_count===undefined?"":<span className="mr20 fl">{item.commit_count} 已交</span>}
{item.uncommit_count===undefined?"":<span className="mr20 fl">{item.uncommit_count} 未交</span>}
{

@ -0,0 +1,84 @@
import React, {Component} from "react";
import { WordsBtn,on, off, trigger,markdownToHTML,getImageUrl} from 'educoder';
import {
Button,
Checkbox,
message,
InputNumber,
DatePicker,
Radio,
Tooltip,
notification,
} from "antd";
import './completetaskdetails.css';
import GroupPackage from "../groupjobbank/GroupPackage";
import GroupPackage2 from "../groupjobbank/GroupPackage2";
class Groupjobbandetails extends Component {
constructor(props) {
super(props);
this.state = {
}
}
componentDidMount() {
console.log("Groupjobbandetails");
console.log("componentDidMount");
// let query = this.props.location.pathname;
// const type = query.split('/');
// this.setState({
// shixuntypes:type[3]
// })
// this.props.triggerRef(this);
}
// 获取数据地方
getTrainingjobsetting = () => {
var homeworkid = this.props.match.params.homeworkid;
}
//跳转道描点的地方
scrollToAnchor = (anchorName) => {
if (anchorName) {
// 找到锚点
let anchorElement = document.getElementById(anchorName);
// 如果对应id的锚点存在就跳转到锚点
if(anchorElement) { anchorElement.scrollIntoView(); }
}
};
render() {
return (
<div className=" clearfix edu-back-white" ref='targetElementTrainingjobsetting' style={{margin: "auto", minWidth:"1200px"}}>
<div className="yslquestionbank1">
<div id="MakedownHTML"className="markdown-body yslquesHeigth yslquesmarkdowntext" dangerouslySetInnerHTML={{__html: markdownToHTML("C++是C语言的面向对象扩展是C语言的一个超集同时也是历史最悠久、最受欢迎的程序设计语言之一。根据C++创始人Stroustrup的自述C++是一个“更好的C语言”。\n" +
"\n" +
"输入输出是计算机程序的基本功能。程序本质上是对数据进行处理的一系列操作,一般程序都可以分解为:“数据输入”、“数据处理”和“数据输出”三个步骤。标准输入输出(键盘输入和显示器输出)是程序的重要组成部分。\n" +
"\n" +
"本实训项目的主要目标是学习和掌握C++程序的基本结构和基本输入输出主要内容包括标准C语言自有的单个字符的输入输出、格式化的输入输出以及C++扩展的使用流对象的输入输出").replace(/▁/g, "▁▁▁")}}/>
<GroupPackage></GroupPackage>
<GroupPackage2></GroupPackage2>
</div>
</div>
)
}
}
export default Groupjobbandetails;

@ -0,0 +1,138 @@
import React, {Component} from "react";
import {Link, NavLink} from 'react-router-dom';
import {WordsBtn, ActionBtn} from 'educoder';
import axios from 'axios';
import {
notification
} from "antd";
import CoursesListType from '../coursesPublic/CoursesListType';
import Completetaskdetails from './Completetaskdetails';
import '../css/members.css';
import "../common/formCommon.css";
import '../css/Courses.css';
import '../css/busyWork.css';
import '../poll/pollStyle.css';
class Completetaskpage extends Component {
//分组作业内容详情
constructor(props) {
super(props);
// this.answerMdRef = React.createRef();
this.setState({
workid:1,
isSpin:false,
datas:[],
})
}
componentDidMount() {
// console.log("父组件加载框");
if( this.props.match.params.workid){
this.setState({
workid: this.props.match.params.workid,
})
}
this.getdata(this.props.match.params.workid);
}
// 获取数据的地方
getdata=(workid)=>{
var workids= workid;
if(workids){
}else{
workids=this.state.workid;
}
this.setState({
isSpin:true,
})
let url = `/homework_banks/${workids}.json`;
//
axios.get(url).then((response) => {
if(response){
if(response.data){
this.setState({
datas:response.data.informs,
})
}else {
this.setState({
datas:[],
})
}
}else {
this.setState({
datas:[],
})
}
this.setState({
isSpin:false,
})
}).catch((error) => {
console.log(error)
this.setState({
datas:[],
isSpin:false,
})
});
}
bindRef = ref => { this.child = ref }
///////////////教师截止
render() {
const isAdmin = this.props.isAdmin();
// console.log(119)
return (
<div className="newMain clearfix ">
<div className={"educontent mt10 mb20"} style={{width: "1200px"}}>
<div className="educontent mb20">
<p className="clearfix mb20 mt10">
<a className="btn colorgrey fl hovercolorblue ">题库</a>
<span className="color-grey-9 fl ml3 mr3">&gt;</span>
<a
className=" btn colorgrey fl hovercolorblue "
>详情</a>
</p>
</div>
<div className="educontent mb20">
<p className=" fl color-black summaryname" style={{heigth: "33px"}}>
MySQL数据库编程开发实训基础篇
</p>
<CoursesListType
typelist={["公开"]}
/>
</div>
<div className="edu-back-white ">
<div className="stud-class-set bor-bottom-greyE ">
<div className=" clearfix edu-back-white poll_list">
<a className={"active ml12"}>内容详情</a>
<a className="fr color-blue font-16" >发送</a>
<a className="fr color-blue font-16" >编辑</a>
<a className="fr color-blue font-16" >删除</a>
</div>
</div>
</div>
<Completetaskdetails/>
</div>
</div>
)
}
}
export default Completetaskpage;

@ -0,0 +1,58 @@
.yslquestionbank1{
padding-top: 30px !important;
padding-right: 30px !important;
padding-left: 30px !important;
}
.yslquesHeigth{
min-height: 500px !important;
}
.yslquesmarkdowntext{
font-size: 16px;
color: #707070;
}
.yslquesmat26{
margin-top: 26px;
padding-bottom: 33px !important;
}
.ysltextcolor9999{
color: #999999;
font-size: 14px;
}
.ysltextcolor66{
color: #666666;
font-size: 14px;
}
.ysltextcolor05{
color: #05101A;
font-size: 14px;
}
.ml47text{
margin-left: 17px;
padding-bottom: 37px;
}
.ysltextcolor99999{
color: #999999;
font-size: 16px;
}
.yslboomdivs{
display: flex;
justify-content:flex-start;
}
.yslboomdivs p{
width: 282px;
}
.yslboomdivs p span {
text-align: left;
}
.yslboomdivsy{
color: #999999;
font-size: 14px;
}
.yslboomdivsys{
color: #666666;
font-size: 14px;
}

@ -0,0 +1,141 @@
import React, {Component} from "react";
import {Link, NavLink} from 'react-router-dom';
import {WordsBtn, ActionBtn} from 'educoder';
import { Input,Checkbox,Table, Pagination, Modal,Menu, Tooltip,Spin,Button,Form } from "antd";
import axios from 'axios';
import {
notification
} from "antd";
import CoursesListType from '../coursesPublic/CoursesListType';
import Completetopicdetails from './Completetopicdetails';
import '../css/members.css';
import "../common/formCommon.css";
import '../css/Courses.css';
import '../css/busyWork.css';
import '../poll/pollStyle.css';
class CompletetopicdePage extends Component {
//毕设选题内容详情
constructor(props) {
super(props);
// this.answerMdRef = React.createRef();
this.setState({
workid:1,
isSpin:false,
datas:[],
})
}
componentDidMount() {
if( this.props.match.params.workid){
this.setState({
workid: this.props.match.params.workid,
})
}
this.getdata(this.props.match.params.workid);
}
//获取数据的地方
getdata=(workid)=>{
var workids= workid;
if(workids){
}else{
workids=this.state.workid;
}
this.setState({
isSpin:true,
})
let url = `/homework_banks/${workids}.json`;
//
axios.get(url).then((response) => {
if(response){
if(response.data){
this.setState({
datas:response.data.informs,
})
}else {
this.setState({
datas:[],
})
}
}else {
this.setState({
datas:[],
})
}
this.setState({
isSpin:false,
})
}).catch((error) => {
console.log(error)
this.setState({
datas:[],
isSpin:false,
})
});
}
/// 确认是否下载
bindRef = ref => { this.child = ref }
///////////////教师截止
render() {
const isAdmin = this.props.isAdmin();
// console.log(119)
return (
<div className="newMain clearfix ">
<div className={"educontent mt10 mb20"} style={{width: "1200px"}}>
<div className="educontent mb20">
<p className="clearfix mb20 mt10">
<a className="btn colorgrey fl hovercolorblue ">题库</a>
<span className="color-grey-9 fl ml3 mr3">&gt;</span>
<a
className=" btn colorgrey fl hovercolorblue "
>详情</a>
</p>
</div>
<div className="educontent mb20">
<p className=" fl color-black summaryname" style={{heigth: "33px"}}>
MySQL数据库编程开发实训基础篇
</p>
<CoursesListType
typelist={["公开"]}
/>
</div>
<div className="edu-back-white ">
<div className="stud-class-set bor-bottom-greyE ">
<div className=" clearfix edu-back-white poll_list">
<a className="active ml12" >内容详情</a>
<a className="fr color-blue font-16" >发送</a>
<a className="fr color-blue font-16" >编辑</a>
<a className="fr color-blue font-16" >删除</a>
</div>
</div>
</div>
<Completetopicdetails/>
{/*{parseInt(tab) === 1 ? <Completetopicdeswer/>:""}*/}
</div>
</div>
)
}
}
export default CompletetopicdePage;

@ -0,0 +1,115 @@
import React, {Component} from "react";
import { WordsBtn,on, off, trigger,markdownToHTML,getImageUrl} from 'educoder';
import {
Button,
Checkbox,
message,
InputNumber,
DatePicker,
Radio,
Tooltip,
notification,
} from "antd";
import GroupPackage from '../groupjobbank/GroupPackage'
import './completetopicde.css';
class Completetopicdetails extends Component {
constructor(props) {
super(props);
this.state = {
}
}
componentDidMount() {
console.log("Generaljobdetails");
console.log("componentDidMount");
// let query = this.props.location.pathname;
// const type = query.split('/');
// this.setState({
// shixuntypes:type[3]
// })
// this.props.triggerRef(this);
}
// 获取数据地方
getTrainingjobsetting = () => {
var homeworkid = this.props.match.params.homeworkid;
}
//跳转道描点的地方
scrollToAnchor = (anchorName) => {
if (anchorName) {
// 找到锚点
let anchorElement = document.getElementById(anchorName);
// 如果对应id的锚点存在就跳转到锚点
if(anchorElement) { anchorElement.scrollIntoView(); }
}
};
render() {
return (
<div className=" clearfix edu-back-white " ref='targetElementTrainingjobsetting' style={{margin: "auto", minWidth:"1200px"}}>
<div className="bor-bottom-greyE">
<div className="yslquestionbank1">
<div id="MakedownHTML"className="markdown-body yslquesHeigth yslquesmarkdowntext" dangerouslySetInnerHTML={{__html: markdownToHTML("C++是C语言的面向对象扩展是C语言的一个超集同时也是历史最悠久、最受欢迎的程序设计语言之一。根据C++创始人Stroustrup的自述C++是一个“更好的C语言”。\n" +
"\n" +
"输入输出是计算机程序的基本功能。程序本质上是对数据进行处理的一系列操作,一般程序都可以分解为:“数据输入”、“数据处理”和“数据输出”三个步骤。标准输入输出(键盘输入和显示器输出)是程序的重要组成部分。\n" +
"\n" +
"本实训项目的主要目标是学习和掌握C++程序的基本结构和基本输入输出主要内容包括标准C语言自有的单个字符的输入输出、格式化的输入输出以及C++扩展的使用流对象的输入输出").replace(/▁/g, "▁▁▁")}}/>
<GroupPackage></GroupPackage>
</div>
</div>
<div style={{width:"100%", padding: "36px"}}>
<div className="yslboomdivs">
<p>
<span className="yslboomdivsy">课题类型</span>
<span className="yslboomdivsys">设计</span>
</p>
<p>
<span className="yslboomdivsy">课题来源</span>
<span className="yslboomdivsys">生产/社会实践</span>
</p>
<p>
<span className="yslboomdivsy">课题性质1</span>
<span className="yslboomdivsys">设计</span>
</p>
<p>
<span className="yslboomdivsy">课题性质2</span>
<span className="yslboomdivsys">设计</span>
</p>
</div>
<div className="yslboomdivs">
<p>
<span className="yslboomdivsy">课题重复情况 </span>
<span className="yslboomdivsys">新需求</span>
</p>
<p>
<span className="yslboomdivsy">调研或实习地点</span>
<span className="yslboomdivsys">长沙</span>
</p>
<p style={{width:"564px"}}>
<span className="yslboomdivsy">课题单位来源</span>
<span className="yslboomdivsys">湖南省据C++创始人Stroustrup有限公司</span>
</p>
</div>
</div>
</div>
)
}
}
export default Completetopicdetails;

@ -0,0 +1,58 @@
.yslquestionbank1{
padding-top: 30px !important;
padding-right: 30px !important;
padding-left: 30px !important;
}
.yslquesHeigth{
min-height: 500px !important;
}
.yslquesmarkdowntext{
font-size: 16px;
color: #707070;
}
.yslquesmat26{
margin-top: 26px;
padding-bottom: 33px !important;
}
.ysltextcolor9999{
color: #999999;
font-size: 14px;
}
.ysltextcolor66{
color: #666666;
font-size: 14px;
}
.ysltextcolor05{
color: #05101A;
font-size: 14px;
}
.ml47text{
margin-left: 17px;
padding-bottom: 37px;
}
.ysltextcolor99999{
color: #999999;
font-size: 16px;
}
.yslboomdivs{
display: flex;
justify-content:flex-start;
}
.yslboomdivs p{
width: 282px;
}
.yslboomdivs p span {
text-align: left;
}
.yslboomdivsy{
color: #999999;
font-size: 14px;
}
.yslboomdivsys{
color: #666666;
font-size: 14px;
}

@ -1061,8 +1061,14 @@ samp {
.newcoursestitle{
font-size: 12px;
color: #989898;
margin-left: 10px;
margin-left: 40px;
}
.newcoursestitleysl{
font-size: 12px;
color: #989898;
margin-left: 51px;
}
.coursenavbox .ant-form-item-label{
margin-left:10px;

@ -134,6 +134,7 @@ class ExerciseListItem extends Component{
{/*</li>*/}
</p>
<p className="color-grey-9 clearfix">
{ item.author && <span className="mr20 fl">{item.author}</span> }
{item.exercise_status===1?"":<span className="mr20 fl">{item.exercise_answer} 已答</span>}
{item.exercise_status===1?"":<span className="mr20 fl">{item.exercise_unanswer} 未答</span>}
{item.unreview_count===null||item.exercise_status===1?"":<span className="mr20 fl">{item.unreview_count} 未评数</span> }

@ -553,6 +553,9 @@ class ExerciseReviewAndAnswer extends Component{
height:16px;
margin-top:2px;
}
.standardAnswer.editormd-html-preview,.answerStyle.editormd-html-preview{
width:100%!important
}
`}</style>
{/*<p style={{height:"60px"}}></p>*/}
<Modals
@ -716,7 +719,7 @@ class ExerciseReviewAndAnswer extends Component{
<span className="fr">
{
// 填空(一直都有调分),和简答题调分:老师身份 已经评分的才能出现调分按钮
isAdmin && ((parseInt(item.answer_status) == 1 && item.question_type == 4) || item.question_type == 3) ?
isAdmin && ((parseInt(item.answer_status) != 0 && item.question_type == 4) || item.question_type == 3) ?
<WordsBtn style="blue" className="mr20 font-16 fl" onClick={()=>this.showSetScore(key,item.setScore,item.q_position+"_"+item.question_type)}>调分</WordsBtn>:""
}
{
@ -724,11 +727,17 @@ class ExerciseReviewAndAnswer extends Component{
isAdmin && parseInt(item.answer_status) == 0 && item.question_type == 4 ?
<span className="color-red fl mr20">未批</span>:""
}
{
// 客观题:老师||学生(试卷已截止且答案公开)显示正确答案
item.question_type < 3 && item.standard_answer_show ?
<span className="font-16 ml20">
正确答案{ item.standard_answer_show }
</span>:""
}
{
//(老师身份且除实训题外) || (学生身份且试卷已经截止)就显示用户当前题目所得分数
( isAdmin || (isStudent && exercise.exercise_status == 3)) && item.question_type != 5 && item.user_score ?
<span className="font-16 ml20">
<i className={parseInt(item.answer_status) ==0 ? "iconfont icon-htmal5icon19 color-red font-20 fl":parseInt(item.answer_status) ==1 ? "fl iconfont icon-wancheng font-20 color-green" :"iconfont icon-htmal5icon19 color-orange-tip font-20 fl"}></i>
<span><span className={parseInt(item.answer_status) == 0 ?"color-red":parseInt(item.answer_status) == 1 ?"color-green":"color-orange-tip"}>{item.user_score}</span> </span>
</span> : ""
}

@ -195,8 +195,8 @@ class SingleEditor extends Component{
<div>
<RadioGroup onChange={this.onOptionClick} value={standard_answers[0]}>
{/* disabled={exerciseIsPublish} */}
<Radio value={true} ></Radio>
<Radio value={false} ></Radio>
<Radio value={true} >正确</Radio>
<Radio value={false} ></Radio>
</RadioGroup>
{/* not work */}
{/* <Radio value={standard_answers[0]} onClick={() => this.onOptionClick(0)} disabled={exerciseIsPublish}></Radio>

@ -108,7 +108,7 @@ class fillEmpty extends Component{
array.map((item,key)=>{
return(
<li className="df mb10 emptyPanel">
<span className="mr10 lineh-35 font-16">答案(填空{key+1})</span>
<span className="mr10 lineh-35 font-16">答案填空{key+1}:</span>
<div className="flex1" style={{width:"0"}}>
{
user_exercise_status == 1 ?
@ -135,7 +135,7 @@ class fillEmpty extends Component{
{ questionType.standard_answer && questionType.standard_answer.map((item,k)=>{
return(
<ul className="df font-16">
<span className="mr10">填空{k+1}:</span>
<span className="mr10">答案填空{k+1}:</span>
<li className="flex1">
{
item.answer_text && item.answer_text.map((i,index)=>{

@ -59,7 +59,7 @@ class Bullsubdirectory extends Component{
}
};
changeTopicName = (e) => {
console.log("调用了changeTopicName");
// console.log("调用了changeTopicName");
let num = e.target.value.length;
if(num>60){

@ -107,7 +107,7 @@ class Eduinforms extends Component{
}
};
changeTopicName = (e) => {
console.log("调用了changeTopicName");
// console.log("调用了changeTopicName");
let num = e.target.value.length;
if(num>60){
return;

@ -0,0 +1,87 @@
import React, {Component} from "react";
import { WordsBtn,on, off, trigger,markdownToHTML,getImageUrl} from 'educoder';
import {
Button,
Checkbox,
message,
InputNumber,
DatePicker,
Radio,
Tooltip,
notification,
} from "antd";
import './questionbanks.css';
class GroupPackage extends Component {
constructor(props) {
super(props);
this.state = {
}
}
componentDidMount() {
console.log("Groupjobquesanswer");
console.log("componentDidMount");
// let query = this.props.location.pathname;
// const type = query.split('/');
// this.setState({
// shixuntypes:type[3]
// })
// this.props.triggerRef(this);
}
// 获取数据地方
getTrainingjobsetting = () => {
var homeworkid = this.props.match.params.homeworkid;
}
//跳转道描点的地方
scrollToAnchor = (anchorName) => {
if (anchorName) {
// 找到锚点
let anchorElement = document.getElementById(anchorName);
// 如果对应id的锚点存在就跳转到锚点
if(anchorElement) { anchorElement.scrollIntoView(); }
}
};
render() {
return (
<div className="color-grey df yslquesmat26" key={0} style={{ lineHeight: '17px'}}>
<a className="color-grey ">
<i className="font-14 color-green iconfont icon-fujian mr8" aria-hidden="true"></i>
</a>
<style>
{
`
a:hover {
color: #459be5 !important;
}
a:link, a:visited {
text-decoration: none;
color: #999999 !important;
}
`
}
</style>
<a href={"/"} title={''}
className="mr12 yslahover overflowHidden1" length="58" style={{maxWidth:'480px',fontSize:"16px",}}>
<span>清除浏览器缓存或换个浏览器操作指南更新版本.zip</span>
</a>
<span className="color656565 color-grey-6 font-12 mr8">{2}</span>
</div>
)
}
}
export default GroupPackage;

@ -0,0 +1,73 @@
import React, {Component} from "react";
import { WordsBtn,on, off, trigger,markdownToHTML,getImageUrl} from 'educoder';
import {
Button,
Checkbox,
message,
InputNumber,
DatePicker,
Radio,
Tooltip,
notification,
} from "antd";
import './questionbanks.css';
class GroupPackage extends Component {
constructor(props) {
super(props);
this.state = {
}
}
componentDidMount() {
console.log("Groupjobquesanswer");
console.log("componentDidMount");
// let query = this.props.location.pathname;
// const type = query.split('/');
// this.setState({
// shixuntypes:type[3]
// })
// this.props.triggerRef(this);
}
// 获取数据地方
getTrainingjobsetting = () => {
var homeworkid = this.props.match.params.homeworkid;
}
//跳转道描点的地方
scrollToAnchor = (anchorName) => {
if (anchorName) {
// 找到锚点
let anchorElement = document.getElementById(anchorName);
// 如果对应id的锚点存在就跳转到锚点
if(anchorElement) { anchorElement.scrollIntoView(); }
}
};
render() {
return (
<div className="ml47text">
<p>
<span className="ysltextcolor66">分组要求</span>
<span className="ysltextcolor05">2~ 5学生提交作品时需要关联同组成员组内成员作品共享</span>
</p>
<p>
<span className="ysltextcolor66">基于项目实施</span>
<span className="ysltextcolor05">学生必须在本平台创建项目项目管理员可以提交作品</span>
</p>
</div>
)
}
}
export default GroupPackage;

@ -0,0 +1,84 @@
import React, {Component} from "react";
import { WordsBtn,on, off, trigger,markdownToHTML,getImageUrl} from 'educoder';
import {
Button,
Checkbox,
message,
InputNumber,
DatePicker,
Radio,
Tooltip,
notification,
} from "antd";
import './questionbanks.css';
import GroupPackage from "./GroupPackage";
import GroupPackage2 from "./GroupPackage2";
class Groupjobbandetails extends Component {
constructor(props) {
super(props);
this.state = {
}
}
componentDidMount() {
console.log("Groupjobbandetails");
console.log("componentDidMount");
// let query = this.props.location.pathname;
// const type = query.split('/');
// this.setState({
// shixuntypes:type[3]
// })
// this.props.triggerRef(this);
}
// 获取数据地方
getTrainingjobsetting = () => {
var homeworkid = this.props.match.params.homeworkid;
}
//跳转道描点的地方
scrollToAnchor = (anchorName) => {
if (anchorName) {
// 找到锚点
let anchorElement = document.getElementById(anchorName);
// 如果对应id的锚点存在就跳转到锚点
if(anchorElement) { anchorElement.scrollIntoView(); }
}
};
render() {
return (
<div className=" clearfix edu-back-white" ref='targetElementTrainingjobsetting' style={{margin: "auto", minWidth:"1200px"}}>
<div className="yslquestionbank1">
<div id="MakedownHTML"className="markdown-body yslquesHeigth yslquesmarkdowntext" dangerouslySetInnerHTML={{__html: markdownToHTML("C++是C语言的面向对象扩展是C语言的一个超集同时也是历史最悠久、最受欢迎的程序设计语言之一。根据C++创始人Stroustrup的自述C++是一个“更好的C语言”。\n" +
"\n" +
"输入输出是计算机程序的基本功能。程序本质上是对数据进行处理的一系列操作,一般程序都可以分解为:“数据输入”、“数据处理”和“数据输出”三个步骤。标准输入输出(键盘输入和显示器输出)是程序的重要组成部分。\n" +
"\n" +
"本实训项目的主要目标是学习和掌握C++程序的基本结构和基本输入输出主要内容包括标准C语言自有的单个字符的输入输出、格式化的输入输出以及C++扩展的使用流对象的输入输出").replace(/▁/g, "▁▁▁")}}/>
<GroupPackage></GroupPackage>
<GroupPackage2></GroupPackage2>
</div>
</div>
)
}
}
export default Groupjobbandetails;

@ -0,0 +1,175 @@
import React, {Component} from "react";
import {Link, NavLink} from 'react-router-dom';
import {WordsBtn, ActionBtn} from 'educoder';
import { Input,Checkbox,Table, Pagination, Modal,Menu, Tooltip,Spin,Button,Form } from "antd";
import axios from 'axios';
import {
notification
} from "antd";
import CoursesListType from '../coursesPublic/CoursesListType';
import Groupjobbandetails from './Groupjobbandetails';
import Groupjobquesanswer from './Groupjobquesanswer';
import '../css/members.css';
import "../common/formCommon.css";
import '../css/Courses.css';
import '../css/busyWork.css';
import '../poll/pollStyle.css';
class GroupjobbankPage extends Component {
//分组作业内容详情
constructor(props) {
super(props);
// this.answerMdRef = React.createRef();
this.state = {
tab: ["0"],
workid:1,
isSpin:false,
datas:[],
}
}
//切换tab
ChangeTab = (e) => {
// console.log(e);
this.setState({
tab: e
})
try {
var currenturl = window.location.href;
var newUrl = (currenturl.split("?"))[0];
window.history.pushState('','',newUrl+'?tab='+e);
}catch (e) {
console.log(e);
console.log("44");
}
}
componentDidMount() {
// console.log("父组件加载框");
const query = this.props.location.search;
const type = query.split('?tab=');
// let sum = []
// sum.push(type[1])
// console.log("componentDidMountcomponentDidMount");
// console.log(type);
this.setState({
tab: type[1],
})
let querys = this.props.location.pathname;
const types = querys.split('/');
// console.log(types);
this.setState({
shixuntypes: types[3]
})
if( this.props.match.params.workid){
this.setState({
workid: this.props.match.params.workid,
})
}
this.getdata(this.props.match.params.workid);
}
///获取数据的地方
getdata=(workid)=>{
var workids= workid;
if(workids){
}else{
workids=this.state.workid;
}
this.setState({
isSpin:true,
})
let url = `/homework_banks/${workids}.json`;
//
axios.get(url).then((response) => {
if(response){
if(response.data){
this.setState({
datas:response.data.informs,
})
}else {
this.setState({
datas:[],
})
}
}else {
this.setState({
datas:[],
})
}
this.setState({
isSpin:false,
})
}).catch((error) => {
console.log(error)
this.setState({
datas:[],
isSpin:false,
})
});
}
bindRef = ref => { this.child = ref }
///////////////教师截止
render() {
let {tab} = this.state;
const isAdmin = this.props.isAdmin();
// console.log(119)
return (
<div className="newMain clearfix ">
<div className={"educontent mt10 mb20"} style={{width: "1200px"}}>
<div className="educontent mb20">
<p className="clearfix mb20 mt10">
<a className="btn colorgrey fl hovercolorblue ">题库</a>
<span className="color-grey-9 fl ml3 mr3">&gt;</span>
<a
className=" btn colorgrey fl hovercolorblue "
>详情</a>
</p>
</div>
<div className="educontent mb20">
<p className=" fl color-black summaryname" style={{heigth: "33px"}}>
MySQL数据库编程开发实训基础篇
</p>
<CoursesListType
typelist={["公开"]}
/>
</div>
<div className="edu-back-white ">
<div className="stud-class-set bor-bottom-greyE ">
<div className=" clearfix edu-back-white poll_list">
<a className={parseInt(tab) === 0 ? "active ml12" : "ml12"} onClick={(e) => this.ChangeTab(0)}>内容详情</a>
<a className={parseInt(tab) === 1 ? "active ml12" : "ml12"} onClick={(e) => this.ChangeTab(1)}>参考答案</a>
<a className="fr color-blue font-16" >发送</a>
<a className="fr color-blue font-16" >编辑</a>
<a className="fr color-blue font-16" >删除</a>
</div>
</div>
</div>
<Spin size="large" spinning={this.state.isSpin} id={"cdiv"}>
{parseInt(tab) === 0 ? <Groupjobbandetails/>:""}
{parseInt(tab) === 1 ? <Groupjobquesanswer/>:""}
</Spin>
</div>
</div>
)
}
}
export default GroupjobbankPage;

@ -0,0 +1,82 @@
import React, {Component} from "react";
import { WordsBtn,on, off, trigger,markdownToHTML,getImageUrl} from 'educoder';
import {
Button,
Checkbox,
message,
InputNumber,
DatePicker,
Radio,
Tooltip,
notification,
} from "antd";
import GroupPackage from './GroupPackage';
import GroupPackage2 from './GroupPackage2';
import './questionbanks.css';
class Groupjobquesanswer extends Component {
constructor(props) {
super(props);
this.state = {
}
}
componentDidMount() {
console.log("Groupjobquesanswer");
console.log("componentDidMount");
// let query = this.props.location.pathname;
// const type = query.split('/');
// this.setState({
// shixuntypes:type[3]
// })
// this.props.triggerRef(this);
}
// 获取数据地方
getTrainingjobsetting = () => {
var homeworkid = this.props.match.params.homeworkid;
}
//跳转道描点的地方
scrollToAnchor = (anchorName) => {
if (anchorName) {
// 找到锚点
let anchorElement = document.getElementById(anchorName);
// 如果对应id的锚点存在就跳转到锚点
if(anchorElement) { anchorElement.scrollIntoView(); }
}
};
render() {
return (
<div className=" clearfix edu-back-white" ref='targetElementTrainingjobsetting' style={{margin: "auto", minWidth:"1200px"}}>
<div className="yslquestionbank1">
<div id="MakedownHTML"className="markdown-body yslquesHeigth yslquesmarkdowntext" dangerouslySetInnerHTML={{__html: markdownToHTML("C++是C语言的面向对象扩展是C语言的一个超集同时也是历史最悠久、最受欢迎的程序设计语言之一。根据C++创始人Stroustrup的自述C++是一个“更好的C语言”。\n" +
"\n" +
"输入输出是计算机程序的基本功能。程序本质上是对数据进行处理的一系列操作,一般程序都可以分解为:“数据输入”、“数据处理”和“数据输出”三个步骤。标准输入输出(键盘输入和显示器输出)是程序的重要组成部分。\n" +
"\n" +
"本实训项目的主要目标是学习和掌握C++程序的基本结构和基本输入输出主要内容包括标准C语言自有的单个字符的输入输出、格式化的输入输出以及C++扩展的使用流对象的输入输出").replace(/▁/g, "▁▁▁")}}/>
<GroupPackage></GroupPackage>
<GroupPackage2></GroupPackage2>
</div>
</div>
)
}
}
export default Groupjobquesanswer;

@ -0,0 +1,41 @@
.yslquestionbank1{
padding-top: 30px !important;
padding-right: 30px !important;
padding-left: 30px !important;
}
.yslquesHeigth{
min-height: 500px !important;
}
.yslquesmarkdowntext{
font-size: 16px;
color: #707070;
}
.yslquesmat26{
margin-top: 26px;
padding-bottom: 33px !important;
}
.ysltextcolor9999{
color: #999999;
font-size: 14px;
}
.ysltextcolor66{
color: #666666;
font-size: 14px;
}
.ysltextcolor05{
color: #05101A;
font-size: 14px;
}
.ml47text{
margin-left: 17px;
padding-bottom: 37px;
}
.ysltextcolor99999{
color: #999999;
font-size: 16px;
}
.yslahover {
color: #999999 ;
}

@ -129,7 +129,7 @@ class studentsList extends Component{
}
/// 确认是否下载
confirmysl(url){
axios.get(url + '&export=true').then((response) => {
axios.get(url).then((response) => {
if(response === undefined){
return
}
@ -506,9 +506,12 @@ class studentsList extends Component{
const { course_group_name, invite_code } = this.state;
const courseId = this.props.match.params.coursesId
let exportUrl = `/courses/${courseId}/export_member_scores_excel.xlsx?`
let exportUrl = `/courses/${courseId}/export_member_scores_excel.xlsx?`; //总成绩
let exportUrltwo = `/courses/${courseId}/export_couser_info.xlsx?`; //课堂信息
let exportUrlthree = `/courses/${courseId}/export_member_act_score.xlsx?`; //活跃度
const params = {}
if (course_group_id) {
if (checkBoxValues) {
params.group_id = course_group_id
}
if (searchValue) {
@ -522,6 +525,11 @@ class studentsList extends Component{
paramsString += `${key}=${params[key]}&`
}
exportUrl += paramsString;
exportUrltwo+=paramsString;
exportUrlthree+=paramsString;
// console.log(paramsString);
// console.log(checkBoxValues);
// console.log(searchValue);
return(
<React.Fragment >
<DownloadMessageysl
@ -567,7 +575,41 @@ class studentsList extends Component{
{ isAdmin && isParent && <WordsBtn style="blue" className="mr30" onClick={()=>this.addDir()}>添加分班</WordsBtn> }
{ isAdmin && !isParent && course_group_id != 0 && <WordsBtn style="blue" className="mr30" onClick={()=>this.deleteDir()}>删除分班</WordsBtn> }
{ isAdmin && !isParent && course_group_id != 0 && <WordsBtn style="blue" className="mr30" onClick={()=>this.renameDir()}>分班重命名</WordsBtn> }
{ isAdmin && <WordsBtn style="blue" className="" onClick={(url)=>this.confirmysl(exportUrl)} >导出成绩</WordsBtn> }
<style>{`
.drop_down_menu li a {
padding: 0px;
font-size: 14px;
}
.drop_down_menu {
width: 93px;
}
.drop_down_menu li {
overflow: visible;
width: 93px;
}
.drop_down_menu, .drop_down_normal {
padding-top: 10px;
padding-bottom: 8px;
}
`}</style>
{ isAdmin &&
<li className="li_line drop_down fr color-blue font-16">
导出<i className="iconfont icon-xiajiantou font-12 ml2"></i>
<ul className="drop_down_menu" style={{"right": "-20px", "left": "unset", "height": "auto"}}>
<li><a
onClick={(i) => this.confirmysl(exportUrltwo)}>课堂信息</a>
</li>
<li><a
onClick={(i) => this.confirmysl(exportUrlthree)}>活跃度</a>
</li>
<li><a
onClick={(i) => this.confirmysl(exportUrl)}>总成绩</a>
</li>
</ul>
</li>
}
{/*<WordsBtn style="blue" className="" onClick={(url)=>this.confirmysl(exportUrl)} >导出成绩</WordsBtn>*/}
{/* */}
</React.Fragment>
}
@ -576,60 +618,6 @@ class studentsList extends Component{
}
onPressEnter={this.onPressEnter}
></Titlesearchsection>
{/* <div className="edu-back-white">
<p className="clearfix padding30 bor-bottom-greyE">
<span className="font-18 fl color-dark-21">学生列表</span>
<span className="color-grey-9 fl font-16 ml10 lineh-15 mt3">邀请码<span className="color-orange-tip">CKPYL</span></span>
<li className="fr">
<a href="javascript:void(0)" className="color-blue mr30">导入创建分班</a>
<WordsBtn style="blue" className="mr30" onClick={()=>this.showStuNewBox(1)}>新建分班</WordsBtn>
<a href="javascript:void(0)" className="color-blue mr30" onClick={()=>this.delClasses()}>删除分班</a>
<a href="javascript:void(0)" className="color-blue mr30" onClick={()=>this.showStuNewBox(2)}>分班重命名</a>
<a href="javascript:void(0)" className="color-blue">导出成绩</a>
</li>
</p>
<div className="clearfix pl30 pr30">
<span className="fl mt22"><label className="color-orange-tip ml3 mr3">6</label></span>
<div className="fr mt16 mb16 searchView">
<Search
value={StudentList_value}
placeholder="请输入姓名进行搜索"
onInput={this.inputStudent}
></Search>
</div>
</div>
<Modals
modalsType={modalsType}
modalsTopval={modalsTopval}
modalsBottomval={modalsBottomval}
modalCancel={this.cancelDelClasses}
modalSave={this.sureDelClasses}
>
</Modals>
<Modal
title={n_And_e==1?"新建分班":"分班重命名"}
visible={stu_new_flag}
closable={false}
footer={null}
destroyOnClose={true}
centered={true}
>
<div className="newupload_conbox clearfix">
<div className="df">
<span className="fl mr20 lineh-40">分班</span>
<Input placeholder="示例分班最佳4个字符" className="input-flex-40"/>
</div>
<div className="mt30 marginauto clearfix edu-txt-center">
<a onClick={this.hideStuNewBox} className="pop_close task-btn mr30">取消</a>
<a className="task-btn task-btn-orange" id="submit_send_shixun">确定</a>
</div>
</div>
</Modal>
</div> */}
{
total_count > 0 || this.state.isSpin == true ?
<div className="mt20 edu-back-white padding20">

@ -47,9 +47,7 @@ class CoursesNew extends Component {
checkboxgroup:undefined,
addonAfteronelenone:0,
addonAfteronelentwo:0,
checkbofrup:[{module_type:"shixun_homework",module_name:"实训作业"},{module_type:"common_homework",module_name:"普通作业"},{module_type:"group_homework",module_name:"分组作业"}
,{module_type:"exercise",module_name:"试卷"},{module_type:"poll",module_name:"问卷"},{module_type:"graduation",module_name:"毕业设计"}
,{module_type:"board",module_name:"讨论"},{module_type:"attachment",module_name:"资源"},{module_type:"course_group",module_name:"分班"}],
bordebool:false,
}
}
componentDidMount() {
@ -364,14 +362,16 @@ class CoursesNew extends Component {
search:value
}).then((result)=>{
// console.log(result.data)
if (result.data.message===undefined) {
if(result){
if (result.data.message===undefined) {
this.setState({
searchlist: result.data.course_lists,
// course:value,
this.setState({
searchlist: result.data.course_lists,
// course:value,
})
}
})
}
}
// this.props.form.setFieldsValue({
// course:value
// })
@ -380,8 +380,8 @@ class CoursesNew extends Component {
})
}
handleSearch=(value)=>{
console.log("handleSearchhandleSearch");
console.log(value);
if(value!=""){
this.props.form.setFieldsValue({
classroom:value,
@ -391,13 +391,40 @@ class CoursesNew extends Component {
}
};
handleSearchsysl=(value)=>{
if(value){
this.props.form.setFieldsValue({
classroom:value,
// course:value
});
}
}
handleChange=(value)=>{
handleChange=(e)=>{
this.props.form.setFieldsValue({
// course:value,
classroom:value
// course:value,
classroom:e.target.value,
})
if(e.target.value){
if(e.target.value.length>60){
this.setState({
bordebool:true,
})
}else if(e.target.value.length===0){
this.setState({
bordebool:true,
})
}else{
this.setState({
bordebool:false,
})
}
}else{
this.setState({
bordebool:true
})
}
};
handleSearchschool=(value)=>{
@ -467,7 +494,7 @@ class CoursesNew extends Component {
this.applyForAddOrgForm.setVisible(true)
}
render() {
let {datatime,school,searchlistscholl} = this.state;
let {datatime,school,searchlistscholl,bordebool} = this.state;
const {getFieldDecorator} = this.props.form;
const propsWithoutForm = Object.assign({}, this.props)
delete propsWithoutForm.form
@ -489,6 +516,16 @@ class CoursesNew extends Component {
if(addonAftertwo){
addonAfteronelens=String(addonAftertwo).length;
}
var addonAfterthree=this.props.form&&this.props.form.getFieldValue('course');
var addonAfteronelens3=0;
if(addonAfterthree){
addonAfteronelens3=String(addonAfterthree).length;
}
var addonAfterfour=this.props.form&&this.props.form.getFieldValue('classroom');
var addonAfteronelens4=0;
if(addonAfterfour){
addonAfteronelens4=String(addonAfterfour).length;
}
return (
<React.Fragment>
@ -543,27 +580,23 @@ class CoursesNew extends Component {
`}
</style>
<Form onSubmit={this.handleSubmit} className={"edu-back-white newcourses"}>
<Form onSubmit={this.handleSubmit} className="edu-back-white newcourses">
{/*内容*/}
<style>
{`
.ant-select-dropdown{
// top: 221px !important;
// left: 115px !important;
width: 280px !important;
height: 160px;
}
.ant-select-dropdown-menu{
width: 280px !important;
height: 160px;
}
.construction .ant-input{
width: 280px !important;
margin-left: 0px !important;
}
.construction {
width: 280px;
margin-left: 10px;
margin-left: 11px;
}
.construction .ant-select-selection__placeholder, .ant-select-search__field__placeholder {
@ -575,21 +608,55 @@ class CoursesNew extends Component {
<div className="stud-class-set bor-bottom-greyE padding10200 ">
<div className={"TabsWarpcourse"}>
<Form.Item label="课程名称">
{getFieldDecorator('course', {
rules: [{required: true, message: "不能为空"}],
})(
<AutoComplete style={{ width: 280 }}
onSearch={this.handleSearch}
onChange={this.handleChange}
className={"fl construction "}
placeholder="例如:数据结构"
>
{options}
</AutoComplete>
<style>{
`
.yslzxueshis .ant-input{
border-right: none !important;
height: 40px !important;
width: 655px !important;
}
.yslzxueshisy span .ant-input-group-addon{
width: 65px !important;
background-color: #fafafa!important;
}
.yslzxueshisy .ant-input-group-addon{
width: 65px !important;
background-color: #fafafa!important;
}
.yslzxueshis .ant-select-dropdown{
width: 655px !important;
height:160px !important;
}
.yslzxueshisy .ant-select-dropdown{
width: 655px !important;
height:160px !important;
}
.yslzxueshis .ant-select-dropdown-menu{
width: 655px !important;
}
.ant-select-dropdown{
width: 655px !important;
height:160px !important;
}
`
}</style>
<Form.Item label="课程名称">
{getFieldDecorator('course', {
rules: [{required: true, message: "不能为空"}],
})(
<AutoComplete
style={{ width: 720}}
onSearch={this.handleSearch}
onSelect={this.handleSearchsysl}
className="fl construction yslzxueshis "
dataSource={options}
>
<Input className="yslzxueshisy " placeholder="例如:数据结构" onChange={this.handleChange} addonAfter={String(addonAfteronelens3)+"/60"} maxLength={60} />
</AutoComplete>
)}
<span className={"newcoursestitle fl"}>
<span className="newcoursestitle fl">
{/*错误示例数据结构2017本部数据结构2017秋季数据结构2017电子商务1班*/}
<p className="ant-progress-text">
<Icon style={{ color: '#52c41a' }} type="check-circle" theme="filled"/>
@ -600,8 +667,8 @@ class CoursesNew extends Component {
<span className={"color-grey-9 font-12 ml5"}>错误示例数据结构2019春</span>
</p>
</span>
<div id='iscourse'></div>
</Form.Item>
<div id='iscourse'></div>
</Form.Item>
</div>
</div>
@ -616,14 +683,41 @@ class CoursesNew extends Component {
}
</style>
<div className="stud-class-set bor-bottom-greyE padding1020 ">
<style>{
`
.yslzxueshiskmc .ant-input{
border-right: none !important;
height: 40px !important;
width: 655px !important;
<Form.Item label="课堂名称">
}
.yslzxueshiskmc .ant-input-group{
width: 720px !important;
}
.yslzxueshisy span .ant-input-group-addon{
width: 65px !important;
background-color: #fafafa!important;
}
.yslzxueshiskmc .ant-input-group-addon{
width: 65px !important;
background-color: #fafafa!important;
}
.yslzxueshiskmc .ant-input-group-wrapper{
width: 720px !important;
}
.yslzxueshiskmcs .ant-input-group-wrapper{
width: 720px !important;
}
`
}</style>
<Form.Item label="课堂名称" className="yslzxueshiskmcs">
{getFieldDecorator('classroom', {
rules: [{required: true, message: "不能为空"}],
})(<Input className={"greyInput fl"} placeholder="例如数据结构2016秋季班级"/>)}
<span className={"newcoursestitle fl"}>
})(<Input className="yslzxueshiskmc fl" placeholder="例如数据结构2016秋季班级" addonAfter={String(addonAfteronelens4)+"/60"} maxLength={60} />)}
<span className="newcoursestitleysl fl">
{/*(如果本学期包含多个班级,只需创建一个课堂然后在课堂内部建立不同的分班)*/}
<p className="ant-progress-text">
<p className="ant-progress-text">
<Icon style={{ color: '#52c41a' }} type="check-circle" theme="filled"/>
<span className={"color-grey-9 font-12 ml5"}>正确示例数据结构2019春季班级</span>
</p>
@ -672,11 +766,7 @@ class CoursesNew extends Component {
rules:[{
pattern: new RegExp(/^[0-9]+([.]{1}[0-9]+){0,1}$/, "g"),
message: '必须是数值'
},
{
max:5,
message: '不能超过5个字符',
}]}
}]}
)(
<Input id="period" className="yslzxueshi " placeholder="例如30" addonAfter={String(addonAfteronelen)+"/5"} maxLength={5}/>
)}
@ -691,14 +781,10 @@ class CoursesNew extends Component {
rules:[{
pattern: new RegExp(/^[0-9]+([.]{1}[0-9]+){0,1}$/, "g"),
message: '必须是数值'
},
{
max:5,
message: '不能超过5个字符',
}
}
]}
)(
<Input id="credit" className="yslzxueshi" placeholder="例如3" addonAfter={String(addonAfteronelen)+"/5"} maxLength={5}/>
<Input id="credit" className="yslzxueshi" placeholder="例如3" addonAfter={String(addonAfteronelens)+"/5"} maxLength={5}/>
)}
</Form.Item>
<Form.Item

@ -54,12 +54,7 @@ class Goldsubject extends Component {
addonAfteronelenone:"",
addonAfteronelentwo:"",
Whethertocreateanewclassroom:true,
checkbofrup:[
{module_type:"announcement",module_name:"公告栏"},{module_type:"online_learning",module_name:"在线学习"}
,{module_type:"shixun_homework",module_name:"实训作业"},{module_type:"common_homework",module_name:"普通作业"}
,{module_type:"exercise",module_name:"试卷"},{module_type:"poll",module_name:"问卷"}
,{module_type:"attachment",module_name:"资源"},{module_type:"board",module_name:"讨论"},{module_type:"course_group",module_name:"分班"},],
bordebool:false,
}
}
// disabledEndDate= endValue => {
@ -110,8 +105,8 @@ class Goldsubject extends Component {
};
componentDidMount() {
console.log("新建精品课堂的数据");
console.log(this.props);
// console.log("新建精品课堂的数据");
// console.log(this.props);
let coursesId = this.props.match.params.coursesId;
let user_school=this.props.current_user&&this.props.current_user.user_school;
@ -164,8 +159,8 @@ class Goldsubject extends Component {
if (response) {
// this.goback
if(response.data){
console.log("获取Goldsubject.js");
console.log(response.data);
// console.log("获取Goldsubject.js");
// console.log(response.data);
if(response.data.status===0){
this.props.form.setFieldsValue({
classroom: response.data.course_name,
@ -206,20 +201,20 @@ class Goldsubject extends Component {
}
}
onChangeTimepublishs = (date, dateString) => {
console.log("结束时间11111111111");
console.log(dateString);
// console.log("结束时间11111111111");
// console.log(dateString);
if(dateString===""){
this.setState({
datatime: undefined,
})
console.log("结束时间111111111116");
// console.log("结束时间111111111116");
this.props.form.setFieldsValue({
endtime:undefined,
});
}else{
console.log("结束时间111111111117");
// console.log("结束时间111111111117");
this.setState({
datatime: dateString,
@ -231,10 +226,10 @@ class Goldsubject extends Component {
};
onChangeTimepublishstwo = (date, dateString) => {
console.log("结束时间22222222222");
console.log(dateString);
// console.log("结束时间22222222222");
// console.log(dateString);
if(dateString===""){
console.log("结束时间222222222223");
// console.log("结束时间222222222223");
this.setState({
datatimetwo: undefined,
})
@ -242,7 +237,7 @@ class Goldsubject extends Component {
starttime: undefined,
});
}else{
console.log("结束时间222222222224");
// console.log("结束时间222222222224");
this.setState({
datatimetwo: dateString,
@ -320,13 +315,23 @@ class Goldsubject extends Component {
if (!err) {
var classroomysl=values.classroom+"";
try {
if(classroomysl){
if(classroomysl.length>60){
classroomysl=classroomysl.substring(0,60);
}
}
}catch (e) {
}
// console.log('Received values of form: ', values);
var datasysl={
// subject_id:128, //这是带过来的值 编辑就不要传值了
name: values.classroom,
name: classroomysl,
class_period: values.period,
credit: parseFloat(values.credit),
start_date:moment(values.starttime).format("YYYY-MM-DD"),
@ -336,12 +341,12 @@ class Goldsubject extends Component {
school:values.school
};
try {
console.log("327");
console.log(datasysl);
// console.log("327");
// console.log(datasysl);
// console.log(JSON.stringify(datasysl));
console.log("88887777");
console.log(moment(values.starttime).format("YYYY-MM-DD"));
console.log(moment(values.endtime).format("YYYY-MM-DD"));
// console.log("88887777");
// console.log(moment(values.starttime).format("YYYY-MM-DD"));
// console.log(moment(values.endtime).format("YYYY-MM-DD"));
}catch (e) {
}
@ -375,15 +380,15 @@ class Goldsubject extends Component {
})
}
console.log("错误信息信息信息1");
console.log(err);
console.log(values.starttime);
console.log(values.endtime);
// console.log("错误信息信息信息1");
// console.log(err);
// console.log(values.starttime);
// console.log(values.endtime);
});
} else {
this.props.form.validateFields((err, values) => {
console.log("错误信息信息信息2");
// console.log("错误信息信息信息2");
console.log(err);
if (err) {
return;
@ -419,11 +424,11 @@ class Goldsubject extends Component {
school:values.school
};
try {
console.log("提交的ysldatas数据");
console.log(ysldatas);
// console.log("提交的ysldatas数据");
// console.log(ysldatas);
// console.log(JSON.stringify(ysldatas));
console.log(moment(values.starttime).format("YYYY-MM-DD"));
console.log(moment(values.endtime).format("YYYY-MM-DD"));
// console.log(moment(values.starttime).format("YYYY-MM-DD"));
// console.log(moment(values.endtime).format("YYYY-MM-DD"));
}catch (e) {
}
@ -527,12 +532,33 @@ class Goldsubject extends Component {
};
handleChange=(value)=>{
handleChange=(e)=>{
console.log(e);
this.props.form.setFieldsValue({
// course:value,
classroom:value
classroom:e.target.value,
})
if(e.target.value){
if(e.target.value.length>60){
this.setState({
bordebool:true,
})
}else if(e.target.value.length===0){
this.setState({
bordebool:true,
})
}else{
this.setState({
bordebool:false,
})
}
}else{
this.setState({
bordebool:true
})
}
};
handleSearchschool=(value)=>{
@ -602,7 +628,7 @@ class Goldsubject extends Component {
this.applyForAddOrgForm.setVisible(true)
}
render() {
let {datatime,datatimetwo,school,searchlistscholl,Whethertocreateanewclassroom,addonAfteronelenone,addonAfteronelentwo} = this.state;
let {datatime,datatimetwo,school,bordebool,searchlistscholl,Whethertocreateanewclassroom,addonAfteronelenone,addonAfteronelentwo} = this.state;
const {getFieldDecorator} = this.props.form;
const propsWithoutForm = Object.assign({}, this.props)
delete propsWithoutForm.form
@ -624,8 +650,12 @@ class Goldsubject extends Component {
if(addonAftertwo){
addonAfteronelens=String(addonAftertwo).length;
}
console.log(addonAfteronelenone);
console.log(addonAfteronelentwo);
var addonAfterthree=this.props.form&&this.props.form.getFieldValue('classroom');
var addonAfteronelens3=0;
if(addonAfterthree){
addonAfteronelens3=String(addonAfterthree).length;
}
return (
<React.Fragment>
@ -687,20 +717,16 @@ class Goldsubject extends Component {
.ant-select-dropdown{
// top: 221px !important;
// left: 115px !important;
width: 280px !important;
height: 160px;
}
.ant-select-dropdown-menu{
width: 280px !important;
height: 160px;
}
.construction .ant-input{
width: 280px !important;
margin-left: 0px !important;
}
.construction {
width: 280px;
margin-left: 10px;
margin-left: 11px;
}
.construction .ant-select-selection__placeholder, .ant-select-search__field__placeholder {
@ -753,19 +779,61 @@ class Goldsubject extends Component {
}
</style>
<div className="stud-class-set bor-bottom-greyE padding1020 ">
<style>{
`
.yslzxueshis .ant-input{
border-right: none !important;
height: 40px !important;
width: 655px !important;
}
.yslzxueshisy span .ant-input-group-addon{
width: 65px !important;
background-color: #fafafa!important;
}
.yslzxueshisy .ant-input-group-addon{
width: 65px !important;
background-color: #fafafa!important;
}
.yslzxueshis .ant-select-dropdown{
width: 655px !important;
height:160px !important;
}
.yslzxueshis .ant-select-dropdown-menu{
width: 655px !important;
}
.ant-select-dropdown{
width: 655px !important;
height:160px !important;
}
`
}</style>
<style>
{bordebool===false?
`
.ant-input:hover {
// border: 1px solid #d9d9d9;
}
`:
`
.ant-input:hover {
// border: 1px solid #f5222d;
}
`
}
</style>
<Form.Item label="课堂名称">
{getFieldDecorator('classroom', {
rules: [{required: true, message: "不能为空"}],
rules: [{required: true, message: "不能为空"}],
})(
<AutoComplete style={{ width: 280 }}
<AutoComplete
style={{width: 720}}
onSearch={this.handleSearch}
onChange={this.handleChange}
className={"fl construction "}
placeholder="例如:数据结构"
className={"fl construction yslzxueshis "}
dataSource={options}
>
{options}
<Input className="yslzxueshisy " placeholder="例如:数据结构" onInput={this.handleChange} addonAfter={String(addonAfteronelens3)+"/60"} maxLength={60} />
</AutoComplete>
)}
{/*<span className={"newcoursestitle fl"}>*/}
@ -863,7 +931,6 @@ class Goldsubject extends Component {
width={"210px"}
value={datatimetwo === undefined ? "" :datatimetwo === null ? "" : moment(datatimetwo, dateFormat)}
disabledTime={disabledDateTime}
disabledDate={this.isabledStartDate}
dropdownClassName="hideDisable"
onChange={this.onChangeTimepublishstwo}
/>
@ -887,7 +954,6 @@ class Goldsubject extends Component {
width={"210px"}
value={datatime === undefined ? "" :datatime === null ? "" : moment(datatime, dateFormat)}
disabledTime={disabledDateTime}
disabledDate={this.disabledEndDate}
dropdownClassName="hideDisable"
onChange={this.onChangeTimepublishs}
/>

@ -103,11 +103,11 @@ class Poll extends Component{
this.InitList(e.key,StudentList_value,page);
}
// 获取列表数据
InitList=(type,search,page)=>{
InitList=(type,search,page,bank_checkValue)=>{
this.setState({
isSpin:true
})
let {pageSize}=this.state
let { pageSize,checkBoxValues }=this.state
let coursesId=this.props.match.params.coursesId;
let url='/courses/'+coursesId+'/polls.json?limit='+pageSize+'&page='+page
if(type!="0"){
@ -123,7 +123,7 @@ class Poll extends Component{
course_types:result.data.course_types,
polls_counts:result.data.polls_counts,
isSpin:false,
checkBoxValues:[]
checkBoxValues: bank_checkValue ? bank_checkValue : []
})
}
}).catch((error)=>{
@ -209,12 +209,6 @@ class Poll extends Component{
//判断是否有选中数据
if(this.state.checkBoxValues.length==0){
this.props.showNotification("请先在列表中选择数据");
// this.setState({
// modalsType:true,
// modalsTopval:"请先在列表中选择数据",
// modalsBottomval:'',
// loadtype:true
// })
}else{
if(value != "bank"){
this.setState({
@ -325,15 +319,13 @@ class Poll extends Component{
}
// 题库选用成功后,立即发布,刷新页面
useBankSuccess=(checkValue,value)=>{
debugger;
this.setState({
isSpin:true
})
let{type,StudentList_value,page}=this.state
this.InitList(type,StudentList_value,page);
this.InitList(type,StudentList_value,page,value);
this.setState({
checkBoxValues:[]
})
let coursesId=this.props.match.params.coursesId;
let url=`/courses/${coursesId}/polls/publish_modal.json`;
axios.get(url,{
@ -351,10 +343,6 @@ class Poll extends Component{
})
}
}
this.setState({
course_groups:list,
checkBoxValues:value
})
this.setState({
modalname:"立即发布",
modaltype:response.data.un_publish > 0 ? 1 : 2,
@ -369,6 +357,8 @@ class Poll extends Component{
Savesname:"立即发布",
Cancel:this.homeworkhide,
Saves:this.homeworkstartend,
course_groups:list,
checkBoxValues:value
})
}
}).catch((error) => {
@ -425,7 +415,7 @@ class Poll extends Component{
addname:undefined,
addnametype:false,
addnametab:undefined,
checkBoxValues:[]
// checkBoxValues:[]
})
}

@ -54,6 +54,7 @@ class PollListItem extends Component{
}
</p>
<p className="color-grey-9 clearfix">
{ item.author && <span className="mr20 fl">{item.author}</span> }
{
item.polls_status !=1 &&
<span className="fl mt3">

@ -77,7 +77,7 @@ class PollNew extends Component {
}
changeTopicName = (e) => {
console.log("调用了changeTopicName");
// console.log("调用了changeTopicName");
let num = parseInt(e.target.value.length);
if(num>60){
return;

@ -0,0 +1,79 @@
import React, {Component} from "react";
import { WordsBtn,on, off, trigger,markdownToHTML,getImageUrl} from 'educoder';
import {
Button,
Checkbox,
message,
InputNumber,
DatePicker,
Radio,
Tooltip,
notification,
} from "antd";
import GroupPackage from '../groupjobbank/GroupPackage'
import './questionbank.css';
class Generaljobanswer extends Component {
constructor(props) {
super(props);
this.state = {
}
}
componentDidMount() {
console.log("Generaljobanswer");
console.log("componentDidMount");
// let query = this.props.location.pathname;
// const type = query.split('/');
// this.setState({
// shixuntypes:type[3]
// })
// this.props.triggerRef(this);
}
// 获取数据地方
getTrainingjobsetting = () => {
var homeworkid = this.props.match.params.homeworkid;
}
//跳转道描点的地方
scrollToAnchor = (anchorName) => {
if (anchorName) {
// 找到锚点
let anchorElement = document.getElementById(anchorName);
// 如果对应id的锚点存在就跳转到锚点
if(anchorElement) { anchorElement.scrollIntoView(); }
}
};
render() {
return (
<div className=" clearfix edu-back-white" ref='targetElementTrainingjobsetting' style={{margin: "auto", minWidth:"1200px"}}>
<div className="yslquestionbank1">
<div id="MakedownHTML"className="markdown-body yslquesHeigth yslquesmarkdowntext" dangerouslySetInnerHTML={{__html: markdownToHTML("C++是C语言的面向对象扩展是C语言的一个超集同时也是历史最悠久、最受欢迎的程序设计语言之一。根据C++创始人Stroustrup的自述C++是一个“更好的C语言”。\n" +
"\n" +
"输入输出是计算机程序的基本功能。程序本质上是对数据进行处理的一系列操作,一般程序都可以分解为:“数据输入”、“数据处理”和“数据输出”三个步骤。标准输入输出(键盘输入和显示器输出)是程序的重要组成部分。\n" +
"\n" +
"本实训项目的主要目标是学习和掌握C++程序的基本结构和基本输入输出主要内容包括标准C语言自有的单个字符的输入输出、格式化的输入输出以及C++扩展的使用流对象的输入输出").replace(/▁/g, "▁▁▁")}}/>
<GroupPackage></GroupPackage>
</div>
</div>
)
}
}
export default Generaljobanswer;

@ -0,0 +1,173 @@
import React, {Component} from "react";
import {Link, NavLink} from 'react-router-dom';
import {WordsBtn, ActionBtn} from 'educoder';
import { Input,Checkbox,Table, Pagination, Modal,Menu, Tooltip,Spin,Button,Form } from "antd";
import axios from 'axios';
import {
notification
} from "antd";
import CoursesListType from '../coursesPublic/CoursesListType';
import Generaljobdetails from './Generaljobdetails';
import Generaljobanswer from './Generaljobanswer';
import '../css/members.css';
import "../common/formCommon.css";
import '../css/Courses.css';
import '../css/busyWork.css';
import '../poll/pollStyle.css';
class Generaljobbankdetails extends Component {
//普通作业内容详情
constructor(props) {
super(props);
// this.answerMdRef = React.createRef();
this.state = {
tab: ["0"],
workid:1,
isSpin:false,
datas:[],
}
}
//切换tab
ChangeTab = (e) => {
// console.log(e);
this.setState({
tab: e
})
try {
var currenturl = window.location.href;
var newUrl = (currenturl.split("?"))[0];
window.history.pushState('','',newUrl+'?tab='+e);
}catch (e) {
console.log(e);
console.log("44");
}
}
componentDidMount() {
// console.log("父组件加载框");
const query = this.props.location.search;
const type = query.split('?tab=');
// let sum = []
// sum.push(type[1])
// console.log("componentDidMountcomponentDidMount");
// console.log(type);
this.setState({
tab: type[1],
});
console.log("Generaljobbankdetails");
console.log(this.props);
if( this.props.match.params.workid){
this.setState({
workid: this.props.match.params.workid,
})
}
this.getdata(this.props.match.params.workid);
}
//获取数据的地方
getdata=(workid)=>{
var workids= workid;
if(workids){
}else{
workids=this.state.workid;
}
this.setState({
isSpin:true,
})
let url = `/homework_banks/${workids}.json`;
//
axios.get(url).then((response) => {
if(response){
if(response.data){
this.setState({
datas:response.data.informs,
})
}else {
this.setState({
datas:[],
})
}
}else {
this.setState({
datas:[],
})
}
this.setState({
isSpin:false,
})
}).catch((error) => {
console.log(error)
this.setState({
datas:[],
isSpin:false,
})
});
}
bindRef = ref => { this.child = ref }
///////////////教师截止
render() {
let {tab} = this.state;
const isAdmin = this.props.isAdmin();
// console.log(119)
return (
<div className="newMain clearfix ">
<div className={"educontent mt10 mb20"} style={{width: "1200px"}}>
<div className="educontent mb20">
<p className="clearfix mb20 mt10">
<a className="btn colorgrey fl hovercolorblue ">题库</a>
<span className="color-grey-9 fl ml3 mr3">&gt;</span>
<a
className=" btn colorgrey fl hovercolorblue "
>详情</a>
</p>
</div>
<div className="educontent mb20">
<p className=" fl color-black summaryname" style={{heigth: "33px"}}>
MySQL数据库编程开发实训基础篇
</p>
<CoursesListType
typelist={["公开"]}
/>
</div>
<div className="edu-back-white ">
<div className="stud-class-set bor-bottom-greyE ">
<div className=" clearfix edu-back-white poll_list">
<a className={parseInt(tab) === 0 ? "active ml12" : "ml12"} onClick={(e) => this.ChangeTab(0)}>内容详情</a>
<a className={parseInt(tab) === 1 ? "active ml12" : "ml12"} onClick={(e) => this.ChangeTab(1)}>参考答案</a>
<a className="fr color-blue font-16" >发送</a>
<a className="fr color-blue font-16" >编辑</a>
<a className="fr color-blue font-16" >删除</a>
</div>
</div>
</div>
<Spin size="large" spinning={this.state.isSpin} id={"cdiv"}>
{parseInt(tab) === 0 ? <Generaljobdetails {...this.props} {...this.state}/> :""}
{parseInt(tab) === 1 ? <Generaljobanswer{...this.props} {...this.state}/>:""}
</Spin>
</div>
</div>
)
}
}
export default Generaljobbankdetails;

@ -0,0 +1,81 @@
import React, {Component} from "react";
import { WordsBtn,on, off, trigger,markdownToHTML,getImageUrl} from 'educoder';
import {
Button,
Checkbox,
message,
InputNumber,
DatePicker,
Radio,
Tooltip,
notification,
} from "antd";
import GroupPackage from '../groupjobbank/GroupPackage'
import './questionbank.css';
class Generaljobdetails extends Component {
constructor(props) {
super(props);
this.state = {
}
}
componentDidMount() {
console.log("Generaljobdetails");
console.log("componentDidMount");
// let query = this.props.location.pathname;
// const type = query.split('/');
// this.setState({
// shixuntypes:type[3]
// })
// this.props.triggerRef(this);
}
// 获取数据地方
getTrainingjobsetting = () => {
var homeworkid = this.props.match.params.homeworkid;
}
//跳转道描点的地方
scrollToAnchor = (anchorName) => {
if (anchorName) {
// 找到锚点
let anchorElement = document.getElementById(anchorName);
// 如果对应id的锚点存在就跳转到锚点
if(anchorElement) { anchorElement.scrollIntoView(); }
}
};
render() {
return (
<div className=" clearfix edu-back-white" ref='targetElementTrainingjobsetting' style={{margin: "auto", minWidth:"1200px"}}>
<div className="yslquestionbank1">
<div id="MakedownHTML"className="markdown-body yslquesHeigth yslquesmarkdowntext" dangerouslySetInnerHTML={{__html: markdownToHTML("C++是C语言的面向对象扩展是C语言的一个超集同时也是历史最悠久、最受欢迎的程序设计语言之一。根据C++创始人Stroustrup的自述C++是一个“更好的C语言”。\n" +
"\n" +
"输入输出是计算机程序的基本功能。程序本质上是对数据进行处理的一系列操作,一般程序都可以分解为:“数据输入”、“数据处理”和“数据输出”三个步骤。标准输入输出(键盘输入和显示器输出)是程序的重要组成部分。\n" +
"\n" +
"本实训项目的主要目标是学习和掌握C++程序的基本结构和基本输入输出主要内容包括标准C语言自有的单个字符的输入输出、格式化的输入输出以及C++扩展的使用流对象的输入输出").replace(/▁/g, "▁▁▁")}}/>
<GroupPackage></GroupPackage>
</div>
</div>
)
}
}
export default Generaljobdetails;

@ -0,0 +1,26 @@
.yslquestionbank1{
padding-top: 30px !important;
padding-right: 30px !important;
padding-left: 30px !important;
}
.yslquesHeigth{
min-height: 500px !important;
}
.yslquesmarkdowntext{
font-size: 16px;
color: #707070;
}
.yslquesmat26{
margin-top: 26px;
padding-bottom: 44px !important;
}
.ysltextcolor9999{
color: #999999;
font-size: 14px;
}
.ysltextcolor99999{
color: #999999;
font-size: 16px;
}

@ -333,7 +333,7 @@ class ShixunhomeWorkItem extends Component{
<p className="color-grey panel-lightgrey mt16 fl">
<span className="mr50">
{/* <a href="/users/innov" className="panel-name-small hide fl mr15 mr30 color-grey3">{discussMessage.author.name}</a> */}
{ discussMessage.author && <span className="mr15 color-grey-3">{discussMessage.author}</span> }
{discussMessage.commit_count===undefined?"":<span className="mr15 color-grey9">{discussMessage.commit_count} 已交</span>}
{discussMessage.uncommit_count===undefined?"":<span className="mr15 color-grey9">{discussMessage.uncommit_count} 未交</span>}
{/*<span className="mr15 color-grey9">{discussMessage.replies_count} 3 未评</span>*/}

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

Loading…
Cancel
Save