dev_aliyun_beta
杨树明 6 years ago
commit adee752481

@ -11,6 +11,7 @@
//= require select2 //= require select2
//= require jquery.cxselect //= require jquery.cxselect
//= require bootstrap-datepicker //= require bootstrap-datepicker
//= require bootstrap.viewer
//= require_tree ./i18n //= require_tree ./i18n
//= require_tree ./admins //= require_tree ./admins
@ -25,6 +26,9 @@ $(document).on('turbolinks:load', function(){
$('[data-toggle="tooltip"]').tooltip(); $('[data-toggle="tooltip"]').tooltip();
$('[data-toggle="popover"]').popover(); $('[data-toggle="popover"]').popover();
// 图片查看大图
$('img.preview-image').bootstrapViewer();
// flash alert提示框自动关闭 // flash alert提示框自动关闭
if($('.admin-alert-container .alert').length > 0){ if($('.admin-alert-container .alert').length > 0){
setTimeout(function(){ setTimeout(function(){
@ -33,10 +37,25 @@ $(document).on('turbolinks:load', function(){
} }
}); });
$(document).on("turbolinks:before-cache", function () { // var progressBar = new Turbolinks.ProgressBar();
$('[data-toggle="tooltip"]').tooltip('hide');
$('[data-toggle="popover"]').popover('hide'); // $(document).on('ajax:send', function(event){
}); // console.log('ajax send', event);
// progressBar.setValue(0)
// progressBar.show()
// });
//
// $(document).on('ajax:complete', function(event){
// console.log('ajax complete', event);
// progressBar.setValue(1)
// progressBar.hide() // 分页时不触发,奇怪
// });
// $(document).on('ajax:success', function(event){
// console.log('ajax success', event);
// });
// $(document).on('ajax:error', function(event){
// console.log('ajax error', event);
// });
$(function () { $(function () {
}); });

@ -0,0 +1,54 @@
$(document).on('turbolinks:load', function() {
var $refuseModal = $('.admin-common-refuse-modal');
if ($refuseModal.length > 0) {
var $form = $refuseModal.find('form.admin-common-refuse-form');
var $applyIdInput = $refuseModal.find('.modal-body input[name="apply_id"]');
$form.validate({
errorElement: 'span',
errorClass: 'danger text-danger',
rules: {
reason: {
required: true,
maxlength: 200
},
}
});
// modal ready fire
$refuseModal.on('show.bs.modal', function (event) {
var $link = $(event.relatedTarget);
var applyId = $link.data('id');
var url = $link.data('url');
$applyIdInput.val(applyId);
$form.data('url', url);
});
// modal visited fire
$refuseModal.on('shown.bs.modal', function(){
$refuseModal.find('.modal-body input[name="reason"]').focus();
});
$refuseModal.on('hide.bs.modal', function () {
$applyIdInput.val('');
$form.data('url', '');
})
$refuseModal.on('click', '.submit-btn', function(){
$form.find('.error').html('');
if ($form.valid()) {
var url = $form.data('url');
$.ajax({
method: 'POST',
dataType: 'script',
url: url,
data: $form.serialize(),
}).done(function(){
$refuseModal.modal('hide');
});
}
});
}
});

@ -0,0 +1,18 @@
$(document).on('turbolinks:load', function() {
if ($('body.admins-identity-authentications-index-page').length > 0) {
var $searchFrom = $('.identity-authentication-list-form');
$searchFrom.on('click', '.search-form-tab', function(){
var $link = $(this);
$searchFrom.find('input[name="keyword"]').val('');
$searchFrom.find('select[name="status"]').val('processed');
if($link.data('value') === 'processed'){
$searchFrom.find('.status-filter').show();
} else {
$searchFrom.find('.status-filter').hide();
}
});
}
})

@ -0,0 +1,18 @@
$(document).on('turbolinks:load', function() {
if ($('body.admins-professional-authentications-index-page').length > 0) {
var $searchFrom = $('.professional-authentication-list-form');
$searchFrom.on('click', '.search-form-tab', function(){
var $link = $(this);
$searchFrom.find('input[name="keyword"]').val('');
$searchFrom.find('select[name="status"]').val('processed');
if($link.data('value') === 'processed'){
$searchFrom.find('.status-filter').show();
} else {
$searchFrom.find('.status-filter').hide();
}
});
}
})

@ -0,0 +1,10 @@
$(document).on('turbolinks:load', function() {
var $tabs = $('.search-form-container .search-form-tabs');
if ($tabs.length > 0) {
$tabs.on('click', '.search-form-tab', function(){
var $activeTab = $(this);
$tabs.find('.search-form-tab').removeClass('active');
$activeTab.addClass('active');
});
}
});

@ -0,0 +1,50 @@
/*
* Copyright 2018-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* WebSite: http://bootstrap-viewer.leftso.com
*/
$.fn.bootstrapViewer = function (options) {
$(this).on('click', function () {
var opts = $.extend({}, $.fn.bootstrapViewer.defaults, options);
var viewer = $('<div class="modal fade bs-example-modal-lg text-center" id="bootstrapViewer" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel" >\n' +
' <div class="modal-dialog modal-lg" style="display: inline-block; width: auto;">\n' +
' <div class="modal-content">\n' +
' <img' +
'\t\t\t class="carousel-inner img-responsive img-rounded img-viewer" \n' +
'\t\t\t onclick="$(\'#bootstrapViewer\').modal(\'hide\');setTimeout(function(){$(\'#bootstrapViewer\').remove();},200);"\n' +
'\t\t\t onmouseover="this.style.cursor=\'zoom-out\';" \n' +
'\t\t\t onmouseout="this.style.cursor=\'default\'" \n' +
'\t\t\t />\n' +
' </div>\n' +
' </div>\n' +
' </div>');
$('body').append(viewer);
if ($(this).attr(opts.src)) {
$("#bootstrapViewer").find(".img-viewer").attr("src", $(this).attr(opts.src));
$("#bootstrapViewer").modal();
} else {
throw "图片不存在"
}
})
$(this).on('mouseover', function () {
$(this).css('cursor', 'zoom-in');
})
}
$.fn.bootstrapViewer.defaults = {
src: 'src'
}

@ -1,403 +1,403 @@
/*! /*!
* jQuery cxSelect * jQuery cxSelect
* @name jquery.cxselect.js * @name jquery.cxselect.js
* @version 1.4.1 * @version 1.4.1
* @date 2016-11-02 * @date 2016-11-02
* @author ciaoca * @author ciaoca
* @email ciaoca@gmail.com * @email ciaoca@gmail.com
* @site https://github.com/ciaoca/cxSelect * @site https://github.com/ciaoca/cxSelect
* @license Released under the MIT license * @license Released under the MIT license
*/ */
(function(factory) { (function(factory) {
if (typeof define === 'function' && define.amd) { if (typeof define === 'function' && define.amd) {
define(['jquery'], factory); define(['jquery'], factory);
} else { } else {
factory(window.jQuery || window.Zepto || window.$); factory(window.jQuery || window.Zepto || window.$);
}; };
}(function($) { }(function($) {
var cxSelect = function() { var cxSelect = function() {
var self = this; var self = this;
var dom, settings, callback; var dom, settings, callback;
// 分配参数 // 分配参数
for (var i = 0, l = arguments.length; i < l; i++) { for (var i = 0, l = arguments.length; i < l; i++) {
if (cxSelect.isJquery(arguments[i]) || cxSelect.isZepto(arguments[i])) { if (cxSelect.isJquery(arguments[i]) || cxSelect.isZepto(arguments[i])) {
dom = arguments[i]; dom = arguments[i];
} else if (cxSelect.isElement(arguments[i])) { } else if (cxSelect.isElement(arguments[i])) {
dom = $(arguments[i]); dom = $(arguments[i]);
} else if (typeof arguments[i] === 'function') { } else if (typeof arguments[i] === 'function') {
callback = arguments[i]; callback = arguments[i];
} else if (typeof arguments[i] === 'object') { } else if (typeof arguments[i] === 'object') {
settings = arguments[i]; settings = arguments[i];
}; };
}; };
var api = new cxSelect.init(dom, settings); var api = new cxSelect.init(dom, settings);
if (typeof callback === 'function') { if (typeof callback === 'function') {
callback(api); callback(api);
}; };
return api; return api;
}; };
cxSelect.isElement = function(o){ cxSelect.isElement = function(o){
if (o && (typeof HTMLElement === 'function' || typeof HTMLElement === 'object') && o instanceof HTMLElement) { if (o && (typeof HTMLElement === 'function' || typeof HTMLElement === 'object') && o instanceof HTMLElement) {
return true; return true;
} else { } else {
return (o && o.nodeType && o.nodeType === 1) ? true : false; return (o && o.nodeType && o.nodeType === 1) ? true : false;
}; };
}; };
cxSelect.isJquery = function(o){ cxSelect.isJquery = function(o){
return (o && o.length && (typeof jQuery === 'function' || typeof jQuery === 'object') && o instanceof jQuery) ? true : false; return (o && o.length && (typeof jQuery === 'function' || typeof jQuery === 'object') && o instanceof jQuery) ? true : false;
}; };
cxSelect.isZepto = function(o){ cxSelect.isZepto = function(o){
return (o && o.length && (typeof Zepto === 'function' || typeof Zepto === 'object') && Zepto.zepto.isZ(o)) ? true : false; return (o && o.length && (typeof Zepto === 'function' || typeof Zepto === 'object') && Zepto.zepto.isZ(o)) ? true : false;
}; };
cxSelect.getIndex = function(n, required) { cxSelect.getIndex = function(n, required) {
return required ? n : n - 1; return required ? n : n - 1;
}; };
cxSelect.getData = function(data, space) { cxSelect.getData = function(data, space) {
if (typeof space === 'string' && space.length) { if (typeof space === 'string' && space.length) {
space = space.split('.'); space = space.split('.');
for (var i = 0, l = space.length; i < l; i++) { for (var i = 0, l = space.length; i < l; i++) {
data = data[space[i]]; data = data[space[i]];
}; };
}; };
return data; return data;
}; };
cxSelect.init = function(dom, settings) { cxSelect.init = function(dom, settings) {
var self = this; var self = this;
if (!cxSelect.isJquery(dom) && !cxSelect.isZepto(dom)) {return}; if (!cxSelect.isJquery(dom) && !cxSelect.isZepto(dom)) {return};
var theSelect = { var theSelect = {
dom: { dom: {
box: dom box: dom
} }
}; };
self.attach = cxSelect.attach.bind(theSelect); self.attach = cxSelect.attach.bind(theSelect);
self.detach = cxSelect.detach.bind(theSelect); self.detach = cxSelect.detach.bind(theSelect);
self.setOptions = cxSelect.setOptions.bind(theSelect); self.setOptions = cxSelect.setOptions.bind(theSelect);
self.clear = cxSelect.clear.bind(theSelect); self.clear = cxSelect.clear.bind(theSelect);
theSelect.changeEvent = function() { theSelect.changeEvent = function() {
cxSelect.selectChange.call(theSelect, this.className); cxSelect.selectChange.call(theSelect, this.className);
}; };
theSelect.settings = $.extend({}, $.cxSelect.defaults, settings, { theSelect.settings = $.extend({}, $.cxSelect.defaults, settings, {
url: theSelect.dom.box.data('url'), url: theSelect.dom.box.data('url'),
emptyStyle: theSelect.dom.box.data('emptyStyle'), emptyStyle: theSelect.dom.box.data('emptyStyle'),
required: theSelect.dom.box.data('required'), required: theSelect.dom.box.data('required'),
firstTitle: theSelect.dom.box.data('firstTitle'), firstTitle: theSelect.dom.box.data('firstTitle'),
firstValue: theSelect.dom.box.data('firstValue'), firstValue: theSelect.dom.box.data('firstValue'),
jsonSpace: theSelect.dom.box.data('jsonSpace'), jsonSpace: theSelect.dom.box.data('jsonSpace'),
jsonName: theSelect.dom.box.data('jsonName'), jsonName: theSelect.dom.box.data('jsonName'),
jsonValue: theSelect.dom.box.data('jsonValue'), jsonValue: theSelect.dom.box.data('jsonValue'),
jsonSub: theSelect.dom.box.data('jsonSub') jsonSub: theSelect.dom.box.data('jsonSub')
}); });
var _dataSelects = theSelect.dom.box.data('selects'); var _dataSelects = theSelect.dom.box.data('selects');
if (typeof _dataSelects === 'string' && _dataSelects.length) { if (typeof _dataSelects === 'string' && _dataSelects.length) {
theSelect.settings.selects = _dataSelects.split(','); theSelect.settings.selects = _dataSelects.split(',');
}; };
self.setOptions(); self.setOptions();
self.attach(); self.attach();
// 使用独立接口获取数据 // 使用独立接口获取数据
if (!theSelect.settings.url && !theSelect.settings.data) { if (!theSelect.settings.url && !theSelect.settings.data) {
cxSelect.start.apply(theSelect); cxSelect.start.apply(theSelect);
// 设置自定义数据 // 设置自定义数据
} else if ($.isArray(theSelect.settings.data)) { } else if ($.isArray(theSelect.settings.data)) {
cxSelect.start.call(theSelect, theSelect.settings.data); cxSelect.start.call(theSelect, theSelect.settings.data);
// 设置 URL通过 Ajax 获取数据 // 设置 URL通过 Ajax 获取数据
} else if (typeof theSelect.settings.url === 'string' && theSelect.settings.url.length) { } else if (typeof theSelect.settings.url === 'string' && theSelect.settings.url.length) {
$.getJSON(theSelect.settings.url, function(json) { $.getJSON(theSelect.settings.url, function(json) {
cxSelect.start.call(theSelect, json); cxSelect.start.call(theSelect, json);
}); });
}; };
}; };
// 设置参数 // 设置参数
cxSelect.setOptions = function(opts) { cxSelect.setOptions = function(opts) {
var self = this; var self = this;
if (opts) { if (opts) {
$.extend(self.settings, opts); $.extend(self.settings, opts);
}; };
// 初次或重设选择器组 // 初次或重设选择器组
if (!$.isArray(self.selectArray) || !self.selectArray.length || (opts && opts.selects)) { if (!$.isArray(self.selectArray) || !self.selectArray.length || (opts && opts.selects)) {
self.selectArray = []; self.selectArray = [];
if ($.isArray(self.settings.selects) && self.settings.selects.length) { if ($.isArray(self.settings.selects) && self.settings.selects.length) {
var _tempSelect; var _tempSelect;
for (var i = 0, l = self.settings.selects.length; i < l; i++) { for (var i = 0, l = self.settings.selects.length; i < l; i++) {
_tempSelect = self.dom.box.find('select.' + self.settings.selects[i]); _tempSelect = self.dom.box.find('select.' + self.settings.selects[i]);
if (!_tempSelect || !_tempSelect.length) {break}; if (!_tempSelect || !_tempSelect.length) {break};
self.selectArray.push(_tempSelect); self.selectArray.push(_tempSelect);
}; };
}; };
}; };
if (opts) { if (opts) {
if (!$.isArray(opts.data) && typeof opts.url === 'string' && opts.url.length) { if (!$.isArray(opts.data) && typeof opts.url === 'string' && opts.url.length) {
$.getJSON(self.settings.url, function(json) { $.getJSON(self.settings.url, function(json) {
cxSelect.start.call(self, json); cxSelect.start.call(self, json);
}); });
} else { } else {
cxSelect.start.call(self, opts.data); cxSelect.start.call(self, opts.data);
}; };
}; };
}; };
// 绑定 // 绑定
cxSelect.attach = function() { cxSelect.attach = function() {
var self = this; var self = this;
if (!self.attachStatus) { if (!self.attachStatus) {
self.dom.box.on('change', 'select', self.changeEvent); self.dom.box.on('change', 'select', self.changeEvent);
}; };
if (typeof self.attachStatus === 'boolean') { if (typeof self.attachStatus === 'boolean') {
cxSelect.start.call(self); cxSelect.start.call(self);
}; };
self.attachStatus = true; self.attachStatus = true;
}; };
// 移除绑定 // 移除绑定
cxSelect.detach = function() { cxSelect.detach = function() {
var self = this; var self = this;
self.dom.box.off('change', 'select', self.changeEvent); self.dom.box.off('change', 'select', self.changeEvent);
self.attachStatus = false; self.attachStatus = false;
}; };
// 清空选项 // 清空选项
cxSelect.clear = function(index) { cxSelect.clear = function(index) {
var self = this; var self = this;
var _style = { var _style = {
display: '', display: '',
visibility: '' visibility: ''
}; };
index = isNaN(index) ? 0 : index; index = isNaN(index) ? 0 : index;
// 清空后面的 select // 清空后面的 select
for (var i = index, l = self.selectArray.length; i < l; i++) { for (var i = index, l = self.selectArray.length; i < l; i++) {
self.selectArray[i].empty().prop('disabled', true); self.selectArray[i].empty().prop('disabled', true);
if (self.settings.emptyStyle === 'none') { if (self.settings.emptyStyle === 'none') {
_style.display = 'none'; _style.display = 'none';
} else if (self.settings.emptyStyle === 'hidden') { } else if (self.settings.emptyStyle === 'hidden') {
_style.visibility = 'hidden'; _style.visibility = 'hidden';
}; };
self.selectArray[i].css(_style); self.selectArray[i].css(_style);
}; };
}; };
cxSelect.start = function(data) { cxSelect.start = function(data) {
var self = this; var self = this;
if ($.isArray(data)) { if ($.isArray(data)) {
self.settings.data = cxSelect.getData(data, self.settings.jsonSpace); self.settings.data = cxSelect.getData(data, self.settings.jsonSpace);
}; };
if (!self.selectArray.length) {return}; if (!self.selectArray.length) {return};
// 保存默认值 // 保存默认值
for (var i = 0, l = self.selectArray.length; i < l; i++) { for (var i = 0, l = self.selectArray.length; i < l; i++) {
if (typeof self.selectArray[i].attr('data-value') !== 'string' && self.selectArray[i][0].options.length) { if (typeof self.selectArray[i].attr('data-value') !== 'string' && self.selectArray[i][0].options.length) {
self.selectArray[i].attr('data-value', self.selectArray[i].val()); self.selectArray[i].attr('data-value', self.selectArray[i].val());
}; };
}; };
if (self.settings.data || (typeof self.selectArray[0].data('url') === 'string' && self.selectArray[0].data('url').length)) { if (self.settings.data || (typeof self.selectArray[0].data('url') === 'string' && self.selectArray[0].data('url').length)) {
cxSelect.getOptionData.call(self, 0); cxSelect.getOptionData.call(self, 0);
} else { } else {
self.selectArray[0].prop('disabled', false).css({ self.selectArray[0].prop('disabled', false).css({
'display': '', 'display': '',
'visibility': '' 'visibility': ''
}); });
}; };
}; };
// 获取选项数据 // 获取选项数据
cxSelect.getOptionData = function(index) { cxSelect.getOptionData = function(index) {
var self = this; var self = this;
if (typeof index !== 'number' || isNaN(index) || index < 0 || index >= self.selectArray.length) {return}; if (typeof index !== 'number' || isNaN(index) || index < 0 || index >= self.selectArray.length) {return};
var _indexPrev = index - 1; var _indexPrev = index - 1;
var _select = self.selectArray[index]; var _select = self.selectArray[index];
var _selectData; var _selectData;
var _valueIndex; var _valueIndex;
var _dataUrl = _select.data('url'); var _dataUrl = _select.data('url');
var _jsonSpace = typeof _select.data('jsonSpace') === 'undefined' ? self.settings.jsonSpace : _select.data('jsonSpace'); var _jsonSpace = typeof _select.data('jsonSpace') === 'undefined' ? self.settings.jsonSpace : _select.data('jsonSpace');
var _query = {}; var _query = {};
var _queryName; var _queryName;
var _selectName; var _selectName;
var _selectValue; var _selectValue;
cxSelect.clear.call(self, index); cxSelect.clear.call(self, index);
// 使用独立接口 // 使用独立接口
if (typeof _dataUrl === 'string' && _dataUrl.length) { if (typeof _dataUrl === 'string' && _dataUrl.length) {
if (index > 0) { if (index > 0) {
for (var i = 0, j = 1; i < index; i++, j++) { for (var i = 0, j = 1; i < index; i++, j++) {
_queryName = self.selectArray[j].data('queryName'); _queryName = self.selectArray[j].data('queryName');
_selectName = self.selectArray[i].attr('name'); _selectName = self.selectArray[i].attr('name');
_selectValue = self.selectArray[i].val(); _selectValue = self.selectArray[i].val();
if (typeof _queryName === 'string' && _queryName.length) { if (typeof _queryName === 'string' && _queryName.length) {
_query[_queryName] = _selectValue; _query[_queryName] = _selectValue;
} else if (typeof _selectName === 'string' && _selectName.length) { } else if (typeof _selectName === 'string' && _selectName.length) {
_query[_selectName] = _selectValue; _query[_selectName] = _selectValue;
}; };
}; };
}; };
$.getJSON(_dataUrl, _query, function(json) { $.getJSON(_dataUrl, _query, function(json) {
_selectData = cxSelect.getData(json, _jsonSpace); _selectData = cxSelect.getData(json, _jsonSpace);
cxSelect.buildOption.call(self, index, _selectData); cxSelect.buildOption.call(self, index, _selectData);
}); });
// 使用整合数据 // 使用整合数据
} else if (self.settings.data && typeof self.settings.data === 'object') { } else if (self.settings.data && typeof self.settings.data === 'object') {
_selectData = self.settings.data; _selectData = self.settings.data;
for (var i = 0; i < index; i++) { for (var i = 0; i < index; i++) {
_valueIndex = cxSelect.getIndex(self.selectArray[i][0].selectedIndex, typeof self.selectArray[i].data('required') === 'boolean' ? self.selectArray[i].data('required') : self.settings.required); _valueIndex = cxSelect.getIndex(self.selectArray[i][0].selectedIndex, typeof self.selectArray[i].data('required') === 'boolean' ? self.selectArray[i].data('required') : self.settings.required);
if (typeof _selectData[_valueIndex] === 'object' && $.isArray(_selectData[_valueIndex][self.settings.jsonSub]) && _selectData[_valueIndex][self.settings.jsonSub].length) { if (typeof _selectData[_valueIndex] === 'object' && $.isArray(_selectData[_valueIndex][self.settings.jsonSub]) && _selectData[_valueIndex][self.settings.jsonSub].length) {
_selectData = _selectData[_valueIndex][self.settings.jsonSub]; _selectData = _selectData[_valueIndex][self.settings.jsonSub];
} else { } else {
_selectData = null; _selectData = null;
break; break;
}; };
}; };
cxSelect.buildOption.call(self, index, _selectData); cxSelect.buildOption.call(self, index, _selectData);
}; };
}; };
// 构建选项列表 // 构建选项列表
cxSelect.buildOption = function(index, data) { cxSelect.buildOption = function(index, data) {
var self = this; var self = this;
var _select = self.selectArray[index]; var _select = self.selectArray[index];
var _required = typeof _select.data('required') === 'boolean' ? _select.data('required') : self.settings.required; var _required = typeof _select.data('required') === 'boolean' ? _select.data('required') : self.settings.required;
var _firstTitle = typeof _select.data('firstTitle') === 'undefined' ? self.settings.firstTitle : _select.data('firstTitle'); var _firstTitle = typeof _select.data('firstTitle') === 'undefined' ? self.settings.firstTitle : _select.data('firstTitle');
var _firstValue = typeof _select.data('firstValue') === 'undefined' ? self.settings.firstValue : _select.data('firstValue'); var _firstValue = typeof _select.data('firstValue') === 'undefined' ? self.settings.firstValue : _select.data('firstValue');
var _jsonName = typeof _select.data('jsonName') === 'undefined' ? self.settings.jsonName : _select.data('jsonName'); var _jsonName = typeof _select.data('jsonName') === 'undefined' ? self.settings.jsonName : _select.data('jsonName');
var _jsonValue = typeof _select.data('jsonValue') === 'undefined' ? self.settings.jsonValue : _select.data('jsonValue'); var _jsonValue = typeof _select.data('jsonValue') === 'undefined' ? self.settings.jsonValue : _select.data('jsonValue');
if (!$.isArray(data)) {return}; if (!$.isArray(data)) {return};
var _html = !_required ? '<option value="' + String(_firstValue) + '">' + String(_firstTitle) + '</option>' : ''; var _html = !_required ? '<option value="' + String(_firstValue) + '">' + String(_firstTitle) + '</option>' : '';
// 区分标题、值的数据 // 区分标题、值的数据
if (typeof _jsonName === 'string' && _jsonName.length) { if (typeof _jsonName === 'string' && _jsonName.length) {
// 无值字段时使用标题作为值 // 无值字段时使用标题作为值
if (typeof _jsonValue !== 'string' || !_jsonValue.length) { if (typeof _jsonValue !== 'string' || !_jsonValue.length) {
_jsonValue = _jsonName; _jsonValue = _jsonName;
}; };
for (var i = 0, l = data.length; i < l; i++) { for (var i = 0, l = data.length; i < l; i++) {
_html += '<option value="' + String(data[i][_jsonValue]) + '">' + String(data[i][_jsonName]) + '</option>'; _html += '<option value="' + String(data[i][_jsonValue]) + '">' + String(data[i][_jsonName]) + '</option>';
}; };
// 数组即为值的数据 // 数组即为值的数据
} else { } else {
for (var i = 0, l = data.length; i < l; i++) { for (var i = 0, l = data.length; i < l; i++) {
_html += '<option value="' + String(data[i]) + '">' + String(data[i]) + '</option>'; _html += '<option value="' + String(data[i]) + '">' + String(data[i]) + '</option>';
}; };
}; };
_select.html(_html).prop('disabled', false).css({ _select.html(_html).prop('disabled', false).css({
'display': '', 'display': '',
'visibility': '' 'visibility': ''
}); });
// 初次加载设置默认值 // 初次加载设置默认值
if (typeof _select.attr('data-value') === 'string') { if (typeof _select.attr('data-value') === 'string') {
_select.val(String(_select.attr('data-value'))).removeAttr('data-value'); _select.val(String(_select.attr('data-value'))).removeAttr('data-value');
if (_select[0].selectedIndex < 0) { if (_select[0].selectedIndex < 0) {
_select[0].options[0].selected = true; _select[0].options[0].selected = true;
}; };
}; };
if (_required || _select[0].selectedIndex > 0) { if (_required || _select[0].selectedIndex > 0) {
_select.trigger('change'); _select.trigger('change');
}; };
}; };
// 改变选择时的处理 // 改变选择时的处理
cxSelect.selectChange = function(name) { cxSelect.selectChange = function(name) {
var self = this; var self = this;
if (typeof name !== 'string' || !name.length) {return}; if (typeof name !== 'string' || !name.length) {return};
var index; var index;
name = name.replace(/\s+/g, ','); name = name.replace(/\s+/g, ',');
name = ',' + name + ','; name = ',' + name + ',';
// 获取当前 select 位置 // 获取当前 select 位置
for (var i = 0, l = self.selectArray.length; i < l; i++) { for (var i = 0, l = self.selectArray.length; i < l; i++) {
if (name.indexOf(',' + self.settings.selects[i] + ',') > -1) { if (name.indexOf(',' + self.settings.selects[i] + ',') > -1) {
index = i; index = i;
break; break;
}; };
}; };
if (typeof index === 'number' && index > -1) { if (typeof index === 'number' && index > -1) {
index += 1; index += 1;
cxSelect.getOptionData.call(self, index); cxSelect.getOptionData.call(self, index);
}; };
}; };
$.cxSelect = function() { $.cxSelect = function() {
return cxSelect.apply(this, arguments); return cxSelect.apply(this, arguments);
}; };
// 默认值 // 默认值
$.cxSelect.defaults = { $.cxSelect.defaults = {
selects: [], // 下拉选框组 selects: [], // 下拉选框组
url: null, // 列表数据文件路径URL或数组数据 url: null, // 列表数据文件路径URL或数组数据
data: null, // 自定义数据 data: null, // 自定义数据
emptyStyle: null, // 无数据状态显示方式 emptyStyle: null, // 无数据状态显示方式
required: false, // 是否为必选 required: false, // 是否为必选
firstTitle: '请选择', // 第一个选项的标题 firstTitle: '请选择', // 第一个选项的标题
firstValue: '', // 第一个选项的值 firstValue: '', // 第一个选项的值
jsonSpace: '', // 数据命名空间 jsonSpace: '', // 数据命名空间
jsonName: 'n', // 数据标题字段名称 jsonName: 'n', // 数据标题字段名称
jsonValue: '', // 数据值字段名称 jsonValue: '', // 数据值字段名称
jsonSub: 's' // 子集数据字段名称 jsonSub: 's' // 子集数据字段名称
}; };
$.fn.cxSelect = function(settings, callback) { $.fn.cxSelect = function(settings, callback) {
this.each(function(i) { this.each(function(i) {
$.cxSelect(this, settings, callback); $.cxSelect(this, settings, callback);
}); });
return this; return this;
}; };
})); }));

File diff suppressed because one or more lines are too long

@ -1,21 +1,21 @@
/*! /*!
* jQuery Validation Plugin v1.19.1 * jQuery Validation Plugin v1.19.1
* *
* https://jqueryvalidation.org/ * https://jqueryvalidation.org/
* *
* Copyright (c) 2019 Jörn Zaefferer * Copyright (c) 2019 Jörn Zaefferer
* Released under the MIT license * Released under the MIT license
*/ */
(function( factory ) { (function( factory ) {
if ( typeof define === "function" && define.amd ) { if ( typeof define === "function" && define.amd ) {
define( ["jquery"], factory ); define( ["jquery"], factory );
} else if (typeof module === "object" && module.exports) { } else if (typeof module === "object" && module.exports) {
module.exports = factory( require( "jquery" ) ); module.exports = factory( require( "jquery" ) );
} else { } else {
factory( jQuery ); factory( jQuery );
} }
}(function( $ ) { }(function( $ ) {
$.extend( $.fn, { $.extend( $.fn, {
// https://jqueryvalidation.org/validate/ // https://jqueryvalidation.org/validate/
@ -1610,7 +1610,7 @@ $.extend( $.validator, {
} }
} ); } );
// Ajax mode: abort // Ajax mode: abort
// usage: $.ajax({ mode: "abort"[, port: "uniqueport"]}); // usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
// if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort() // if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()
@ -1646,5 +1646,5 @@ if ( $.ajaxPrefilter ) {
return ajax.apply( this, arguments ); return ajax.apply( this, arguments );
}; };
} }
return $; return $;
})); }));

@ -25,7 +25,7 @@ a {
} }
} }
input.danger { textarea.danger, input.danger {
border-color: #dc3545!important; border-color: #dc3545!important;
} }
@ -43,4 +43,8 @@ label.error {
height: calc(1.5em + 0.75rem + 2px) height: calc(1.5em + 0.75rem + 2px)
} }
} }
}
.flex-1 {
flex: 1;
} }

@ -100,5 +100,11 @@
font-size: 24px; font-size: 24px;
} }
} }
.nav-tabs {
.nav-link {
padding: 0.5rem 2rem;
}
}
} }

@ -0,0 +1,9 @@
.admins-identity-authentications-index-page {
.identity-authentication-list-container {
span {
&.apply-status-1 { color: #28a745; }
&.apply-status-2 { color: #dc3545; }
&.apply-status-3 { color: #6c757d; }
}
}
}

@ -0,0 +1,9 @@
.admins-professional-authentications-index-page {
.professional-authentication-list-container {
span {
&.apply-status-1 { color: #28a745; }
&.apply-status-2 { color: #dc3545; }
&.apply-status-3 { color: #6c757d; }
}
}
}

@ -0,0 +1,26 @@
class Admins::IdentityAuthenticationsController < Admins::BaseController
def index
params[:status] ||= 'pending'
applies = Admins::ApplyUserAuthenticationQuery.call(params.merge(type: 1))
@applies = paginate applies.preload(user: { user_extension: [:school, :department] })
end
def agree
Admins::IdentityAuths::AgreeApplyService.call(current_apply)
render_success_js
end
def refuse
Admins::IdentityAuths::RefuseApplyService.call(current_apply, params)
render_success_js
end
private
def current_apply
@_current_apply ||= ApplyUserAuthentication.real_name_auth.find(params[:id])
end
end

@ -0,0 +1,26 @@
class Admins::ProfessionalAuthenticationsController < Admins::BaseController
def index
params[:status] ||= 'pending'
applies = Admins::ApplyUserAuthenticationQuery.call(params.merge(type: 2))
@applies = paginate applies.preload(user: { user_extension: [:school, :department] })
end
def agree
Admins::ProfessionalAuths::AgreeApplyService.call(current_apply)
render_success_js
end
def refuse
Admins::ProfessionalAuths::RefuseApplyService.call(current_apply, params)
render_success_js
end
private
def current_apply
@_current_apply ||= ApplyUserAuthentication.professional_auth.find(params[:id])
end
end

@ -40,6 +40,7 @@ module Admins::RenderHelper
def render_delete_success def render_delete_success
render_js_template 'admins/shared/delete' render_js_template 'admins/shared/delete'
end end
alias_method :render_success_js, :render_delete_success
def render_js_error(message) def render_js_error(message)
render_js_template 'admins/shared/error', locals: { message: message } render_js_template 'admins/shared/error', locals: { message: message }

@ -0,0 +1,102 @@
module Admins::BaseHelper
def sidebar_item_group(url, text, **opts)
link_opts = url.start_with?('/') ? {} : { 'data-toggle': 'collapse', 'aria-expanded': false }
content =
link_to url, link_opts do
content_tag(:i, '', class: "fa fa-#{opts[:icon]}", 'data-toggle': 'tooltip', 'data-placement': 'right', 'data-boundary': 'window', title: text) +
content_tag(:span, text)
end
content +=
content_tag(:ul, id: url[1..-1], class: 'collapse list-unstyled', "data-parent": '#sidebar') do
yield
end
raw content
end
def sidebar_item(url, text, **opts)
content =
link_to url, 'data-controller': opts[:controller] do
content_tag(:i, '', class: "fa fa-#{opts[:icon]}", 'data-toggle': 'tooltip', 'data-placement': 'right', 'data-boundary': 'window', title: text) +
content_tag(:span, text)
end
raw content
end
def admin_sidebar_controller
key = params[:controller].to_s.gsub(/\//, '-')
SidebarUtil.controller_name(key) || key
end
def define_admin_breadcrumbs(&block)
content_for(:setup_admin_breadcrumb, &block)
end
def add_admin_breadcrumb(text, url = nil)
@_admin_breadcrumbs ||= []
@_admin_breadcrumbs << OpenStruct.new(text: text, url: url)
end
def display_text(str, default = '--')
str.presence || default
end
def overflow_hidden_span(text, width: 300)
opts = { class: 'd-inline-block text-truncate', style: "max-width: #{width}px" }
opts.merge!('data-toggle': 'tooltip', title: text) if text != '--'
content_tag(:span, text, opts)
end
def sort_tag(content = '', **opts)
options = {}
options[:sort_by] = opts.delete(:name)
is_current_sort = params[:sort_by].to_s == options[:sort_by]
options[:sort_direction] = is_current_sort && params[:sort_direction].to_s == 'desc' ? 'asc' : 'desc'
path = opts.delete(:path) + "?" + unsafe_params.merge(options).to_query
arrow_class = case params[:sort_direction].to_s
when 'desc' then 'fa-sort-amount-desc'
when 'asc' then 'fa-sort-amount-asc'
else ''
end
opts[:style] = "#{opts[:style]} ;position: relative;"
content_tag(:span, opts) do
link_to path, remote: true do
content = content_tag(:span) { yield } if block_given?
content += content_tag(:i, '', class: "fa color-light-green ml-1 #{arrow_class}", style: 'position: absolute;top:0;') if is_current_sort
raw content
end
end
end
def javascript_void_link(name, **opts)
raw link_to(name, 'javascript:void(0)', opts)
end
def agree_link(name, url, **opts)
klass = ['action agree-action', opts.delete(:class)].compact.join(' ')
refresh_url_data = "refresh_url=#{CGI::escape(request.fullpath)}"
url = url + (url.index('?') ? '&' : '?') + refresh_url_data
raw link_to(name, url, { method: :post, remote: true, class: klass, 'data-confirm': '确认审核通过?'}.merge(opts))
end
def delete_link(name, url, **opts)
klass = ['action delete-action', opts.delete(:class)].compact.join(' ')
refresh_url_data = "refresh_url=#{CGI::escape(request.fullpath)}"
url = url + (url.index('?') ? '&' : '?') + refresh_url_data
raw link_to(name, url, { method: :delete, remote: true, class: klass, 'data-confirm': '确认删除?'}.merge(opts))
end
def unsafe_params
params.except(:controller, :action).to_unsafe_h
end
end

@ -158,10 +158,22 @@ module ApplicationHelper
disk_auth_filename('UserAuthentication', source_id, 'ID') disk_auth_filename('UserAuthentication', source_id, 'ID')
end end
def auth_file_url(source_type, source_id, type)
File.join('/images', relative_path, source_type, "#{source_id}#{type}")
end
def real_name_auth_file_url(source_id)
auth_file_url('UserAuthentication', source_id, 'ID')
end
def disk_professional_auth_filename(source_id) def disk_professional_auth_filename(source_id)
disk_auth_filename('UserAuthentication', source_id, 'PRO') disk_auth_filename('UserAuthentication', source_id, 'PRO')
end end
def professional_auth_file_url(source_id)
auth_file_url('UserAuthentication', source_id, 'PRO')
end
def shixun_url_to_avatar(shixun) def shixun_url_to_avatar(shixun)
if File.exist?(disk_filename(shixun.class, shixun.id)) if File.exist?(disk_filename(shixun.class, shixun.id))
File.join("images/#{relative_path}", "#{shixun.class}", "#{shixun.id}") File.join("images/#{relative_path}", "#{shixun.class}", "#{shixun.id}")
@ -386,95 +398,6 @@ module ApplicationHelper
m_t&.include?("src=\"") ? m_t&.gsub("src=\"","src=\"#{origin_url}") : m_t m_t&.include?("src=\"") ? m_t&.gsub("src=\"","src=\"#{origin_url}") : m_t
end end
# =========== Admin Helpers Begin ===========
def sidebar_item_group(url, text, **opts)
link_opts = url.start_with?('/') ? {} : { 'data-toggle': 'collapse', 'aria-expanded': false }
content =
link_to url, link_opts do
content_tag(:i, '', class: "fa fa-#{opts[:icon]}", 'data-toggle': 'tooltip', 'data-placement': 'right', 'data-boundary': 'window', title: text) +
content_tag(:span, text)
end
content +=
content_tag(:ul, id: url[1..-1], class: 'collapse list-unstyled', "data-parent": '#sidebar') do
yield
end
raw content
end
def sidebar_item(url, text, **opts)
content =
link_to url, 'data-controller': opts[:controller] do
content_tag(:i, '', class: "fa fa-#{opts[:icon]}", 'data-toggle': 'tooltip', 'data-placement': 'right', 'data-boundary': 'window', title: text) +
content_tag(:span, text)
end
raw content
end
def admin_sidebar_controller
key = params[:controller].to_s.gsub(/\//, '-')
SidebarUtil.controller_name(key) || key
end
def define_admin_breadcrumbs(&block)
content_for(:setup_admin_breadcrumb, &block)
end
def add_admin_breadcrumb(text, url = nil)
@_admin_breadcrumbs ||= []
@_admin_breadcrumbs << OpenStruct.new(text: text, url: url)
end
def display_text(str, default = '--')
str.presence || default
end
def overflow_hidden_span(text, width: 300)
opts = { class: 'd-inline-block text-truncate', style: "max-width: #{width}px" }
opts.merge!('data-toggle': 'tooltip', title: text) if text != '--'
content_tag(:span, text, opts)
end
def sort_tag(content = '', **opts)
options = {}
options[:sort_by] = opts.delete(:name)
is_current_sort = params[:sort_by].to_s == options[:sort_by]
options[:sort_direction] = is_current_sort && params[:sort_direction].to_s == 'desc' ? 'asc' : 'desc'
path = opts.delete(:path) + "?" + params.slice(:action, :controller).merge(options).to_unsafe_h.to_query
arrow_class = case params[:sort_direction].to_s
when 'desc' then 'fa-sort-amount-desc'
when 'asc' then 'fa-sort-amount-asc'
else ''
end
opts[:style] = "#{opts[:style]} ;position: relative;"
content_tag(:span, opts) do
link_to path, remote: true do
content = content_tag(:span) { yield } if block_given?
content += content_tag(:i, '', class: "fa color-light-green ml-1 #{arrow_class}", style: 'position: absolute;top:0;') if is_current_sort
raw content
end
end
end
def javascript_void_link(name, **opts)
raw link_to(name, 'javascript:void(0)', opts)
end
def delete_link(name, url, **opts)
klass = ['action delete-action', opts.delete(:class)].compact.join(' ')
refresh_url_data = "refresh_url=#{CGI::escape(request.fullpath)}"
url = url + (url.index('?') ? '&' : '?') + refresh_url_data
raw link_to(name, url, { method: :delete, remote: true, class: klass, 'data-confirm': '确认删除?'}.merge(opts))
end
# =========== Admin Helpers End ===========
end end

@ -0,0 +1,40 @@
module Util::FileManage
module_function
# 不同的类型扩展不同的目录
def relative_path
"avatars"
end
def storage_path
File.join(Rails.root, "public", "images", relative_path)
end
def disk_filename(source_type,source_id,image_file=nil)
File.join(storage_path, "#{source_type}", "#{source_id}")
end
def disk_auth_filename(source_type, source_id, type)
File.join(storage_path, "#{source_type}", "#{source_id}#{type}")
end
def disk_real_name_auth_filename(source_id)
disk_auth_filename('UserAuthentication', source_id, 'ID')
end
def auth_file_url(source_type, source_id, type)
File.join('/images', relative_path, source_type, "#{source_id}#{type}")
end
def real_name_auth_file_url(source_id)
auth_file_url('UserAuthentication', source_id, 'ID')
end
def disk_professional_auth_filename(source_id)
disk_auth_filename('UserAuthentication', source_id, 'PRO')
end
def professional_auth_file_url(source_id)
auth_file_url('UserAuthentication', source_id, 'PRO')
end
end

@ -12,6 +12,12 @@ class ApplyUserAuthentication < ApplicationRecord
after_create :send_tiding after_create :send_tiding
def status_text
I18n.t!("apply_user_authentication.status.#{status}")
rescue I18n::MissingTranslationData
nil
end
private private
def send_tiding def send_tiding

@ -0,0 +1,34 @@
class Admins::ApplyUserAuthenticationQuery < ApplicationQuery
include CustomSortable
attr_reader :params
sort_columns :updated_at, default_by: :updated_at, default_direction: :desc
def initialize(params)
@params = params
end
def call
applies = ApplyUserAuthentication.where(auth_type: params[:type].presence || 1)
status =
case params[:status]
when 'pending' then 0
when 'processed' then [1, 2]
when 'agreed' then 1
when 'refused' then 2
else 0
end
applies = applies.where(status: status) if status.present?
# 关键字模糊查询
keyword = params[:keyword].to_s.strip
if keyword.present?
applies = applies.joins(user: { user_extension: :school })
.where('CONCAT(lastname,firstname) LIKE :keyword OR schools.name LIKE :keyword', keyword: "%#{keyword}%")
end
custom_sort(applies, params[:sort_by], params[:sort_direction])
end
end

@ -0,0 +1,38 @@
class Admins::IdentityAuths::AgreeApplyService < ApplicationService
attr_reader :apply, :user
def initialize(apply)
@apply = apply
@user = apply.user
end
def call
ActiveRecord::Base.transaction do
apply.update!(status: 1)
user.update!(authentication: true)
RewardGradeService.call(user, container_id: user.id, container_type: 'Authentication', score: 500)
deal_tiding!
delete_auth_file!
end
end
private
def deal_tiding!
apply.tidings.where(tiding_type: 'Apply').update_all(status: 1)
Tiding.create!(user_id: apply.user_id, trigger_user_id: 0,
container_id: apply.id, container_type: 'ApplyUserAuthentication',
belong_container_id: apply.user_id, belong_container_type: 'User',
status: 1, tiding_type: 'System')
end
def delete_auth_file!
path = Util::FileManage.disk_real_name_auth_filename(user.id)
File.delete(path) if File.exists?(path)
apply.update!(is_delete: true)
end
end

@ -0,0 +1,40 @@
class Admins::IdentityAuths::RefuseApplyService < ApplicationService
attr_reader :apply, :user, :params
def initialize(apply, params)
@apply = apply
@user = apply.user
@params = params
end
def call
ActiveRecord::Base.transaction do
apply.update!(status: 2, remarks: reason)
deal_tiding!
delete_auth_file!
end
end
private
def reason
params[:reason].to_s.strip
end
def deal_tiding!
apply.tidings.where(tiding_type: 'Apply').update_all(status: 1)
Tiding.create!(user_id: apply.user_id, trigger_user_id: 0,
container_id: apply.id, container_type: 'ApplyUserAuthentication',
belong_container_id: apply.user_id, belong_container_type: 'User',
status: 2, tiding_type: 'System')
end
def delete_auth_file!
path = Util::FileManage.disk_real_name_auth_filename(user.id)
File.delete(path) if File.exists?(path)
apply.update!(is_delete: true)
end
end

@ -0,0 +1,38 @@
class Admins::ProfessionalAuths::AgreeApplyService < ApplicationService
attr_reader :apply, :user
def initialize(apply)
@apply = apply
@user = apply.user
end
def call
ActiveRecord::Base.transaction do
apply.update!(status: 1)
user.update!(professional_certification: true)
RewardGradeService.call(user, container_id: user.id, container_type: 'Professional', score: 500)
deal_tiding!
delete_auth_file!
end
end
private
def deal_tiding!
apply.tidings.where(tiding_type: 'Apply').update_all(status: 1)
Tiding.create!(user_id: apply.user_id, trigger_user_id: 0,
container_id: apply.id, container_type: 'ApplyUserAuthentication',
belong_container_id: apply.user_id, belong_container_type: 'User',
status: 1, tiding_type: 'System')
end
def delete_auth_file!
path = Util::FileManage.disk_professional_auth_filename(user.id)
File.delete(path) if File.exists?(path)
apply.update!(is_delete: true)
end
end

@ -0,0 +1,40 @@
class Admins::ProfessionalAuths::RefuseApplyService < ApplicationService
attr_reader :apply, :user, :params
def initialize(apply, params)
@apply = apply
@user = apply.user
@params = params
end
def call
ActiveRecord::Base.transaction do
apply.update!(status: 2, remarks: reason)
deal_tiding!
delete_auth_file!
end
end
private
def reason
params[:reason].to_s.strip
end
def deal_tiding!
apply.tidings.where(tiding_type: 'Apply').update_all(status: 1)
Tiding.create!(user_id: apply.user_id, trigger_user_id: 0,
container_id: apply.id, container_type: 'ApplyUserAuthentication',
belong_container_id: apply.user_id, belong_container_type: 'User',
status: 2, tiding_type: 'System')
end
def delete_auth_file!
path = Util::FileManage.disk_professional_auth_filename(user.id)
File.delete(path) if File.exists?(path)
apply.update!(is_delete: true)
end
end

@ -0,0 +1,32 @@
<% define_admin_breadcrumbs do %>
<% add_admin_breadcrumb('实名认证') %>
<% end %>
<div class="box search-form-container flex-column mb-0 pb-0 identity-authentication-list-form">
<ul class="nav nav-tabs w-100 search-form-tabs">
<li class="nav-item">
<%= link_to '待审批', admins_identity_authentications_path(status: :pending), remote: true, 'data-value': 'pending',
class: "nav-link search-form-tab #{params[:status] == 'pending' ? 'active' : ''}" %>
</li>
<li class="nav-item">
<%= link_to '已审批', admins_identity_authentications_path(status: :processed), remote: true, 'data-value': 'processed',
class: "nav-link search-form-tab #{params[:status] != 'pending' ? 'active' : ''}" %>
</li>
</ul>
<%= form_tag(admins_identity_authentications_path(unsafe_params), method: :get, class: 'form-inline search-form justify-content-end mt-3', remote: true) do %>
<div class="form-group status-filter" style="<%= params[:status] != 'pending' ? '' : 'display: none;' %>">
<label for="status">审核状态:</label>
<% status_options = [['全部', 'processed'], ['已同意', 'agreed'], ['已拒绝', 'refused']] %>
<%= select_tag(:status, options_for_select(status_options), class: 'form-control') %>
</div>
<%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: '姓名/学校/单位检索') %>
<%= submit_tag('搜索', class: 'btn btn-primary ml-3') %>
<% end %>
</div>
<div class="box identity-authentication-list-container">
<%= render(partial: 'admins/identity_authentications/shared/list', locals: { applies: @applies }) %>
</div>
<%= render(partial: 'admins/shared/admin_common_refuse_modal') %>

@ -0,0 +1 @@
$('.identity-authentication-list-container').html("<%= j( render partial: 'admins/identity_authentications/shared/list', locals: { applies: @applies } ) %>");

@ -0,0 +1,74 @@
<% is_processed = params[:status].to_s != 'pending' %>
<table class="table table-hover text-center identity-authentication-list-table">
<thead class="thead-light">
<tr>
<th width="8%">头像</th>
<th width="10%">姓名</th>
<th width="14%">身份证号</th>
<th width="20%">学校/单位</th>
<th width="12%">职称</th>
<% unless is_processed %>
<th width="8%">
照片
<i class="fa fa-question-circle" data-toggle="tooltip" data-html="true" data-placement="top" title="审核完成后自动删除图片"></i>
</th>
<% end %>
<th width="16%">时间</th>
<% if is_processed %>
<th width="14%">拒绝原因</th>
<th width="8%">状态</th>
<% else %>
<th width="20%">操作</th>
<% end %>
</tr>
</thead>
<tbody>
<% if applies.present? %>
<% applies.each do |apply| %>
<% user = apply.user %>
<tr class="identity-authentication-item identity-authentication-<%= apply.id %>">
<td>
<%= link_to "/users/#{user.login}", class: 'identity-authentication-avatar', target: '_blank', data: { toggle: 'tooltip', title: '个人主页' } do %>
<img src="/images/<%= url_to_avatar(user) %>" class="rounded-circle" width="40" height="40" />
<% end %>
</td>
<td><%= user.real_name %></td>
<td><%= user.ID_number %></td>
<td><%= raw [user.school_name.presence, user.department_name.presence].compact.join('<br/>') %></td>
<td><%= user.identity %> <%= raw user.user_extension.student? && user.student_id ? "<br/>#{user.student_id}" : '' %></td>
<% unless is_processed %>
<td>
<% if File.exists?(disk_real_name_auth_filename(user.id)) %>
<%= image_tag(real_name_auth_file_url(user.id).to_s + "?#{Time.now.to_i}", width: 40, height: 40, class: 'preview-image auth-image', data: { toggle: 'tooltip', title: '点击预览' }) %>
<% else %>
<%= content_tag(:span, '图片已删除', class: 'text-secondary') %>
<% end %>
</td>
<% end %>
<td><%= apply.updated_at.strftime('%Y-%m-%d %H:%M') %></td>
<% if is_processed %>
<td class="text-secondary"><%= overflow_hidden_span apply.remarks, width: 140 %></td>
<td><span class="apply-status-<%= apply.status %>"><%= apply.status_text %></span></td>
<% else %>
<td class="action-container">
<%= agree_link '同意', agree_admins_identity_authentication_path(apply, element: ".identity-authentication-#{apply.id}"), 'data-confirm': '确认审核通过?' %>
<%= javascript_void_link('拒绝', class: 'action refuse-action',
data: {
toggle: 'modal', target: '.admin-common-refuse-modal', id: apply.id,
url: refuse_admins_identity_authentication_path(apply, element: ".identity-authentication-#{apply.id}")
}) %>
</td>
<% end %>
</tr>
<% end %>
<% else %>
<%= render 'admins/shared/no_data_for_table' %>
<% end %>
</tbody>
</table>
<%= render partial: 'admins/shared/paginate', locals: { objects: applies } %>

@ -0,0 +1,32 @@
<% define_admin_breadcrumbs do %>
<% add_admin_breadcrumb('职业认证') %>
<% end %>
<div class="box search-form-container flex-column mb-0 pb-0 professional-authentication-list-form">
<ul class="nav nav-tabs w-100 search-form-tabs">
<li class="nav-item">
<%= link_to '待审批', admins_professional_authentications_path(status: :pending), remote: true, 'data-value': 'pending',
class: "nav-link search-form-tab #{params[:status] == 'pending' ? 'active' : ''}" %>
</li>
<li class="nav-item">
<%= link_to '已审批', admins_professional_authentications_path(status: :processed), remote: true, 'data-value': 'processed',
class: "nav-link search-form-tab #{params[:status] != 'pending' ? 'active' : ''}" %>
</li>
</ul>
<%= form_tag(admins_professional_authentications_path(unsafe_params), method: :get, class: 'form-inline search-form justify-content-end mt-3', remote: true) do %>
<div class="form-group status-filter" style="<%= params[:status] != 'pending' ? '' : 'display: none;' %>">
<label for="status">审核状态:</label>
<% status_options = [['全部', 'processed'], ['已同意', 'agreed'], ['已拒绝', 'refused']] %>
<%= select_tag(:status, options_for_select(status_options), class: 'form-control') %>
</div>
<%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: '姓名/学校/单位检索') %>
<%= submit_tag('搜索', class: 'btn btn-primary ml-3') %>
<% end %>
</div>
<div class="box professional-authentication-list-container">
<%= render(partial: 'admins/professional_authentications/shared/list', locals: { applies: @applies }) %>
</div>
<%= render(partial: 'admins/shared/admin_common_refuse_modal') %>

@ -0,0 +1 @@
$('.professional-authentication-list-container').html("<%= j( render partial: 'admins/professional_authentications/shared/list', locals: { applies: @applies } ) %>");

@ -0,0 +1,72 @@
<% is_processed = params[:status].to_s != 'pending' %>
<table class="table table-hover text-center professional-authentication-list-table">
<thead class="thead-light">
<tr>
<th width="8%">头像</th>
<th width="14%">姓名</th>
<th width="28%">学校/单位</th>
<th width="12%">职称</th>
<% unless is_processed %>
<th width="10%">
照片
<i class="fa fa-question-circle" data-toggle="tooltip" data-html="true" data-placement="top" title="审核完成后自动删除图片"></i>
</th>
<% end %>
<th width="16%">时间</th>
<% if is_processed %>
<th width="14%">拒绝原因</th>
<th width="8%">状态</th>
<% else %>
<th width="18%">操作</th>
<% end %>
</tr>
</thead>
<tbody>
<% if applies.present? %>
<% applies.each do |apply| %>
<% user = apply.user %>
<tr class="professional-authentication-item professional-authentication-<%= apply.id %>">
<td>
<%= link_to "/users/#{user.login}", class: 'professional-authentication-avatar', target: '_blank', data: { toggle: 'tooltip', title: '个人主页' } do %>
<img src="/images/<%= url_to_avatar(user) %>" class="rounded-circle" width="40" height="40" />
<% end %>
</td>
<td><%= user.real_name %></td>
<td><%= raw [user.school_name.presence, user.department_name.presence].compact.join('<br/>') %></td>
<td><%= user.identity %> <%= raw user.user_extension.student? && user.student_id ? "<br/>#{user.student_id}" : '' %></td>
<% unless is_processed %>
<td>
<% if File.exists?(disk_professional_auth_filename(user.id)) %>
<%= image_tag(professional_auth_file_url(user.id).to_s + "?#{Time.now.to_i}", width: 40, height: 40, class: 'preview-image auth-image', data: { toggle: 'tooltip', title: '点击预览' }) %>
<% else %>
<%= content_tag(:span, '图片已删除', class: 'text-secondary') %>
<% end %>
</td>
<% end %>
<td><%= apply.updated_at.strftime('%Y-%m-%d %H:%M') %></td>
<% if is_processed %>
<td class="text-secondary"><%= overflow_hidden_span apply.remarks, width: 140 %></td>
<td><span class="apply-status-<%= apply.status %>"><%= apply.status_text %></span></td>
<% else %>
<td class="action-container">
<%= agree_link '同意', agree_admins_professional_authentication_path(apply, element: ".professional-authentication-#{apply.id}"), 'data-confirm': '确认审核通过?' %>
<%= javascript_void_link('拒绝', class: 'action refuse-action',
data: {
toggle: 'modal', target: '.admin-common-refuse-modal', id: apply.id,
url: refuse_admins_professional_authentication_path(apply, element: ".professional-authentication-#{apply.id}")
}) %>
</td>
<% end %>
</tr>
<% end %>
<% else %>
<%= render 'admins/shared/no_data_for_table' %>
<% end %>
</tbody>
</table>
<%= render partial: 'admins/shared/paginate', locals: { objects: applies } %>

@ -32,9 +32,9 @@
<div class="type-box ml-3"> <div class="type-box ml-3">
<%= hidden_field_tag :data_type, params[:data_type] || 'grow' %> <%= hidden_field_tag :data_type, params[:data_type] || 'grow' %>
<%= javascript_void_link '时段对比', class: "btn btn-outline-primary btn-sm contrast-btn #{params[:data_type] == 'contrast' ? 'active' : ''}", <%= javascript_void_link '时段对比', class: "btn btn-outline-info btn-sm contrast-btn #{params[:data_type] == 'contrast' ? 'active' : ''}",
data: { toggle: 'tooltip', trigger: 'hover', title: '请在左侧分别选择需进行对比的两个时段具体从当日5:00开始计算下表显示两时段选定指标两时段变化情况对比' } %> data: { toggle: 'tooltip', trigger: 'hover', title: '请在左侧分别选择需进行对比的两个时段具体从当日5:00开始计算下表显示两时段选定指标两时段变化情况对比' } %>
<%= javascript_void_link '数据变化', class: "btn btn-outline-primary btn-sm grow-btn #{params[:data_type] == 'contrast' ? '' : 'active'}", <%= javascript_void_link '数据变化', class: "btn btn-outline-info btn-sm grow-btn #{params[:data_type] == 'contrast' ? '' : 'active'}",
data: { toggle: 'tooltip', trigger: 'hover', title: '请在左侧选择时间段具体从当日5:00开始计算下表显示选定时间段内各项指标数据变化情况' } %> data: { toggle: 'tooltip', trigger: 'hover', title: '请在左侧选择时间段具体从当日5:00开始计算下表显示选定时间段内各项指标数据变化情况' } %>
</div> </div>

@ -0,0 +1,26 @@
<div class="modal fade admin-common-refuse-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" id="exampleModalLongTitle">拒绝原因</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-common-refuse-form">
<%= hidden_field_tag(:apply_id, nil) %>
<div class="form-group">
<label for="reason" class="col-form-label">原因:</label>
<%= text_area_tag(:reason, nil, class: 'form-control', placeholder: '我得说点儿什么最多200字') %>
</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>

@ -37,6 +37,13 @@
<% end %> <% end %>
</li> </li>
<li>
<%= sidebar_item_group('#apply-review-submenu', '审核', icon: 'gavel') do %>
<li><%= sidebar_item(admins_identity_authentications_path, '实名认证', icon: 'id-card-o', controller: 'admins-identity_authentications') %></li>
<li><%= sidebar_item(admins_professional_authentications_path, '职业认证', icon: 'drivers-license', controller: 'admins-professional_authentications') %></li>
<% end %>
</li>
<li><%= sidebar_item('/', '返回主站', icon: 'sign-out', controller: 'root') %></li> <li><%= sidebar_item('/', '返回主站', icon: 'sign-out', controller: 'root') %></li>
</ul> </ul>
</nav> </nav>

@ -1,3 +1,4 @@
; ;
$('[data-toggle="tooltip"]').tooltip(); $('[data-toggle="tooltip"]').tooltip();
$('[data-toggle="popover"]').popover(); $('[data-toggle="popover"]').popover();
$('img.preview-image').bootstrapViewer();

@ -1,6 +1,8 @@
var deleteRow = $('<%= params[:element] %>'); var deleteRow = $('<%= params[:element] %>');
var refreshUrl = '<%= params[:refresh_url] %>'; var refreshUrl = '<%= params[:refresh_url] %>';
$.notify({ message: '操作成功' },{ type: 'success' });
var refreshFunc = function(url) { var refreshFunc = function(url) {
$.ajax({ $.ajax({
url: url.length > 0 ? url : window.location.href, url: url.length > 0 ? url : window.location.href,

@ -1,29 +1,23 @@
<table class="table table-hover users-list-table"> <table class="table table-hover users-list-table">
<thead class="thead-light"> <thead class="thead-light">
<tr> <tr>
<th width="10%">ID</th> <th width="10%" class="text-left">真实姓名</th>
<th width="10%">真实姓名</th>
<th width="16%">邮件地址</th> <th width="16%">邮件地址</th>
<th width="10%">手机号码</th> <th width="10%">手机号码</th>
<th width="14%">单位</th> <th width="14%">单位</th>
<th width="12%"><%= sort_tag('创建于', name: 'created_on', path: admins_users_path) %></th> <th width="10%"><%= sort_tag('创建于', name: 'created_on', path: admins_users_path) %></th>
<th width="12%"><%= sort_tag('最后登录', name: 'last_login_on', path: admins_users_path) %></th> <th width="10%"><%= sort_tag('最后登录', name: 'last_login_on', path: admins_users_path) %></th>
<th width="10%"><%= sort_tag('经验值', name: 'experience', path: admins_users_path) %></th> <th width="6%"><%= sort_tag('经验值', name: 'experience', path: admins_users_path) %></th>
<th width="8%"><%= sort_tag('金币', name: 'grade', path: admins_users_path) %></th> <th width="6%"><%= sort_tag('金币', name: 'grade', path: admins_users_path) %></th>
<th width="14%">操作</th> <th width="20%">操作</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<% if users.present? %> <% if users.present? %>
<% users.each do |user| %> <% users.each do |user| %>
<tr class="user-item-<%= user.id %>"> <tr class="user-item-<%= user.id %>">
<td> <td class="text-left">
<%= link_to "/users/#{user.login}", target: '_blank' do %> <%= link_to "/users/#{user.login}", target: '_blank' do %>
<%= overflow_hidden_span user.login, width: 100 %>
<% end %>
</td>
<td>
<%= link_to edit_admins_user_path(user) do %>
<%= overflow_hidden_span user.real_name, width: 100 %> <%= overflow_hidden_span user.real_name, width: 100 %>
<% end %> <% end %>
</td> </td>
@ -35,6 +29,8 @@
<td><%= user.experience.to_i %></td> <td><%= user.experience.to_i %></td>
<td class="grade-content"><%= user.grade.to_i %></td> <td class="grade-content"><%= user.grade.to_i %></td>
<td class="action-container"> <td class="action-container">
<%= link_to '编辑', edit_admins_user_path(user), class: 'action' %>
<%= javascript_void_link('奖励', class: 'action reward-grade-action', data: { toggle: 'modal', target: '.admin-users-reward-grade-modal', id: user.id }) %> <%= javascript_void_link('奖励', class: 'action reward-grade-action', data: { toggle: 'modal', target: '.admin-users-reward-grade-modal', id: user.id }) %>
<%= javascript_void_link '解锁', class: 'action unlock-action', data: { id: user.id, confirm: '确认解锁吗?' }, style: user.locked? ? '' : 'display: none;' %> <%= javascript_void_link '解锁', class: 'action unlock-action', data: { id: user.id, confirm: '确认解锁吗?' }, style: user.locked? ? '' : 'display: none;' %>

@ -0,0 +1,7 @@
zh-CN:
apply_user_authentication:
status:
'0': '待处理'
'1': '已同意'
'2': '已拒绝'
'3': '已撤销'

@ -753,7 +753,7 @@ Rails.application.routes.draw do
get :contrast, on: :collection get :contrast, on: :collection
end end
resources :users, only: [:index, :edit, :update] do resources :users, only: [:index, :edit, :update, :destroy] do
member do member do
post :reward_grade post :reward_grade
post :lock post :lock
@ -761,6 +761,19 @@ Rails.application.routes.draw do
post :active post :active
end end
end end
resources :identity_authentications, only: [:index] do
member do
post :agree
post :refuse
end
end
resources :professional_authentications, only: [:index] do
member do
post :agree
post :refuse
end
end
end end
#git 认证回调 #git 认证回调

@ -30,7 +30,8 @@ module.exports = {
// You may want 'eval' instead if you prefer to see the compiled output in DevTools. // 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 // See the discussion in https://github.com/facebookincubator/create-react-app/issues/343.s
// devtool: "cheap-module-eval-source-map", // devtool: "cheap-module-eval-source-map",
// 开启调试 // 开启调试
devtool: "source-map", // 开启调试
// These are the "entry points" to our application. // These are the "entry points" to our application.
// This means they will be the "root" imports that are included in JS bundle. // 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. // The first two entry points enable "hot" CSS and auto-refreshes for JS.

@ -195,7 +195,29 @@ function generateNewIndexJsp() {
let cdnHost = 'https://shixun.educoder.net' let cdnHost = 'https://shixun.educoder.net'
cdnHost = 'https://ali-cdn.educoder.net' cdnHost = 'https://ali-cdn.educoder.net'
cdnHost = '' cdnHost = ''
var result = data.replace('/js/js_min_all.js', `${cdnHost}/react/build/js/js_min_all.js?v=${newVersion}`)
var mainRegex = /<script type="text\/javascript" src="\/react\/build\/.\/static\/js\/main.([a-zA-Z0-9]{8,}).js"><\/script>/
var matchResult = data.match(mainRegex)
var code = `
<script>
(function() {
var _host = ''
if (window.location.host == 'pre-newweb.educoder.net') {
_host = 'https://testali-cdn.educoder.net/react/build/'
} else if (window.location.host == 'www.educoder.net') {
_host = 'https://ali-newweb.educoder.net/react/build/'
}
document.write('<script type="text/javascript" src="' + _host + 'js/js_min_all.js"><\\/script>');
document.write('<script type="text/javascript" src="' + _host + 'static/js/main.${matchResult[1]}.js"><\\/script>');
})()
</script>
`
var jsMinAllRegex = /<script type="text\/javascript" src="\/js\/js_min_all.js"><\/script>/
// <script type="text/javascript" src="/js/js_min_all.js"></script>
var result = data
.replace(jsMinAllRegex, code)
// .replace('/js/js_min_all.js', `${cdnHost}/react/build/js/js_min_all.js?v=${newVersion}`)
// .replace('/js/js_min_all_2.js', `${cdnHost}/react/build/js/js_min_all_2.js?v=${newVersion}`) // .replace('/js/js_min_all_2.js', `${cdnHost}/react/build/js/js_min_all_2.js?v=${newVersion}`)
// ${cdnHost} 加了cdn后这个文件里的字体文件加载会有跨域的报错 ../fonts/fontawesome-webfont.eot // ${cdnHost} 加了cdn后这个文件里的字体文件加载会有跨域的报错 ../fonts/fontawesome-webfont.eot
@ -204,10 +226,11 @@ function generateNewIndexJsp() {
.replace('/css/iconfont.css', `${cdnHost}/react/build/css/iconfont.css?v=${newVersion}`) .replace('/css/iconfont.css', `${cdnHost}/react/build/css/iconfont.css?v=${newVersion}`)
.replace(/\/js\/create_kindeditor.js/g, `${cdnHost}/react/build/js/create_kindeditor.js?v=${newVersion}`) .replace(/\/js\/create_kindeditor.js/g, `${cdnHost}/react/build/js/create_kindeditor.js?v=${newVersion}`)
.replace(mainRegex, '')
// .replace('/react/build/./static/css/main', `${cdnHost}/react/build/./static/css/main`) // .replace('/react/build/./static/css/main', `${cdnHost}/react/build/./static/css/main`)
// .replace('/react/build/./static/js/main', `${cdnHost}/react/build/./static/js/main`) // .replace('/react/build/./static/js/main', `${cdnHost}/react/build/./static/js/main`)
.replace(/https:\/\/testeduplus2.educoder.net/g, ''); // .replace(/https:\/\/testeduplus2.educoder.net/g, '');
// .replace(/http:\/\/testbdweb.educoder.net/g, ''); // .replace(/http:\/\/testbdweb.educoder.net/g, '');
// .replace('/css/css_min_all.css', '/react/build/css/css_min_all.css'); // .replace('/css/css_min_all.css', '/react/build/css/css_min_all.css');

@ -55,6 +55,10 @@ html, body {
.markdown-body p { .markdown-body p {
white-space: pre-wrap; white-space: pre-wrap;
} }
/* https://www.educoder.net/courses/2346/group_homeworks/34405/question */
.renderAsHtml.markdown-body p {
white-space: inherit;
}
/* resize */ /* resize */
.editormd .CodeMirror { .editormd .CodeMirror {
border-right: none !important; border-right: none !important;

@ -1,4 +1,5 @@
import React, {Component} from 'react'; import React, {Component} from 'react';
import './public-path';
import logo from './logo.svg'; import logo from './logo.svg';
import './App.css'; import './App.css';
import {LocaleProvider} from 'antd' import {LocaleProvider} from 'antd'

@ -9,6 +9,7 @@ export function markdownToHTML(oldContent, selector) {
window.$('#md_div').html('') window.$('#md_div').html('')
// markdown to html // markdown to html
if (selector && oldContent && oldContent.startsWith('<p')) { // 普通html处理 if (selector && oldContent && oldContent.startsWith('<p')) { // 普通html处理
window.$('#' + selector).addClass('renderAsHtml')
window.$('#' + selector).html(oldContent) window.$('#' + selector).html(oldContent)
} else { } else {
try { try {

@ -1,4 +1,5 @@
import React,{ Component } from "react"; import React,{ Component } from "react";
import { ConditionToolTip } from 'educoder'
class AttachmentsList extends Component{ class AttachmentsList extends Component{
constructor(props){ constructor(props){
@ -12,14 +13,18 @@ class AttachmentsList extends Component{
attachments.map((item,key)=>{ attachments.map((item,key)=>{
return( return(
<p key={key}> <p key={key}>
<a className="color-grey"> <a className="color-grey fl">
<i className="font-14 color-green iconfont icon-fujian mr8"></i> <i className="font-14 color-green iconfont icon-fujian mr8"></i>
</a> </a>
{ {
item.is_pdf && item.is_pdf == true ? item.is_pdf && item.is_pdf == true ?
<a href={item.url} className="mr12" length="58" target="_blank">{item.title}</a> <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>
: :
<a href={item.url} className="mr12" length="58">{item.title}</a> <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>
} }
<span className="color-grey mt2 color-grey-6 font-12">{item.filesize}</span> <span className="color-grey mt2 color-grey-6 font-12">{item.filesize}</span>
</p> </p>

@ -129,12 +129,16 @@ class Fileslistitem extends Component{
.catch(function (error) { .catch(function (error) {
console.log(error); console.log(error);
}); });
} }
eventStop = (event) =>{
event.stopPropagation()
}
render(){ render(){
const { checkBox, const { checkBox,
discussMessage, discussMessage,index
} = this.props; } = this.props;
return( return(
@ -190,9 +194,9 @@ class Fileslistitem extends Component{
white-space:nowrap white-space:nowrap
} }
`}</style> `}</style>
<div className="clearfix ds pr contentSection"> <div className="clearfix ds pr contentSection" style={{cursor : this.props.isAdmin ? "pointer" : "default"}} onClick={() => window.$(`.sourceitem${index} input`).click() }>
<h6> <h6 onClick={(event)=>this.eventStop(event)}>
<span className="fl mr12 mt3"> <span className={`sourceitem${index} fl mr12 mt3`}>
{checkBox} {checkBox}
</span> </span>
{ {
@ -283,16 +287,15 @@ class Fileslistitem extends Component{
</span> </span>
</span> </span>
{this.props.isAdmin? {this.props.isAdmin?
<span className={"fr mrf2 mr10"}> <span className={"fr mrf2 mr10"} onClick={(event)=>this.eventStop(event)}>
<WordsBtn style="blue" className="colorblue font-16 mr20 fr"> <WordsBtn style="blue" className="colorblue font-16 mr20 fr">
<a className="btn colorblue" <a className="btn colorblue"
onClick={()=>this.settingList()}>设置</a> onClick={()=>this.settingList()}>设置</a>
</WordsBtn> </WordsBtn>
</span>:""} </span>:""}
{this.props.isStudent===true&&this.props.current_user.login===discussMessage.author.login? {this.props.isStudent===true&&this.props.current_user.login===discussMessage.author.login?
<span className={"fr mrf2 mr10"}> <span className={"fr mrf2 mr10"} onClick={(event)=>this.eventStop(event)}>
<WordsBtn style="blue" className="colorblue font-16 mr20 fr"> <WordsBtn style="blue" className="colorblue font-16 mr20 fr">
<a className="btn colorblue" <a className="btn colorblue"

@ -918,7 +918,8 @@ class Fileslists extends Component{
checkBox={this.props.isAdmin()?<Checkbox value={item.id} key={item.id}></Checkbox>:""} checkBox={this.props.isAdmin()?<Checkbox value={item.id} key={item.id}></Checkbox>:""}
Settingtypes={(id)=>this.Settingtypes(id)} Settingtypes={(id)=>this.Settingtypes(id)}
coursesId={this.props.match.params.coursesId} coursesId={this.props.match.params.coursesId}
updatafiledfun={()=>this.updatafiled()} updatafiledfun={()=>this.updatafiled()}
index={index}
></Fileslistitem> ></Fileslistitem>
</div> </div>
</div> </div>

@ -337,6 +337,17 @@ class BoardsNew extends Component{
<span style={{ "padding-left": 0, "padding-right": 0 }}></span> <span style={{ "padding-left": 0, "padding-right": 0 }}></span>
</React.Fragment> </React.Fragment>
} }
<style>
{
`
.yslboardsnewinputaddonAfter .ant-input{
border-right: none !important;
height: 40px !important;
}
`
}
</style>
<Form.Item <Form.Item
label="标题" label="标题"
className="topicTitle " className="topicTitle "
@ -349,8 +360,8 @@ class BoardsNew extends Component{
max: MAX_TITLE_LENGTH, message: `最大限制为${MAX_TITLE_LENGTH}个字符`, max: MAX_TITLE_LENGTH, message: `最大限制为${MAX_TITLE_LENGTH}个字符`,
}], }],
})( })(
<Input placeholder={`请输入帖子标题,最大限制${MAX_TITLE_LENGTH}个字符 `}className="searchViewAfter" maxLength={MAX_TITLE_LENGTH} <Input placeholder={`请输入帖子标题,最大限制${MAX_TITLE_LENGTH}个字符 `}className="searchViewAfter yslboardsnewinputaddonAfter" maxLength={MAX_TITLE_LENGTH}
onInput={this.changeTitle} suffix={`${title_num}/${MAX_TITLE_LENGTH}`} /> onInput={this.changeTitle} addonAfter={`${title_num}/${MAX_TITLE_LENGTH}`} />
)} )}
</Form.Item> </Form.Item>
@ -365,10 +376,15 @@ class BoardsNew extends Component{
dropdownRender={menu => ( dropdownRender={menu => (
<div> <div>
{menu} {menu}
<Divider style={{ margin: '4px 0' }} /> {
<div style={{ padding: '8px', cursor: 'pointer' }} onMouseDown={() => this.refs['addDirModal'].open()}> isAdmin &&
<Icon type="plus" /> 添加目录 <React.Fragment>
</div> <Divider style={{ margin: '4px 0' }} />
<div style={{ padding: '8px', cursor: 'pointer' }} onMouseDown={() => this.refs['addDirModal'].open()}>
<Icon type="plus" /> 添加目录
</div>
</React.Fragment>
}
</div> </div>
)} )}
> >

@ -24,7 +24,7 @@ import '../../forums/RightSection.css'
import './TopicDetail.css' import './TopicDetail.css'
import '../common/courseMessage.css' import '../common/courseMessage.css'
import { Pagination, Tooltip } from 'antd' import { Pagination, Tooltip } from 'antd'
import { bytesToSize, ConditionToolTip, markdownToHTML, MarkdownToHtml } from 'educoder' import { bytesToSize, ConditionToolTip, markdownToHTML, MarkdownToHtml , setImagesUrl } from 'educoder'
import SendToCourseModal from '../coursesPublic/modal/SendToCourseModal' import SendToCourseModal from '../coursesPublic/modal/SendToCourseModal'
import CBreadcrumb from '../common/CBreadcrumb' import CBreadcrumb from '../common/CBreadcrumb'
import { generateComments, generateChildComments, _findById, handleContentBeforeCreateNew, addNewComment import { generateComments, generateChildComments, _findById, handleContentBeforeCreateNew, addNewComment
@ -57,6 +57,7 @@ class TopicDetail extends Component {
pageCount: 1, pageCount: 1,
comments: [], comments: [],
goldRewardDialogOpen: false, goldRewardDialogOpen: false,
author:undefined
} }
} }
componentDidMount() { componentDidMount() {
@ -85,7 +86,8 @@ class TopicDetail extends Component {
memo: Object.assign({}, { memo: Object.assign({}, {
...response.data.data, ...response.data.data,
replies_count: response.data.data.total_replies_count replies_count: response.data.data.total_replies_count
}, {...this.state.memo}) }, {...this.state.memo}),
author:response.data.data.author
}, () => { }, () => {
}) })
@ -514,7 +516,7 @@ class TopicDetail extends Component {
render() { render() {
const { match, history } = this.props const { match, history } = this.props
const { recommend_shixun, current_user,author_info } = this.props; const { recommend_shixun, current_user,author_info } = this.props;
const { memo, comments, hasMoreComments, goldRewardDialogOpen, pageCount, total_count } = this.state; const { memo, comments, hasMoreComments, goldRewardDialogOpen, pageCount, total_count , author } = this.state;
const messageId = match.params.topicId const messageId = match.params.topicId
if (this.state.memoLoading || !current_user) { if (this.state.memoLoading || !current_user) {
return <div className="edu-back-white" id="forum_index_list"></div> return <div className="edu-back-white" id="forum_index_list"></div>
@ -599,51 +601,54 @@ class TopicDetail extends Component {
} }
</div> </div>
<div className="color-grey-9 clearfix"> <div className="df mt20">
<span className="fl" style={{marginTop: "2px"}}>{moment(memo.created_on).fromNow()} 发布</span> <img src={setImagesUrl(`/images/${author && author.image_url}`)} className="radius mr10 mt2" width="40px" height="40px"/>
<div className="fr"> <div className="flex1">
<div className="color-grey-9 lineh-20">
</div> <span class="color-grey-3 mr20 fl" style={{"fontWeight":"400"}}>{author && author.name}</span>
</div> <span className="fl">{moment(memo.created_on).fromNow()} 发布</span>
</div>
<div className="color-grey-9 clearfix">
<span className="fl" style={{marginTop: '4px'}}> <div className="color-grey-9 clearfix">
{/* { current_user.admin && <Tooltip title={ "" }> <span className="fl" style={{marginTop: '4px'}}>
<span className="noteDetailNum rightline cdefault" style={{padding: '0 4px', cursor: 'pointer'}}> {/* { current_user.admin && <Tooltip title={ "" }>
<i className="iconfont icon-jiangli mr5" onClick={this.showRewardDialog}></i> <span className="noteDetailNum rightline cdefault" style={{padding: '0 4px', cursor: 'pointer'}}>
</span> <i className="iconfont icon-jiangli mr5" onClick={this.showRewardDialog}></i>
</Tooltip> } */}
<Tooltip title={"浏览数"}>
<span className={`noteDetailNum `} style={{paddingLeft: '0px'}}>
<i className="iconfont icon-liulanyan mr5"></i>
<span style={{ top: "1px", position: "relative" }}>{memo.visits || '1'}</span>
</span>
</Tooltip>
{ !!memo.total_replies_count &&
<Tooltip title={"回复数"}>
<a href="javascript:void(0)" className="noteDetailNum">
<i className="iconfont icon-huifu1 mr5" onClick={this.showCommentInput}></i>
<span style={{ top: "2px", position: "relative" }}>{ memo.total_replies_count }</span>
</a>
</Tooltip>
}
{!!memo.praises_count &&
<Tooltip title={"点赞数"}>
<span className={`noteDetailNum `} style={{}}>
<i className="iconfont icon-dianzan-xian mr5"></i>
<span style={{ top: "2px", position: "relative" }}>{ memo.praises_count }</span>
</span> </span>
</Tooltip> </Tooltip> } */}
<Tooltip title={"浏览数"}>
<span className={`noteDetailNum `} style={{paddingLeft: '0px'}}>
<i className="iconfont icon-liulanyan mr5"></i>
<span style={{ top: "1px", position: "relative" }}>{memo.visits || '1'}</span>
</span>
</Tooltip>
{ !!memo.total_replies_count &&
<Tooltip title={"回复数"}>
<a href="javascript:void(0)" className="noteDetailNum">
<i className="iconfont icon-huifu1 mr5" onClick={this.showCommentInput}></i>
<span style={{ top: "2px", position: "relative" }}>{ memo.total_replies_count }</span>
</a>
</Tooltip>
} }
</span> {!!memo.total_praises_count &&
<div className="fr"> <Tooltip title={"点赞数"}>
{/* || current_user.user_id === author_info.user_id */} <span className={`noteDetailNum `} style={{}}>
<a className={`task-hide fr return_btn color-grey-6 ${ current_user && (isAdmin <i className="iconfont icon-dianzan-xian mr5"></i>
) ? '': 'no_mr'} `} onClick={() => this.props.toListPage(Object.assign({}, this.props.match.params, {'coursesId': this.state.memo.course_id})) } > <span style={{ top: "2px", position: "relative" }}>{ memo.total_praises_count }</span>
返回 </span>
</a> </Tooltip>
</div> }
</span>
<div className="fr">
{/* || current_user.user_id === author_info.user_id */}
<a className={`task-hide fr return_btn color-grey-6 ${ current_user && (isAdmin
) ? '': 'no_mr'} `} onClick={() => this.props.toListPage(Object.assign({}, this.props.match.params, {'coursesId': this.state.memo.course_id})) } >
返回
</a>
</div>
</div>
</div> </div>
</div>
</div> </div>

@ -15,7 +15,7 @@ import WorkDetailPageHeader from './common/WorkDetailPageHeader'
import CommonWorkAppraiseReply from './reply/CommonWorkAppraiseReply' import CommonWorkAppraiseReply from './reply/CommonWorkAppraiseReply'
import Example from './TestHooks' import Example from './TestHooks'
import CommonWorkAppraiseReviseAttachments from './CommonWorkAppraiseReviseAttachments' import CommonWorkAppraiseReviseAttachments from './CommonWorkAppraiseReviseAttachments'
import LeaderIcon from './common/LeaderIcon'
const { Option} = Select; const { Option} = Select;
const CheckboxGroup = Checkbox.Group; const CheckboxGroup = Checkbox.Group;
const confirm = Modal.confirm; const confirm = Modal.confirm;
@ -88,6 +88,14 @@ class CommonWorkAppraise extends Component{
console.log(error) console.log(error)
}) })
} }
componentDidUpdate(prevProps, prevState) {
if (this.props.match.params.studentWorkId != prevProps.match.params.studentWorkId) {
this.getWork();
this.getReviseAttachments()
this.commonWorkAppraiseReply && this.commonWorkAppraiseReply.fetchAllComments()
}
}
componentDidMount() { componentDidMount() {
this.getWork(); this.getWork();
this.getReviseAttachments() this.getReviseAttachments()
@ -156,12 +164,13 @@ class CommonWorkAppraise extends Component{
attachments, homework_id, project_info, work_members, is_evaluation, attachments, homework_id, project_info, work_members, is_evaluation,
description, update_user_name, update_time, commit_time, author_name, description, update_user_name, update_time, commit_time, author_name,
revise_attachments, revise_reason, atta_update_user, atta_update_time, atta_update_user_login, revise_attachments, revise_reason, atta_update_user, atta_update_time, atta_update_user_login,
Modalstype,Modalstopval,ModalCancel,ModalSave,loadtype Modalstype,Modalstopval,ModalCancel,ModalSave,loadtype, is_leader_work
} =this.state; } =this.state;
let courseId=this.props.match.params.coursesId; let courseId=this.props.match.params.coursesId;
let category_id=this.props.match.params.category_id; let category_id=this.props.match.params.category_id;
let studentWorkId=this.props.match.params.studentWorkId; let studentWorkId=this.props.match.params.studentWorkId;
const isAdmin = this.props.isAdmin()
return( return(
<WorkDetailPageHeader <WorkDetailPageHeader
{...this.props} {...this.state} {...this.props} {...this.state}
@ -251,12 +260,27 @@ class CommonWorkAppraise extends Component{
{is_evaluation != true && work_members && !!work_members.length && <div className={"stud-class-set bor-top-greyE edu-back-white padding20-30"}> {is_evaluation != true && work_members && !!work_members.length && <div className={"stud-class-set bor-top-greyE edu-back-white padding20-30"}>
<div className={"color-grey-6 mb10"}> <div className={"color-grey-6 mb10"}>
其他组员 全部组员
</div> </div>
<div className={"ml20"}> <div className={"ml20 color-grey-6"}>
{work_members.map((item, index) => { <div className="">
return item.user_name + ' ' 当前组员{author_name} {is_leader_work && <LeaderIcon small={true} ></LeaderIcon>}
})} </div>
<div>
其他组员
{work_members.map((item, index) => {
return <React.Fragment>
{isAdmin ?
<a className={`color-blue ${index == 0 ? '' : 'ml10'}`} href="javascript:void(0)"
onClick={() => this.props.toWorkDetailPage(this.props.match.params, null, item.work_id)}
>
{item.user_name}
</a> : <span className={`${index == 0 ? '' : 'ml10'}`} >{item.user_name}</span>}
{item.is_leader && <LeaderIcon small={true} ></LeaderIcon>}
</React.Fragment>
})}
</div>
</div> </div>
</div> </div>
} }
@ -266,6 +290,7 @@ class CommonWorkAppraise extends Component{
{/* task_type={datalist&&datalist.task_type} */} {/* task_type={datalist&&datalist.task_type} */}
<CommonWorkAppraiseReply {...this.props} task_id={studentWorkId} <CommonWorkAppraiseReply {...this.props} task_id={studentWorkId}
onReplySuccess={this.onReplySuccess} {...this.state} onReplySuccess={this.onReplySuccess} {...this.state}
wrappedComponentRef={(ref) => {this.commonWorkAppraiseReply = ref}}
></CommonWorkAppraiseReply> ></CommonWorkAppraiseReply>
</div> </div>

@ -15,7 +15,7 @@ import WorkDetailPageHeader from './common/WorkDetailPageHeader'
import PublishRightnow from './PublishRightnow' import PublishRightnow from './PublishRightnow'
import ModulationModal from "../coursesPublic/ModulationModal"; import ModulationModal from "../coursesPublic/ModulationModal";
import AccessoryModal from "../coursesPublic/AccessoryModal"; import AccessoryModal from "../coursesPublic/AccessoryModal";
import LeaderIcon from './common/LeaderIcon'
const { Option} = Select; const { Option} = Select;
const CheckboxGroup = Checkbox.Group; const CheckboxGroup = Checkbox.Group;
const confirm = Modal.confirm; const confirm = Modal.confirm;
@ -97,7 +97,12 @@ function buildColumns(that, student_works, studentData) {
}} title={text && text.length > 5 ? text : ''}> }} title={text && text.length > 5 ? text : ''}>
{/* <Tooltip placement="bottom" title={text}> {/* <Tooltip placement="bottom" title={text}>
</Tooltip> */} </Tooltip> */}
{text} {record.is_leader ?
<div style={{ display: 'flex', 'flex-direction': 'column', 'align-items': 'center'}}>
<div >{text}</div>
<LeaderIcon></LeaderIcon>
</div>
: <React.Fragment>{text}</React.Fragment>}
</div> </div>
), ),
}] }]

@ -389,6 +389,17 @@ class NewWork extends Component{
</p> </p>
<div> <div>
{/* onSubmit={this.handleSubmit} */} {/* onSubmit={this.handleSubmit} */}
<style>
{
`
.yslnewworkinputaddonAfter .ant-input{
border-right: none !important;
height: 40px !important;
}
`
}
</style>
<Form className="courseForm"> <Form className="courseForm">
<Form.Item <Form.Item
label="标题" label="标题"
@ -399,7 +410,7 @@ class NewWork extends Component{
required: true, message: '请输入标题' required: true, message: '请输入标题'
}], }],
})( })(
<Input placeholder="请输入作业标题最大限制60个字符" onInput={this.changeTitle} className="searchView searchViewAfter" style={{"width":"100%"}} maxLength={MAX_TITLE_LENGTH} suffix={`${String(title_num)}/${MAX_TITLE_LENGTH}`}/> <Input placeholder="请输入作业标题最大限制60个字符" onInput={this.changeTitle} className="searchView yslnewworkinputaddonAfter searchViewAfter" style={{"width":"100%"}} maxLength={MAX_TITLE_LENGTH} addonAfter={`${String(title_num)}/${MAX_TITLE_LENGTH}`}/>
)} )}
</Form.Item> </Form.Item>
<style>{` <style>{`

@ -0,0 +1,19 @@
import React,{Component} from "React";
export default function LeaderIcon(props = {}) {
let icon = null;
if (props.small) {
icon = <div className="font-8 blueFull Actionbtn" style={{
height: '14px',
'line-height': '14px',
width: '24px',
padding: 0,
'margin-top': '-2px',
'margin-left': '2px',
'vertical-align': 'middle', }}>组长</div>
} else {
icon = <div className="font-8 blueFull Actionbtn" style={{ height: '16px', 'line-height': '16px', width: '30px'}}>组长</div>
}
return icon
}

@ -85,8 +85,7 @@ class WorkDetailPageHeader extends Component{
background: #fff; background: #fff;
} }
.workDetailPageHeader .summaryname { .workDetailPageHeader .summaryname {
line-height: 20px; line-height:30px
margin-top: 13px;
} }
`}</style> `}</style>
<CBreadcrumb items={[ <CBreadcrumb items={[
@ -99,18 +98,18 @@ class WorkDetailPageHeader extends Component{
// { name: childModuleName } // { name: childModuleName }
]}></CBreadcrumb> ]}></CBreadcrumb>
<div style={{ width:'100%',height:'52px'}} > <div className="clearfix mt20 mb20" >
<span className=" fl color-black summaryname" style={{height: 'auto'}}> <span className=" fl color-black summaryname">
{homework_name} {homework_name}
{/* <Link to={"/courses/"+courseId+"/graduation"+"/graduation_tasks/"}>{homework_name}</Link> */} {/* <Link to={"/courses/"+courseId+"/graduation"+"/graduation_tasks/"}>{homework_name}</Link> */}
</span> </span>
<CoursesListType <CoursesListType
typelist={homework_status} typelist={homework_status}
typesylename={"mt12"} typesylename={"mt3"}
/> />
{category && <a className="color-grey-6 fr font-16 ml30 mt7 mr20" onClick={this.goback} style={{ marginRight: '26px'}}>返回</a>} {category && <a className="color-grey-6 fr font-16 ml30 mr30 lineh-25" onClick={this.goback}>返回</a>}
{this.props.update_atta && {this.props.update_atta &&
<React.Fragment> <React.Fragment>

@ -143,7 +143,9 @@ class commonWork extends Component{
this.setState({ this.setState({
order:e.key==="all"?"":e.key, order:e.key==="all"?"":e.key,
page:1, page:1,
isSpin:true isSpin:true,
checkBoxValues:[],
checkAll:false
}) })
let {search}=this.state; let {search}=this.state;
this.getList(1,search,e.key==="all"?"":e.key); this.getList(1,search,e.key==="all"?"":e.key);

@ -1,5 +1,5 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import {getImageUrl} from 'educoder'; import { getImageUrl , getUrl } from 'educoder';
class NoneData extends Component{ class NoneData extends Component{
constructor(props) { constructor(props) {
@ -9,7 +9,20 @@ class NoneData extends Component{
const { style } = this.props; const { style } = this.props;
return( return(
<div className="edu-tab-con-box clearfix edu-txt-center" style={style}> <div className="edu-tab-con-box clearfix edu-txt-center" style={style}>
<img className="edu-nodata-img mb20" src={getImageUrl("images/educoder/nodata.png")}/> <style>
{`
.edu-tab-con-box{
padding:100px 0px;
}
.ant-modal-body .edu-tab-con-box{
padding:0px!important;
}
img.edu-nodata-img{
margin: 40px auto 20px;
}
`}
</style>
<img className="edu-nodata-img mb20" src={getUrl("/images/educoder/nodata.png")}/>
<p className="edu-nodata-p mb20">暂时还没有相关数据哦</p> <p className="edu-nodata-p mb20">暂时还没有相关数据哦</p>
</div> </div>
) )

@ -1,209 +1,209 @@
import React, { Component } from "react"; import React, { Component } from "react";
import { Modal, Checkbox, Input, Spin} from "antd"; import { Modal, Checkbox, Input, Spin} from "antd";
import axios from 'axios' import axios from 'axios'
import ModalWrapper from "../../common/ModalWrapper" import ModalWrapper from "../../common/ModalWrapper"
import InfiniteScroll from 'react-infinite-scroller'; import InfiniteScroll from 'react-infinite-scroller';
const Search = Input.Search const Search = Input.Search
const pageCount = 15; const pageCount = 15;
class SendToCourseModal extends Component{ class SendToCourseModal extends Component{
constructor(props){ constructor(props){
super(props); super(props);
this.state={ this.state={
checkBoxValues: [], checkBoxValues: [],
course_lists: [], course_lists: [],
course_lists_after_filter: [], course_lists_after_filter: [],
searchValue: '', searchValue: '',
hasMore: true, hasMore: true,
loading: false, loading: false,
page: 1 page: 1
} }
} }
fetchCourseList = (arg_page) => { fetchCourseList = (arg_page) => {
const page = arg_page || this.state.page; const page = arg_page || this.state.page;
// search=''& // search=''&
let url = `/courses/mine.json?page=${page}&page_size=${pageCount}` let url = `/courses/mine.json?page=${page}&page_size=${pageCount}`
const searchValue = this.state.searchValue.trim() const searchValue = this.state.searchValue.trim()
if (searchValue) { if (searchValue) {
url += `&search=${searchValue}` url += `&search=${searchValue}`
} }
this.setState({ loading: true }) this.setState({ loading: true })
axios.get(url, { axios.get(url, {
}) })
.then((response) => { .then((response) => {
if (!response.data.data || response.data.data.length == 0) { if (!response.data.data || response.data.data.length == 0) {
this.setState({ this.setState({
course_lists: page == 1 ? [] : this.state.course_lists, course_lists: page == 1 ? [] : this.state.course_lists,
page, page,
loading: false, loading: false,
hasMore: false, hasMore: false,
}) })
} else { } else {
this.setState({ this.setState({
course_lists: page == 1 ? response.data.data : this.state.course_lists.concat(response.data.data), course_lists: page == 1 ? response.data.data : this.state.course_lists.concat(response.data.data),
course_lists_after_filter: response.data.data, course_lists_after_filter: response.data.data,
page, page,
loading: false, loading: false,
hasMore: response.data.data.length == pageCount hasMore: response.data.data.length == pageCount
}) })
} }
}) })
.catch(function (error) { .catch(function (error) {
console.log(error); console.log(error);
}); });
} }
componentDidMount() { componentDidMount() {
setTimeout(() => { setTimeout(() => {
this.fetchCourseList() this.fetchCourseList()
}, 500) }, 500)
} }
setVisible = (visible) => { setVisible = (visible) => {
this.refs.modalWrapper.setVisible(visible) this.refs.modalWrapper.setVisible(visible)
if (visible == false) { if (visible == false) {
this.setState({ this.setState({
checkBoxValues: [] checkBoxValues: []
}) })
} }
} }
onSendOk = () => { onSendOk = () => {
if (!this.state.checkBoxValues || this.state.checkBoxValues.length == 0) { if (!this.state.checkBoxValues || this.state.checkBoxValues.length == 0) {
this.props.showNotification('请先选择要发送至的课堂') this.props.showNotification('请先选择要发送至的课堂')
return; return;
} }
if(this.props.url==="/files/bulk_send.json"){ if(this.props.url==="/files/bulk_send.json"){
axios.post("/files/bulk_send.json", { axios.post("/files/bulk_send.json", {
course_id:this.props.match.params.coursesId, course_id:this.props.match.params.coursesId,
ids: this.props.selectedMessageIds, ids: this.props.selectedMessageIds,
to_course_ids: this.state.checkBoxValues to_course_ids: this.state.checkBoxValues
}) })
.then((response) => { .then((response) => {
if (response.data.status == 0) { if (response.data.status == 0) {
this.setVisible(false) this.setVisible(false)
this.props.gobackonSend(response.data.message) this.props.gobackonSend(response.data.message)
} }
}) })
.catch(function (error) { .catch(function (error) {
console.log(error); console.log(error);
}); });
}else{ }else{
const bid = this.props.match.params.boardId const bid = this.props.match.params.boardId
const url = `/boards/${bid}/messages/bulk_send.json` const url = `/boards/${bid}/messages/bulk_send.json`
axios.post(url, { axios.post(url, {
ids: this.props.selectedMessageIds, ids: this.props.selectedMessageIds,
to_course_ids: this.state.checkBoxValues to_course_ids: this.state.checkBoxValues
}) })
.then((response) => { .then((response) => {
if (response.data.status == 0) { if (response.data.status == 0) {
this.setVisible(false) this.setVisible(false)
this.props.showNotification('发送成功') this.props.showNotification('发送成功')
} }
}) })
.catch(function (error) { .catch(function (error) {
console.log(error); console.log(error);
}); });
} }
} }
onOk = () => { onOk = () => {
const { course_lists, checkBoxValues } = this.state const { course_lists, checkBoxValues } = this.state
this.onSendOk() this.onSendOk()
// this.props.onOk && this.props.onOk(checkBoxValues) // this.props.onOk && this.props.onOk(checkBoxValues)
// this.refs.modalWrapper.setVisible(false) // this.refs.modalWrapper.setVisible(false)
} }
onCheckBoxChange = (checkBoxValues) => { onCheckBoxChange = (checkBoxValues) => {
this.setState({ this.setState({
checkBoxValues: checkBoxValues checkBoxValues: checkBoxValues
}) })
} }
onSearchChange = (e) => { onSearchChange = (e) => {
this.setState({ this.setState({
searchValue: e.target.value searchValue: e.target.value
}) })
} }
handleInfiniteOnLoad = () => { handleInfiniteOnLoad = () => {
console.log('loadmore...') console.log('loadmore...')
this.fetchCourseList(this.state.page + 1) this.fetchCourseList(this.state.page + 1)
} }
onSearch = () => { onSearch = () => {
// const course_lists_after_filter = this.state.course_lists.filter( item => item.name.indexOf(this.state.searchValue) != -1 ) // const course_lists_after_filter = this.state.course_lists.filter( item => item.name.indexOf(this.state.searchValue) != -1 )
// this.setState({ course_lists_after_filter }) // this.setState({ course_lists_after_filter })
this.fetchCourseList(1) this.fetchCourseList(1)
} }
render(){ render(){
const { course_lists, checkBoxValues, searchValue, loading, hasMore } = this.state const { course_lists, checkBoxValues, searchValue, loading, hasMore } = this.state
const { moduleName } = this.props const { moduleName } = this.props
return( return(
<ModalWrapper <ModalWrapper
ref="modalWrapper" ref="modalWrapper"
title={`发送${moduleName}`} title={`发送${moduleName}`}
{...this.props } {...this.props }
onOk={this.onOk} onOk={this.onOk}
> >
<style> <style>
{` {`
.demo-loading-container { .demo-loading-container {
position: absolute; position: absolute;
bottom: 93px; bottom: 93px;
width: 82%; width: 82%;
text-align: center; text-align: center;
}`} }`}
</style> </style>
<p className="color-grey-6 mb20 edu-txt-center" style={{ fontWeight: "bold" }} >选择的{moduleName}发送到<span className="color-orange-tip">指定课堂</span></p> <p className="color-grey-6 mb20 edu-txt-center" style={{ fontWeight: "bold" }} >选择的{moduleName}发送到<span className="color-orange-tip">指定课堂</span></p>
<Search <Search
className="mb14" className="mb14"
value={searchValue} value={searchValue}
placeholder="请输入课堂名称进行搜索" placeholder="请输入课堂名称进行搜索"
onChange={this.onSearchChange} onChange={this.onSearchChange}
onSearch={this.onSearch} onSearch={this.onSearch}
></Search> ></Search>
<div> <div>
{/* https://github.com/CassetteRocks/react-infinite-scroller/issues/70 */} {/* https://github.com/CassetteRocks/react-infinite-scroller/issues/70 */}
<div className="edu-back-skyblue padding15" style={{"height":"300px", overflowY: "scroll", overflowAnchor: 'none' }}> <div className="edu-back-skyblue padding15" style={{"height":"300px", overflowY: "scroll", overflowAnchor: 'none' }}>
<InfiniteScroll <InfiniteScroll
threshold={10} threshold={10}
initialLoad={false} initialLoad={false}
pageStart={0} pageStart={0}
loadMore={this.handleInfiniteOnLoad} loadMore={this.handleInfiniteOnLoad}
hasMore={!loading && hasMore} hasMore={!loading && hasMore}
useWindow={false} useWindow={false}
> >
<Checkbox.Group style={{ width: '100%' }} onChange={this.onCheckBoxChange} value={checkBoxValues}> <Checkbox.Group style={{ width: '100%' }} onChange={this.onCheckBoxChange} value={checkBoxValues}>
{ course_lists && course_lists.map( course => { { course_lists && course_lists.map( course => {
return ( return (
<p className="clearfix mb7" key={course.id}> <p className="clearfix mb7" key={course.id}>
<Checkbox className="fl" value={course.id} key={course.id}></Checkbox> <Checkbox className="fl" value={course.id} key={course.id}></Checkbox>
<span className="fl with45"><label className="task-hide fl" style={{"maxWidth":"208px;"}}>{course.name}</label></span> <span className="fl with45"><label className="task-hide fl" style={{"maxWidth":"208px;"}}>{course.name}</label></span>
</p> </p>
) )
}) } }) }
</Checkbox.Group> </Checkbox.Group>
{loading && hasMore && ( {loading && hasMore && (
<div className="demo-loading-container"> <div className="demo-loading-container">
<Spin /> <Spin />
</div> </div>
)} )}
{/* TODO */} {/* TODO */}
{/* { {/* {
!hasMore && <div>没有更多了</div> !hasMore && <div>没有更多了</div>
} */} } */}
</InfiniteScroll> </InfiniteScroll>
</div> </div>
</div> </div>
</ModalWrapper> </ModalWrapper>
) )
} }
} }
export default SendToCourseModal; export default SendToCourseModal;

@ -1,80 +1,80 @@
.studentList_operation_ul{ .studentList_operation_ul{
color: #999; color: #999;
font-size: 12px; font-size: 12px;
float: right; float: right;
margin-top: 2px; margin-top: 2px;
} }
.studentList_operation_ul li{ .studentList_operation_ul li{
float: left; float: left;
padding:0px 20px; padding:0px 20px;
position: relative; position: relative;
cursor: pointer; cursor: pointer;
flex: 0 0 26px; flex: 0 0 26px;
line-height: 26px; line-height: 26px;
} }
.studentList_operation_ul li.li_line:after{ .studentList_operation_ul li.li_line:after{
position: absolute; position: absolute;
content: ''; content: '';
width: 1px; width: 1px;
height: 12px; height: 12px;
background-color: #EDEDED; background-color: #EDEDED;
right: 0px; right: 0px;
top:6px; top:6px;
} }
.studentList_operation_ul li:last-child{ .studentList_operation_ul li:last-child{
padding-right: 0px; padding-right: 0px;
} }
.studentList_operation_ul li:last-child:after{ .studentList_operation_ul li:last-child:after{
width: 0px; width: 0px;
} }
/* 基础的下拉列表、列如排序等 */ /* 基础的下拉列表、列如排序等 */
.drop_down_normal li{ .drop_down_normal li{
padding: 0px 20px; padding: 0px 20px;
height: 34px; height: 34px;
line-height: 34px; line-height: 34px;
min-width: 96px; min-width: 96px;
color: #333; color: #333;
font-size: 14px; font-size: 14px;
cursor: pointer; cursor: pointer;
width: 100%; width: 100%;
} }
.stu_table table{ .stu_table table{
line-height: 1.2; line-height: 1.2;
} }
.stu_table .classesName{ .stu_table .classesName{
display: block; display: block;
max-width: 428px; max-width: 428px;
} }
.stu_table .ant-table-thead > tr > th{ .stu_table .ant-table-thead > tr > th{
padding:21px 16px; padding:21px 16px;
border-bottom: none; border-bottom: none;
} }
.stu_table .ant-table-tbody tr:last-child td{ .stu_table .ant-table-tbody tr:last-child td{
border-bottom: none; border-bottom: none;
} }
.stu_table table .ant-table-tbody > tr:hover:not(.ant-table-expanded-row) > td{ .stu_table table .ant-table-tbody > tr:hover:not(.ant-table-expanded-row) > td{
background-color: #fff; background-color: #fff;
} }
.stu_head{ .stu_head{
padding-bottom: 15px; padding-bottom: 15px;
} }
.ant-modal-body{ .ant-modal-body{
padding:30px 40px; padding:30px 40px;
} }
.color-dark-21{ .color-dark-21{
color: #212121; color: #212121;
} }
.tabletd { .tabletd {
background-color:#E6F7FF; background-color:#E6F7FF;
} }
.yslminheigth{ .yslminheigth{
min-height: 20px; min-height: 20px;
} }
.yslminheigths{ .yslminheigths{
min-height: 21px; min-height: 21px;
} }

@ -572,7 +572,7 @@ class Exercise extends Component{
{...this.props} {...this.props}
{...this.state} {...this.state}
item={item} item={item}
key={key} index={key}
onItemClick={this.onItemClick} onItemClick={this.onItemClick}
checkBox={<Checkbox value={item.id} key={item.id} checkBox={<Checkbox value={item.id} key={item.id}
></Checkbox>} ></Checkbox>}

@ -52,17 +52,17 @@ class ExerciseListItem extends Component{
}) })
} }
render(){ render(){
let{item,checkBox}=this.props; let{item,checkBox,index}=this.props;
let {coursesId,Id}=this.props.match.params let {coursesId,Id}=this.props.match.params
const IsAdmin =this.props.isAdmin(); const IsAdmin =this.props.isAdmin();
const IsStudent =this.props.isStudent(); const IsStudent =this.props.isStudent();
// console.log(this.props.current_user.user_id) // console.log(this.props.current_user.user_id)
return( return(
<div className="workList_Item" style={{padding:"30px"}} onClick={() => this.props.onItemClick(this.props.item)}> <div className="workList_Item" style={{cursor : IsAdmin ? "pointer" : "default",padding:"30px" }} onClick={() => this.props.onItemClick(this.props.item)}>
{ {
IsAdmin && IsAdmin &&
<span className="fl mr12"> <span className={`exerciseitem${index} fl mr12`}>
{checkBox} {checkBox}
</span> </span>
} }
@ -96,20 +96,20 @@ class ExerciseListItem extends Component{
{/*<Link to={`/courses/${coursesId}/exercises/${item.id}/exercises/student_exercise_list?tab=0`} className="fl font-16 font-bd mt2 color-grey-3 task-hide" style={{"maxWidth":"600px"}}>{item.exercise_name}</Link>*/} {/*<Link to={`/courses/${coursesId}/exercises/${item.id}/exercises/student_exercise_list?tab=0`} className="fl font-16 font-bd mt2 color-grey-3 task-hide" style={{"maxWidth":"600px"}}>{item.exercise_name}</Link>*/}
{ {
this.props.isAdmin()? <a className="fl font-16 font-bd mt2 color-grey-3 task-hide comnonwidth580" this.props.isAdmin()? <Link className="fl font-16 font-bd mt2 color-grey-3 task-hide comnonwidth580"
title={item.exercise_name} title={item.exercise_name}
href={`/courses/${coursesId}/exercises/${item.id}/student_exercise_list?tab=0`}>{item.exercise_name}</a>:"" to={`/courses/${coursesId}/exercises/${item.id}/student_exercise_list?tab=0`}>{item.exercise_name}</Link>:""
} }
{ {
this.props.isStudent()? this.props.isStudent()?
<a className="fl font-16 font-bd mt2 color-grey-3 task-hide comnonwidth580" title={item.exercise_name} href={`/courses/${coursesId}/exercises/${item.id}/student_exercise_list?tab=0`}>{item.exercise_name}</a>:"" <Link className="fl font-16 font-bd mt2 color-grey-3 task-hide comnonwidth580" title={item.exercise_name} to={`/courses/${coursesId}/exercises/${item.id}/student_exercise_list?tab=0`}>{item.exercise_name}</Link>:""
} }
{ {
this.props.isNotMember()? item.lock_status === 0 ? this.props.isNotMember()? item.lock_status === 0 ?
<span className="fl mt3 font-16 font-bd color-dark comnonwidth580" title={item.exercise_name}>{item.exercise_name}</span> <span className="fl mt3 font-16 font-bd color-dark comnonwidth580" title={item.exercise_name}>{item.exercise_name}</span>
: <a className="fl font-16 font-bd mt2 color-grey-3 task-hide comnonwidth580" title={item.exercise_name} href={`/courses/${coursesId}/exercises/${item.id}/student_exercise_list?tab=0`}>{item.exercise_name}</a>:"" : <Link className="fl font-16 font-bd mt2 color-grey-3 task-hide comnonwidth580" title={item.exercise_name} to={`/courses/${coursesId}/exercises/${item.id}/student_exercise_list?tab=0`}>{item.exercise_name}</Link>:""
} }
{ {
@ -165,8 +165,8 @@ class ExerciseListItem extends Component{
{ IsAdmin &&<div className="homepagePostSetting" style={{"right":"-17px","top":"51px","display":"block","width":"100px"}}> { IsAdmin &&<div className="homepagePostSetting" style={{"right":"-17px","top":"51px","display":"block","width":"100px"}}>
<a className="btn colorblue font-16" href={`/courses/${coursesId}/exercises/${item.id}/edit`}>编辑</a> <Link className="btn colorblue font-16" to={`/courses/${coursesId}/exercises/${item.id}/edit`}>编辑</Link>
<a className="btn colorblue ml20 font-16" href={`/courses/${coursesId}/exercises/${item.id}/student_exercise_list?tab=3`}>设置</a> <Link className="btn colorblue ml20 font-16" to={`/courses/${coursesId}/exercises/${item.id}/student_exercise_list?tab=3`}>设置</Link>
</div> } </div> }
</p> </p>
@ -193,7 +193,7 @@ class ExerciseListItem extends Component{
<div className="homepagePostSetting" style={{"right":"0px","top":"62px","position":"absolute","display":"block"}}> <div className="homepagePostSetting" style={{"right":"0px","top":"62px","position":"absolute","display":"block"}}>
{item.current_status ===0&&item.exercise_status>1? <li> <Link className="btn colorblue font-16" to={`/courses/${coursesId}/exercises/${item.id}/users/${this.props.current_user.login}`}>继续答题</Link></li>: {item.current_status ===0&&item.exercise_status>1? <li> <Link className="btn colorblue font-16" to={`/courses/${coursesId}/exercises/${item.id}/users/${this.props.current_user.login}`}>继续答题</Link></li>:
item.current_status ===1&&item.exercise_status>1? <li> <Link className="btn colorblue font-16" to={`/courses/${coursesId}/exercises/${item.id}/users/${this.props.current_user.login}`}>查看答题</Link></li>: item.current_status ===1&&item.exercise_status>1? <li> <Link className="btn colorblue font-16" to={`/courses/${coursesId}/exercises/${item.id}/users/${this.props.current_user.login}`}>查看答题</Link></li>:
item.current_status ===2&&item.exercise_status>1? <li> <a className="btn colorblue ml20 font-16" onClick={()=>this.setgameexercise(`/courses/${coursesId}/exercises/${item.id}/users/${this.props.current_user.login}`)}>开始答题</a></li>:""} item.current_status ===2&&item.exercise_status>1? <li> <a className="btn colorblue ml20 font-16" onClick={()=>this.setgameexercise(`/courses/${coursesId}/exercises/${item.id}/users/${this.props.current_user.login}`)}>开始答题</a></li>:""}
</div> </div>
} }
</div> </div>

@ -481,8 +481,19 @@ class ExerciceNew extends Component{
max: 20, message: '最大限制为20个字符', max: 20, message: '最大限制为20个字符',
}], }],
})( */} })( */}
<Input placeholder={`请输入试卷标题,最大限制${TITLE_MAX_LENGTH}个字符`} maxLength={TITLE_MAX_LENGTH} className="mt5" value={exercise_name} <style>
onChange={this.exercise_name_change} suffix={`${exercise_name ? exercise_name.length : 0}/${TITLE_MAX_LENGTH}`} {
`
.exercicenewinputysl .ant-input{
border-right: none !important;
height: 40px !important;
}
`
}
</style>
<Input placeholder={`请输入试卷标题,最大限制${TITLE_MAX_LENGTH}个字符`} maxLength={TITLE_MAX_LENGTH} className="mt5 exercicenewinputysl" value={exercise_name}
onChange={this.exercise_name_change} addonAfter={`${exercise_name ? exercise_name.length : 0}/${TITLE_MAX_LENGTH}`}
/> />
{/* )} */} {/* )} */}
</Form.Item> </Form.Item>

@ -541,6 +541,18 @@ class ExerciseReviewAndAnswer extends Component{
.inputNumber30 .ant-input-number-input-wrap .ant-input-number-input{ .inputNumber30 .ant-input-number-input-wrap .ant-input-number-input{
height: 28px; height: 28px;
} }
.setRadioStyle{
width:100%;
cursor:pointer;
}
.setRadioStyle span:last-child{
flex:1;
display:flex;
}
.setRadioStyle .ant-radio,.setRadioStyle .ant-checkbox{
height:16px;
margin-top:2px;
}
`}</style> `}</style>
{/*<p style={{height:"60px"}}></p>*/} {/*<p style={{height:"60px"}}></p>*/}
<Modals <Modals

@ -44,19 +44,19 @@ class Multiple extends Component{
console.log(questionType); console.log(questionType);
return( return(
<div className="pl30 pr30 singleDisplay"> <div className="pl30 pr30 singleDisplay">
<Checkbox.Group disabled={ user_exercise_status == 1 ? true : false } onChange={this.saveId} value={questionType.user_answer}> <Checkbox.Group className="with100" disabled={ user_exercise_status == 1 ? true : false } onChange={this.saveId} value={questionType.user_answer}>
{ {
questionType.question_choices && questionType.question_choices.map((item,key)=>{ questionType.question_choices && questionType.question_choices.map((item,key)=>{
let prefix = `${tagArray[key]}.` let prefix = `${tagArray[key]}.`
return( return(
<p className="clearfix mb15 df"> <p className="clearfix mb15 df">
<Checkbox className="fl lineh-15 df mr8 mt2" value={item.choice_id} key={item.choice_id}>{prefix}</Checkbox> <Checkbox className="lineh-15 df mr8 setRadioStyle" value={item.choice_id}>
{/* <span class="fl lineh-20 mt1"></span> */} <span className="fl mr3 lineh-20">{prefix}</span>
{/* <span style={{display:"inline-block"}} className="markdown-body " dangerouslySetInnerHTML={{__html: markdownToHTML1(item.choice_text)}}></span> */} <MarkdownToHtml content={item.choice_text} selector={'multiple_' + (this.props.index + 1) + (key + 1)}
<MarkdownToHtml content={item.choice_text} selector={'multiple_' + (this.props.index + 1) + (key + 1)} className="flex1" style={{display:"inline-block"}}
className="" style={{display:"inline-block"}} ></MarkdownToHtml>
></MarkdownToHtml> </Checkbox>
</p> </p>
) )
}) })

@ -40,18 +40,18 @@ class single extends Component{
let isJudge = questionType.question_type == 2 let isJudge = questionType.question_type == 2
return( return(
<div className="pl30 pr30 singleDisplay"> <div className="pl30 pr30 singleDisplay">
<Radio.Group disabled={ user_exercise_status == 1 ? true : false } value={questionType.user_answer[0]} onChange={this.changeItem}> <Radio.Group className="with100" disabled={ user_exercise_status == 1 ? true : false } value={questionType.user_answer[0]} onChange={this.changeItem}>
{ {
questionType.question_choices && questionType.question_choices.map((item,key)=>{ questionType.question_choices && questionType.question_choices.map((item,key)=>{
let prefix = isJudge ? undefined : `${tagArray[key]}.` let prefix = isJudge ? undefined : `${tagArray[key]}.`
return( return(
<p className={parseInt(questionType.question_type) == 0 ? "clearfix mb15 df" : "fl mr40 df"}> <p className={parseInt(questionType.question_type) == 0 ? "clearfix mb15" : "fl mr40"}>
<Radio className="fl lineh-20" value={item.choice_id}>{prefix}</Radio> <Radio className="df lineh-20 setRadioStyle" value={item.choice_id}>
{/* <span className="fl lineh-20 mr3 "></span> */} <span className="fl mr3">{prefix}</span>
{/* <span style={{display:"inline-block", 'margin-top': '-1px'}} className="markdown-body fl " dangerouslySetInnerHTML={{__html: markdownToHTML1(item.choice_text)}}></span> */} <MarkdownToHtml content={item.choice_text} selector={'single_' + (this.props.index + 1) + (key + 1)}
<MarkdownToHtml content={item.choice_text} selector={'single_' + (this.props.index + 1) + (key + 1)} className="flex1" style={{display:"inline-block", 'margin-top': '-1px'}}
className="fl" style={{display:"inline-block", 'margin-top': '-1px'}} ></MarkdownToHtml>
></MarkdownToHtml> </Radio>
</p> </p>
) )
}) })

@ -218,11 +218,19 @@ class Bullsubdirectory extends Component{
<span className="yslduincolorred">*</span> <span className="yslduincolorred">*</span>
</div> </div>
<div className="yslduinleft"> <div className="yslduinleft">
<style>{
`
.ant-input{
border-right: none !important;
height: 40px !important;
}
`
}</style>
<Input placeholder="请在此输入标题最多60个字符" maxLength="60" <Input placeholder="请在此输入标题最多60个字符" maxLength="60"
style={{ textAlign: "left",width:"100%",}} style={{ textAlign: "left",width:"100%",}}
onInput={this.changeTopicName} onInput={this.changeTopicName}
autoComplete="off" autoComplete="off"
suffix={String(addonAfter)+"/60"} addonAfter={String(addonAfter)+"/60"}
value={eduintits} value={eduintits}
className="searchViewAfter"></Input> className="searchViewAfter"></Input>
</div> </div>

@ -287,11 +287,19 @@ class Eduinforms extends Component{
<span className="yslduincolorred">*</span> <span className="yslduincolorred">*</span>
</div> </div>
<div className="yslduinleft"> <div className="yslduinleft">
<style>{
`
.ant-input{
border-right: none !important;
height: 40px !important;
}
`
}</style>
<Input placeholder="请在此输入标题最多60个字符" maxLength={60} <Input placeholder="请在此输入标题最多60个字符" maxLength={60}
style={{ textAlign: "left",width:"100%",}} style={{ textAlign: "left",width:"100%",}}
onInput={this.changeTopicName} onInput={this.changeTopicName}
autoComplete="off" autoComplete="off"
suffix={String(addonAfter)+"/60"} addonAfter={String(addonAfter)+"/60"}
value={eduintits} value={eduintits}
className="searchViewAfter"></Input> className="searchViewAfter"></Input>
</div> </div>

@ -151,16 +151,12 @@ class GraduateTaskItem extends Component{
coursesId, coursesId,
categoryid, categoryid,
taskid, taskid,
index,
isAdmin
} = this.props; } = this.props;
// console.log(discussMessage)
return( return(
<div className="graduateTopicList boardsList"> <div className="graduateTopicList boardsList" style={{cursor : isAdmin ? "pointer" : "default" }} onClick={() => window.$(`.taskitem${index} input`).click() }>
<Modals <Modals
modalsType={Modalstype} modalsType={Modalstype}
modalsTopval={Modalstopval} modalsTopval={Modalstopval}
@ -193,8 +189,9 @@ class GraduateTaskItem extends Component{
margin-right: 15px; margin-right: 15px;
} }
`}</style> `}</style>
{ checkBox } <span className={`taskitem${index} fl`} style={{"height":"59px"}}>
{ checkBox }
</span>
{/* {/*
style={{borderTop:data===undefined?"":data.course_identity<4?'1px solid #EBEBEB':'1px solid transparent'}} style={{borderTop:data===undefined?"":data.course_identity<4?'1px solid #EBEBEB':'1px solid transparent'}}
*/} */}

@ -375,11 +375,21 @@ class GraduationTasksedit extends Component{
<input type="hidden" id='tasktypes' /> <input type="hidden" id='tasktypes' />
<span className={"newcoursestitle"}>选择确认后无法修改</span> <span className={"newcoursestitle"}>选择确认后无法修改</span>
</Form.Item> </Form.Item>
<style>
{
`
.yslgraduainputedit .ant-input{
border-right: none !important;
height: 40px !important;
}
`
}
</style>
<Form.Item label="任务标题" > <Form.Item label="任务标题" >
{getFieldDecorator('name', { {getFieldDecorator('name', {
rules: [{ required: true, message: "请输入标题" }], rules: [{ required: true, message: "请输入标题" }],
})(<Input placeholder="请输入任务名称最大限制60个字符" value={name} onInput={this.changeTitle} className="searchView searchViewAfter" style={{"width":"100%"}} maxLength="60" suffix={String(title_num)+"/60"}/>)} })(<Input placeholder="请输入任务名称最大限制60个字符" value={name} onInput={this.changeTitle} className="searchView searchViewAfter yslgraduainputedit" style={{"width":"100%"}} maxLength="60" addonAfter={String(title_num)+"/60"}/>)}
</Form.Item> </Form.Item>
<input type="hidden" id='nametypes' /> <input type="hidden" id='nametypes' />
</div> </div>

@ -377,15 +377,23 @@ class GraduationTasksnew extends Component {
margin-top: 0px; margin-top: 0px;
margin-bottom: 0px; margin-bottom: 0px;
} }
.yslgts .ant-input{
border-right: none !important;
height: 40px !important;
}
` `
} }
</style> </style>
<Form.Item label="任务标题" className={"taskname"} > <Form.Item label="任务标题" className={"taskname"} >
{getFieldDecorator('name', { {getFieldDecorator('name', {
rules: [{required: true, message: "不能为空"}], rules: [{required: true, message: "不能为空"}],
})(<Input placeholder="请输入任务名称最大限制60个字符" value={title_value} onInput={this.changeTitle} })(
className="searchView searchViewAfter h40" style={{"width": "100%"}} maxLength="60"
suffix={String(title_num)+"/60"}/>)} <Input placeholder="请输入任务名称最大限制60个字符" value={title_value} onInput={this.changeTitle}
className="searchView searchViewAfter h40 yslgts" style={{"width": "100%"}} maxLength="60"
addonAfter={String(title_num)+"/60"}/>
)}
</Form.Item> </Form.Item>
<input type="hidden" id='nametypes' /> <input type="hidden" id='nametypes' />
</div> </div>

@ -364,7 +364,7 @@ class GraduationTasks extends Component{
} }
PaginationTask=(page)=>{ PaginationTask=(page)=>{
let {search,order,selectpage,checkAllValue,checkBoxValues}=this.state; let {search,order,selectpage,checkAllValue,checkBoxValues}=this.state;
let selectpagetype=selectpage===page?true:false let selectpagetype=selectpage===page?true:false
@ -393,7 +393,9 @@ class GraduationTasks extends Component{
this.setState({ this.setState({
order: e.key, order: e.key,
isSpin:true isSpin:true,
checkBoxValues:[],
checkAllValue:false
}); });
let newkey=e.key; let newkey=e.key;
@ -676,7 +678,7 @@ class GraduationTasks extends Component{
// } // }
secondRowLeft={ secondRowLeft={
<div style={{"display":"inline-block", "marginTop": "22px"}}> <div style={{"display":"inline-block", "marginTop": "22px"}}>
<span>{all_count}个毕设任务</span> <span>{all_count}个毕设任务</span>
<span style={{"marginLeft":"16px"}}>已发布{this.state.published_count}</span> <span style={{"marginLeft":"16px"}}>已发布{this.state.published_count}</span>
<span style={{"marginLeft":"16px"}}>未发布{this.state.unpublished_count}</span> <span style={{"marginLeft":"16px"}}>未发布{this.state.unpublished_count}</span>
@ -738,7 +740,7 @@ class GraduationTasks extends Component{
{ tasks&&tasks.map((item, index) => { { tasks&&tasks.map((item, index) => {
// console.log(item) // console.log(item)
return ( return (
<div className="mt20 edu-back-white padding02010" key={index} onClick={()=>this.onItemClick(item)}> <div className="mt20 edu-back-white pt10 pl30 pr30" key={index} onClick={()=>this.onItemClick(item)}>
<div className="clearfix"> <div className="clearfix">
<GraduateTaskItem <GraduateTaskItem
discussMessage={item} discussMessage={item}
@ -755,6 +757,7 @@ class GraduationTasks extends Component{
coursesId={this.props.match.params.coursesId} coursesId={this.props.match.params.coursesId}
categoryid={this.props.match.params.Id} categoryid={this.props.match.params.Id}
workid={item.work_id} workid={item.work_id}
index={index}
></GraduateTaskItem> ></GraduateTaskItem>
</div> </div>
</div> </div>

@ -6,7 +6,7 @@ import '../style.css'
import axios from "axios"; import axios from "axios";
import GraduateTopicReply from './GraduateTopicReply' import GraduateTopicReply from './GraduateTopicReply'
import { ConditionToolTip,MarkdownToHtml } from 'educoder' import { ConditionToolTip , MarkdownToHtml , AttachmentList } from 'educoder'
const $=window.$; const $=window.$;
const type={1: "设计",2: "论文", 3: "创作"} const type={1: "设计",2: "论文", 3: "创作"}
@ -60,9 +60,10 @@ class GraduateTopicDetailTable extends Component{
{ {
topicInfo && topicInfo.attachment_list.length>0 && topicInfo && topicInfo.attachment_list.length>0 &&
<p className="mt30"> <p className="mt30">
{ {/* {
topicInfo.attachment_list.map((item,key)=>{ topicInfo.attachment_list.map((item,key)=>{
return( return(
<li className="clearfix mb8" key={key}> <li className="clearfix mb8" key={key}>
<i className="iconfont icon-fujian color-green font-16 mr8 fl"></i> <i className="iconfont icon-fujian color-green font-16 mr8 fl"></i>
<ConditionToolTip title={item.title} condition={item.title && item.title.length > 30 }> <ConditionToolTip title={item.title} condition={item.title && item.title.length > 30 }>
@ -72,7 +73,8 @@ class GraduateTopicDetailTable extends Component{
</li> </li>
) )
}) })
} } */}
<AttachmentList {...this.props} {...this.state} attachments = {topicInfo.attachment_list}></AttachmentList>
</p> </p>
} }
</div> </div>

@ -47,7 +47,7 @@ class GraduateTopicItem extends Component{
} }
</style> </style>
<div className="graduateTopicList boardsList mb20"> <div className="graduateTopicList boardsList mb20" style={{cursor : isAdmin ? "pointer" : "default" }} onClick={() => window.$(`.topicItem${index} input`).click() }>
<style>{` <style>{`
.graduateTopicList .ant-checkbox-input {s .graduateTopicList .ant-checkbox-input {s
@ -58,7 +58,7 @@ class GraduateTopicItem extends Component{
padding: 17px 30px 20px!important; padding: 17px 30px 20px!important;
} }
`}</style> `}</style>
{ isAdmin ? checkBox : ""} { isAdmin ? <span className={`topicItem${index} fl`} style={{"height":"64px"}}>{checkBox}</span> : ""}
<div className="clearfix ds pr flex1"> <div className="clearfix ds pr flex1">
<style>{` <style>{`
.maxwidth580{ .maxwidth580{

@ -358,6 +358,17 @@ class GraduateTopicNew extends Component{
</Select> </Select>
)} )}
</Form.Item> </Form.Item>
<style>
{
`
.exercicenewinputysl .ant-input{
border-right: none !important;
height: 40px !important;
}
`
}
</style>
<Form.Item <Form.Item
label="选题名称" label="选题名称"
className="mt15" className="mt15"
@ -369,7 +380,7 @@ class GraduateTopicNew extends Component{
max: 60, message: '最大限制为60个字符', max: 60, message: '最大限制为60个字符',
}], }],
})( })(
<Input placeholder="请输入帖子选题名称最大限制60个字符" maxLength="60" onInput={this.changeTopicName} autoComplete="off" suffix={`${String(addonAfter)}/${NAME_COUNT}`} className="searchViewAfter" /> <Input placeholder="请输入帖子选题名称最大限制60个字符" maxLength="60" onInput={this.changeTopicName} autoComplete="off" addonAfter={`${String(addonAfter)}/${NAME_COUNT}`} className="searchViewAfter exercicenewinputysl" />
)} )}
</Form.Item> </Form.Item>
</div> </div>

@ -1,288 +1,288 @@
import React, { Component } from "react"; import React, { Component } from "react";
import { Modal, Checkbox, Input, Spin, Select, Divider } from "antd"; import { Modal, Checkbox, Input, Spin, Select, Divider } from "antd";
import axios from 'axios' import axios from 'axios'
import ModalWrapper from "../../common/ModalWrapper" import ModalWrapper from "../../common/ModalWrapper"
import InfiniteScroll from 'react-infinite-scroller'; import InfiniteScroll from 'react-infinite-scroller';
import { ROLE_TEACHER_NUM, ROLE_ASSISTANT_NUM } from '../common' import { ROLE_TEACHER_NUM, ROLE_ASSISTANT_NUM } from '../common'
import NoneData from '../../coursesPublic/NoneData' import NoneData from '../../coursesPublic/NoneData'
import { ConditionToolTip, ThemeContext } from 'educoder' import { ConditionToolTip, ThemeContext } from 'educoder'
import SchoolSelect from '../../coursesPublic/form/SchoolSelect' import SchoolSelect from '../../coursesPublic/form/SchoolSelect'
const Option = Select.Option; const Option = Select.Option;
const pageCount = 15; const pageCount = 15;
class AddStudentModal extends Component{ class AddStudentModal extends Component{
constructor(props){ constructor(props){
super(props); super(props);
this.state={ this.state={
checkBoxValues: [], checkBoxValues: [],
users: [], users: [],
hasMore: true, hasMore: true,
loading: false, loading: false,
courseGroup: '', courseGroup: '',
page: 1, page: 1,
isSpin:false isSpin:false
} }
} }
fetchMemberList = (arg_page) => { fetchMemberList = (arg_page) => {
const courseId = this.props.match.params.coursesId const courseId = this.props.match.params.coursesId
const page = arg_page || this.state.page; const page = arg_page || this.state.page;
const { name, school_name } = this.state const { name, school_name } = this.state
let url = `/courses/${courseId}/search_users.json?page=${page}&limit=${pageCount}&school_name=${school_name || ''}&name=${name || ''}` let url = `/courses/${courseId}/search_users.json?page=${page}&limit=${pageCount}&school_name=${school_name || ''}&name=${name || ''}`
this.setState({ loading: true }) this.setState({ loading: true })
axios.get(url) axios.get(url)
.then((response) => { .then((response) => {
if (!response.data.users || response.data.users.length == 0) { if (!response.data.users || response.data.users.length == 0) {
this.setState({ this.setState({
users: page == 1 ? response.data.users : this.state.users, users: page == 1 ? response.data.users : this.state.users,
page, page,
loading: false, loading: false,
hasMore: false, hasMore: false,
}) })
} else { } else {
this.setState({ this.setState({
users: page == 1 ? response.data.users : this.state.users.concat(response.data.users), users: page == 1 ? response.data.users : this.state.users.concat(response.data.users),
page, page,
loading: false, loading: false,
hasMore: response.data.users.length == pageCount hasMore: response.data.users.length == pageCount
}) })
} }
}) })
.catch(function (error) { .catch(function (error) {
console.log(error); console.log(error);
}); });
} }
componentDidMount() { componentDidMount() {
} }
fetchOptions = () => { fetchOptions = () => {
// add_teacher_popup // add_teacher_popup
const courseId = this.props.match.params.coursesId const courseId = this.props.match.params.coursesId
let url = `/courses/${courseId}/all_course_groups.json` let url = `/courses/${courseId}/all_course_groups.json`
axios.get(url, { axios.get(url, {
}) })
.then((response) => { .then((response) => {
if (response.data.course_groups && response.data.course_groups.length) { if (response.data.course_groups && response.data.course_groups.length) {
this.setState({ this.setState({
course_groups: response.data.course_groups, course_groups: response.data.course_groups,
courseGroup: response.data.course_groups[0].id courseGroup: response.data.course_groups[0].id
}) })
} else { } else {
// showNotification('') // showNotification('')
} }
}) })
.catch(function (error) { .catch(function (error) {
console.log(error); console.log(error);
}); });
} }
setVisible = (visible) => { setVisible = (visible) => {
if (visible) { if (visible) {
this.setState({school_name: this.props.user.user_school}) this.setState({school_name: this.props.user.user_school})
this.fetchMemberList() this.fetchMemberList()
this.fetchOptions() this.fetchOptions()
} }
this.refs.modalWrapper.setVisible(visible) this.refs.modalWrapper.setVisible(visible)
if (visible == false) { if (visible == false) {
this.setState({ this.setState({
checkBoxValues: [] checkBoxValues: []
}) })
} }
} }
onSendOk = () => { onSendOk = () => {
if(!this.state.checkBoxValues || this.state.checkBoxValues.length == 0) { if(!this.state.checkBoxValues || this.state.checkBoxValues.length == 0) {
this.props.showNotification('请从列表中先选择用户。') this.props.showNotification('请从列表中先选择用户。')
return; return;
} }
this.setState({ this.setState({
isSpin:true isSpin:true
}) })
const courseId = this.props.match.params.coursesId const courseId = this.props.match.params.coursesId
const url = `/courses/${courseId}/add_students_by_search.json` const url = `/courses/${courseId}/add_students_by_search.json`
const params = { const params = {
"user_ids": this.state.checkBoxValues "user_ids": this.state.checkBoxValues
} }
const { courseGroup } = this.state const { courseGroup } = this.state
if (courseGroup) { if (courseGroup) {
params.course_group_id = courseGroup params.course_group_id = courseGroup
} }
axios.post(url, params) axios.post(url, params)
.then((response) => { .then((response) => {
if (response.data.status == 0) { if (response.data.status == 0) {
this.setVisible(false) this.setVisible(false)
this.props.showNotification('添加成功') this.props.showNotification('添加成功')
this.props.addStudentSuccess && this.props.addStudentSuccess(params) this.props.addStudentSuccess && this.props.addStudentSuccess(params)
this.setState({ this.setState({
isSpin:false isSpin:false
}) })
} }
}) })
.catch(function (error) { .catch(function (error) {
console.log(error); console.log(error);
}); });
} }
onOk = () => { onOk = () => {
this.onSendOk() this.onSendOk()
} }
onCheckBoxChange = (checkBoxValues) => { onCheckBoxChange = (checkBoxValues) => {
this.setState({ this.setState({
checkBoxValues: checkBoxValues checkBoxValues: checkBoxValues
}) })
} }
handleInfiniteOnLoad = () => { handleInfiniteOnLoad = () => {
this.fetchMemberList(this.state.page + 1) this.fetchMemberList(this.state.page + 1)
} }
onSearch = () => { onSearch = () => {
this.fetchMemberList(1) this.fetchMemberList(1)
} }
handleCourseGroupChange = (value) => { handleCourseGroupChange = (value) => {
this.setState({ this.setState({
courseGroup: value courseGroup: value
}) })
} }
render(){ render(){
const { users, checkBoxValues, loading, hasMore, name, school_name const { users, checkBoxValues, loading, hasMore, name, school_name
, courseGroup, course_groups,isSpin } = this.state , courseGroup, course_groups,isSpin } = this.state
const { moduleName } = this.props const { moduleName } = this.props
let theme = this.context; let theme = this.context;
return( return(
<ModalWrapper <ModalWrapper
ref="modalWrapper" ref="modalWrapper"
width="700px" width="700px"
title={`添加${moduleName}`} title={`添加${moduleName}`}
{...this.props } {...this.props }
onOk={this.onOk} onOk={this.onOk}
className="addStudentModal courseForm" className="addStudentModal courseForm"
> >
<style> <style>
{` {`
.demo-loading-container { .demo-loading-container {
position: absolute; position: absolute;
bottom: 93px; bottom: 93px;
width: 82%; width: 82%;
text-align: center; text-align: center;
} }
.df { .df {
display: flex; display: flex;
align-items: baseline; align-items: baseline;
margin: 12px 0; margin: 12px 0;
} }
.firstLabel { .firstLabel {
flex: 0 0 60px; flex: 0 0 60px;
} }
.df span.label { .df span.label {
margin-right: 8px; margin-right: 8px;
text-align: right; text-align: right;
margin-left: 12px; margin-left: 12px;
} }
.df .ant-input-affix-wrapper { .df .ant-input-affix-wrapper {
width: 32%; width: 32%;
} }
.addTeacherModal label.task-hide { .addTeacherModal label.task-hide {
width: 100%; width: 100%;
} }
`} `}
</style> </style>
<div className="df"> <div className="df">
<span className="mr10">姓名:</span> <span className="mr10">姓名:</span>
<Input allowClear placeholder="请输入真实姓名" value={name} onChange={(e) => {this.setState({name: e.target.value})}} <Input allowClear placeholder="请输入真实姓名" value={name} onChange={(e) => {this.setState({name: e.target.value})}}
style={{ width: '221px'}} style={{ width: '221px'}}
></Input> ></Input>
<span className="label" style={{ minWidth: '36px' }}>单位:</span> <span className="label" style={{ minWidth: '36px' }}>单位:</span>
{/* <Input allowClear placeholder="" value={school_name} onChange={(e) => {this.setState({school_name: e.target.value})}} {/* <Input allowClear placeholder="" value={school_name} onChange={(e) => {this.setState({school_name: e.target.value})}}
style={{ width: '200px'}}> style={{ width: '200px'}}>
</Input> */} </Input> */}
<SchoolSelect <SchoolSelect
value={school_name} value={school_name}
onChange={(value) => {this.setState({school_name: value})}} onChange={(value) => {this.setState({school_name: value})}}
></SchoolSelect> ></SchoolSelect>
<a className="task-btn task-btn-orange" onClick={() => this.fetchMemberList(1)} <a className="task-btn task-btn-orange" onClick={() => this.fetchMemberList(1)}
style={{ height: '30px', lineHeight: '30px', marginLeft: '10px', width: '70px'}} style={{ height: '30px', lineHeight: '30px', marginLeft: '10px', width: '70px'}}
>搜索</a> >搜索</a>
</div> </div>
{/* <Divider /> */} {/* <Divider /> */}
<p className="clearfix mb2" style={{ margin: '0px 15px 6px' }}> <p className="clearfix mb2" style={{ margin: '0px 15px 6px' }}>
<Checkbox className="fl" style={{ visibility: 'hidden' }} ></Checkbox> <Checkbox className="fl" style={{ visibility: 'hidden' }} ></Checkbox>
<span className="fl with25"><label className="task-hide fl" style={{"maxWidth":"208px;"}}>{'姓名'}</label></span> <span className="fl with25"><label className="task-hide fl" style={{"maxWidth":"208px;"}}>{'姓名'}</label></span>
<span className="fl with25"><label className="task-hide fl" style={{"maxWidth":"208px;"}}>{'学号'}</label></span> <span className="fl with25"><label className="task-hide fl" style={{"maxWidth":"208px;"}}>{'学号'}</label></span>
<span className="fl with35"><label className="task-hide fl" style={{"maxWidth":"208px;"}}>{'单位'}</label></span> <span className="fl with35"><label className="task-hide fl" style={{"maxWidth":"208px;"}}>{'单位'}</label></span>
<span className="fl with10"><label className="task-hide fl" style={{"maxWidth":"48px;"}}>{''}</label></span> <span className="fl with10"><label className="task-hide fl" style={{"maxWidth":"48px;"}}>{''}</label></span>
</p> </p>
<Spin size="large" spinning={isSpin}> <Spin size="large" spinning={isSpin}>
{ loading || users.length ? <div> { loading || users.length ? <div>
{/* https://github.com/CassetteRocks/react-infinite-scroller/issues/70 */} {/* https://github.com/CassetteRocks/react-infinite-scroller/issues/70 */}
<div className="edu-back-skyblue padding10-15" style={{"height":"300px", overflowY: "scroll", overflowAnchor: 'none' }}> <div className="edu-back-skyblue padding10-15" style={{"height":"300px", overflowY: "scroll", overflowAnchor: 'none' }}>
<InfiniteScroll <InfiniteScroll
threshold={10} threshold={10}
initialLoad={false} initialLoad={false}
pageStart={0} pageStart={0}
loadMore={this.handleInfiniteOnLoad} loadMore={this.handleInfiniteOnLoad}
hasMore={!loading && hasMore} hasMore={!loading && hasMore}
useWindow={false} useWindow={false}
> >
<Checkbox.Group style={{ width: '100%' }} onChange={this.onCheckBoxChange} value={checkBoxValues}> <Checkbox.Group style={{ width: '100%' }} onChange={this.onCheckBoxChange} value={checkBoxValues}>
{ users.map( candidate => { { users.map( candidate => {
return ( return (
<p className="clearfix mb7" key={candidate.id}> <p className="clearfix mb7" key={candidate.id}>
<Checkbox className="fl" value={candidate.id} key={candidate.id} disabled={candidate.added}></Checkbox> <Checkbox className="fl" value={candidate.id} key={candidate.id} disabled={candidate.added}></Checkbox>
<span className="fl with25"> <span className="fl with25">
<ConditionToolTip title={candidate.name} condition={candidate.name && candidate.name.length > 12 }> <ConditionToolTip title={candidate.name} condition={candidate.name && candidate.name.length > 12 }>
<label className="task-hide fl" style={{"maxWidth":"208px;"}}> <label className="task-hide fl" style={{"maxWidth":"208px;"}}>
{ candidate.name ? { candidate.name ?
<a href={`/users/${candidate.login}`} target="_blank" style={{"maxWidth":"208px;"}}> <a href={`/users/${candidate.login}`} target="_blank" style={{"maxWidth":"208px;"}}>
{ candidate.name } { candidate.name }
</a> : <span> </span> } </a> : <span> </span> }
</label> </label>
</ConditionToolTip> </ConditionToolTip>
</span> </span>
<span className="fl with25"> <span className="fl with25">
<ConditionToolTip title={candidate.student_id} condition={candidate.student_id && candidate.student_id.length > 12 }> <ConditionToolTip title={candidate.student_id} condition={candidate.student_id && candidate.student_id.length > 12 }>
<label className="task-hide fl" style={{"maxWidth":"208px;"}}>{candidate.student_id || ' '}</label> <label className="task-hide fl" style={{"maxWidth":"208px;"}}>{candidate.student_id || ' '}</label>
</ConditionToolTip> </ConditionToolTip>
</span> </span>
<span className="fl with35"><label className="task-hide fl" style={{"maxWidth":"208px;"}}>{candidate.school_name}</label></span> <span className="fl with35"><label className="task-hide fl" style={{"maxWidth":"208px;"}}>{candidate.school_name}</label></span>
<span className="fl with10"><label className="task-hide fl" <span className="fl with10"><label className="task-hide fl"
style={{"maxWidth":"48px", color: theme.foreground_select }}>{candidate.added ? '已加入' : ''}</label></span> style={{"maxWidth":"48px", color: theme.foreground_select }}>{candidate.added ? '已加入' : ''}</label></span>
</p> </p>
) )
}) } }) }
</Checkbox.Group> </Checkbox.Group>
{loading && hasMore && ( {loading && hasMore && (
<div className="demo-loading-container"> <div className="demo-loading-container">
<Spin /> <Spin />
</div> </div>
)} )}
</InfiniteScroll> </InfiniteScroll>
</div> </div>
{course_groups && course_groups.length && <div className="df" style={{ marginTop: '12px' }} > {course_groups && course_groups.length && <div className="df" style={{ marginTop: '12px' }} >
<span className="mr10" style={{ width: '148px' }}>所选学生分班至(选填):</span> <span className="mr10" style={{ width: '148px' }}>所选学生分班至(选填):</span>
<Select style={{ width: 236 }} onChange={this.handleCourseGroupChange} value={courseGroup}> <Select style={{ width: 236 }} onChange={this.handleCourseGroupChange} value={courseGroup}>
{ course_groups.map((item) => { { course_groups.map((item) => {
return <Option value={item.id}>{item.name}</Option> return <Option value={item.id}>{item.name}</Option>
})} })}
</Select> </Select>
</div>} </div>}
</div> : <NoneData></NoneData> } </div> : <NoneData></NoneData> }
</Spin> </Spin>
</ModalWrapper> </ModalWrapper>
) )
} }
} }
AddStudentModal.contextType = ThemeContext; AddStudentModal.contextType = ThemeContext;
export default AddStudentModal; export default AddStudentModal;

@ -1,355 +1,355 @@
import React, { Component } from "react"; import React, { Component } from "react";
import { Modal, Checkbox, Input, Spin, Select, Divider, Icon } from "antd"; import { Modal, Checkbox, Input, Spin, Select, Divider, Icon } from "antd";
import axios from 'axios' import axios from 'axios'
import ModalWrapper from "../../common/ModalWrapper" import ModalWrapper from "../../common/ModalWrapper"
import InfiniteScroll from 'react-infinite-scroller'; import InfiniteScroll from 'react-infinite-scroller';
import { ROLE_TEACHER_NUM, ROLE_ASSISTANT_NUM } from '../common' import { ROLE_TEACHER_NUM, ROLE_ASSISTANT_NUM } from '../common'
import { ConditionToolTip, ActionBtn } from 'educoder' import { ConditionToolTip, ActionBtn } from 'educoder'
import NoneData from '../../coursesPublic/NoneData' import NoneData from '../../coursesPublic/NoneData'
import AddGraduationGroupModal from './AddGraduationGroupModal' import AddGraduationGroupModal from './AddGraduationGroupModal'
import SchoolSelect from '../../coursesPublic/form/SchoolSelect' import SchoolSelect from '../../coursesPublic/form/SchoolSelect'
const Option = Select.Option; const Option = Select.Option;
const pageCount = 15; const pageCount = 15;
let timeout, currentValue let timeout, currentValue
class AddTeacherModal extends Component{ class AddTeacherModal extends Component{
constructor(props){ constructor(props){
super(props); super(props);
this.state={ this.state={
school_names: [], school_names: [],
checkBoxValues: [], checkBoxValues: [],
candidates: [], candidates: [],
hasMore: true, hasMore: true,
loading: false, loading: false,
page: 1 page: 1
} }
} }
fetchMemberList = (arg_page) => { fetchMemberList = (arg_page) => {
const courseId = this.props.match.params.coursesId const courseId = this.props.match.params.coursesId
const page = arg_page || this.state.page; const page = arg_page || this.state.page;
const { name, school_name } = this.state const { name, school_name } = this.state
let url = `/courses/${courseId}/search_teacher_candidate.json` let url = `/courses/${courseId}/search_teacher_candidate.json`
this.setState({ loading: true }) this.setState({ loading: true })
axios.post(url, { axios.post(url, {
page: page, page: page,
limit: pageCount, limit: pageCount,
school_name: school_name || '', school_name: school_name || '',
name: name || '' name: name || ''
}) })
.then((response) => { .then((response) => {
if (!response.data.candidates || response.data.candidates.length == 0) { if (!response.data.candidates || response.data.candidates.length == 0) {
this.setState({ this.setState({
candidates: page == 1 ? response.data.candidates : this.state.candidates, candidates: page == 1 ? response.data.candidates : this.state.candidates,
page, page,
loading: false, loading: false,
hasMore: false, hasMore: false,
}) })
} else { } else {
this.setState({ this.setState({
candidates: page == 1 ? response.data.candidates : this.state.candidates.concat(response.data.candidates), candidates: page == 1 ? response.data.candidates : this.state.candidates.concat(response.data.candidates),
page, page,
loading: false, loading: false,
hasMore: response.data.candidates.length == pageCount hasMore: response.data.candidates.length == pageCount
}) })
} }
}) })
.catch(function (error) { .catch(function (error) {
console.log(error); console.log(error);
}); });
} }
componentDidMount() { componentDidMount() {
} }
onAddGraduationGroupOk = () => { onAddGraduationGroupOk = () => {
this.fetchOptions() this.fetchOptions()
} }
fetchOptions = () => { fetchOptions = () => {
// add_teacher_popup // add_teacher_popup
const courseId = this.props.match.params.coursesId const courseId = this.props.match.params.coursesId
let url = `/courses/${courseId}/add_teacher_popup.json` let url = `/courses/${courseId}/add_teacher_popup.json`
axios.get(url, { axios.get(url, {
}) })
.then((response) => { .then((response) => {
if (response.data.school_name) { if (response.data.school_name) {
this.setState({ this.setState({
school_name: response.data.school_name school_name: response.data.school_name
}, () => this.fetchMemberList()) }, () => this.fetchMemberList())
} else { } else {
this.fetchMemberList() this.fetchMemberList()
} }
if (response.data.graduation_groups) { if (response.data.graduation_groups) {
this.setState({ this.setState({
graduation_groups: response.data.graduation_groups graduation_groups: response.data.graduation_groups
}) })
} }
if (response.data.course_groups) { if (response.data.course_groups) {
this.setState({ this.setState({
course_groups: response.data.course_groups course_groups: response.data.course_groups
}) })
} }
}) })
.catch(function (error) { .catch(function (error) {
console.log(error); console.log(error);
}); });
} }
setVisible = (visible) => { setVisible = (visible) => {
if (visible) { if (visible) {
this.fetchOptions() this.fetchOptions()
} }
this.refs.modalWrapper.setVisible(visible) this.refs.modalWrapper.setVisible(visible)
if (visible == false) { if (visible == false) {
this.setState({ this.setState({
checkBoxValues: [] checkBoxValues: []
}) })
} }
} }
onSendOk = () => { onSendOk = () => {
const courseId = this.props.match.params.coursesId const courseId = this.props.match.params.coursesId
const url = `/courses/${courseId}/add_teacher.json` const url = `/courses/${courseId}/add_teacher.json`
if (this.state.checkBoxValues.length == 0) { if (this.state.checkBoxValues.length == 0) {
this.props.showNotification('请先在下面列表中选择要添加教师的成员') this.props.showNotification('请先在下面列表中选择要添加教师的成员')
return return
} }
const params = { const params = {
"user_list": this.state.checkBoxValues.map (item => { return { 'user_id': item }}) , "user_list": this.state.checkBoxValues.map (item => { return { 'user_id': item }}) ,
// "graduation_group_id": "2", // "graduation_group_id": "2",
// "course_group_id": "820", // "course_group_id": "820",
"role": this.props.isTeacher ? ROLE_TEACHER_NUM : ROLE_ASSISTANT_NUM "role": this.props.isTeacher ? ROLE_TEACHER_NUM : ROLE_ASSISTANT_NUM
} }
const { graduationGroup, courseGroup } = this.state const { graduationGroup, courseGroup } = this.state
if (graduationGroup) { if (graduationGroup) {
params.graduation_group_id = graduationGroup params.graduation_group_id = graduationGroup
} }
if (courseGroup) { if (courseGroup) {
params.course_group_id = courseGroup params.course_group_id = courseGroup
} }
axios.post(url, params) axios.post(url, params)
.then((response) => { .then((response) => {
if (response.data.status == 0) { if (response.data.status == 0) {
this.setVisible(false) this.setVisible(false)
this.props.showNotification('添加成功') this.props.showNotification('添加成功')
this.props.addTeacherSuccess && this.props.addTeacherSuccess(params) this.props.addTeacherSuccess && this.props.addTeacherSuccess(params)
} }
}) })
.catch(function (error) { .catch(function (error) {
console.log(error); console.log(error);
}); });
} }
onOk = () => { onOk = () => {
this.onSendOk() this.onSendOk()
} }
onCheckBoxChange = (checkBoxValues) => { onCheckBoxChange = (checkBoxValues) => {
this.setState({ this.setState({
checkBoxValues: checkBoxValues checkBoxValues: checkBoxValues
}) })
} }
handleInfiniteOnLoad = () => { handleInfiniteOnLoad = () => {
this.fetchMemberList(this.state.page + 1) this.fetchMemberList(this.state.page + 1)
} }
onSearch = () => { onSearch = () => {
this.fetchMemberList(1) this.fetchMemberList(1)
} }
handleGradationGroupChange = (value) => { handleGradationGroupChange = (value) => {
this.setState({ this.setState({
graduationGroup: value graduationGroup: value
}) })
} }
handleCourseGroupChange = (value) => { handleCourseGroupChange = (value) => {
this.setState({ this.setState({
courseGroup: value courseGroup: value
}) })
} }
onOrgNameChange = (value) => { onOrgNameChange = (value) => {
// console.log('school_name: ', value) // console.log('school_name: ', value)
this.setState({ school_name: value }) this.setState({ school_name: value })
} }
hasGraduationModule = () => { hasGraduationModule = () => {
const { course_modules } = this.props; const { course_modules } = this.props;
const result = course_modules && course_modules.filter( item => { const result = course_modules && course_modules.filter( item => {
return item.type == 'graduation' return item.type == 'graduation'
}) })
return result && result.length > 0 return result && result.length > 0
} }
render(){ render(){
const { candidates, checkBoxValues, loading, hasMore, name, school_name, school_names const { candidates, checkBoxValues, loading, hasMore, name, school_name, school_names
, graduationGroup, graduation_groups, courseGroup, course_groups } = this.state , graduationGroup, graduation_groups, courseGroup, course_groups } = this.state
const { moduleName } = this.props const { moduleName } = this.props
return( return(
<ModalWrapper <ModalWrapper
ref="modalWrapper" ref="modalWrapper"
width="700px" width="700px"
title={`添加${moduleName}`} title={`添加${moduleName}`}
{...this.props } {...this.props }
onOk={this.onOk} onOk={this.onOk}
className="addTeacherModal courseForm" className="addTeacherModal courseForm"
> >
<AddGraduationGroupModal ref="addGraduationGroupModal" <AddGraduationGroupModal ref="addGraduationGroupModal"
{...this.props} onOk={this.onAddGraduationGroupOk} {...this.props} onOk={this.onAddGraduationGroupOk}
></AddGraduationGroupModal> ></AddGraduationGroupModal>
<style> <style>
{` {`
.demo-loading-container { .demo-loading-container {
position: absolute; position: absolute;
bottom: 210px; bottom: 210px;
width: 82%; width: 82%;
text-align: center; text-align: center;
} }
.df { .df {
display: flex; display: flex;
align-items: baseline; align-items: baseline;
margin: 12px 0; margin: 12px 0;
} }
.firstLabel { .firstLabel {
flex: 0 0 60px; flex: 0 0 60px;
} }
.df span.label { .df span.label {
margin-right: 8px; margin-right: 8px;
text-align: left; text-align: left;
} }
.df .ant-input-affix-wrapper { .df .ant-input-affix-wrapper {
width: 32%; width: 32%;
} }
.addTeacherModal label.task-hide { .addTeacherModal label.task-hide {
width: 100%; width: 100%;
} }
`} `}
</style> </style>
<div className="df"> <div className="df">
<span className="firstLabel label" style={{ flex: '0 0 40px' }}>姓名:</span> <span className="firstLabel label" style={{ flex: '0 0 40px' }}>姓名:</span>
<Input allowClear placeholder="请输入真实姓名" value={name} onChange={(e) => {this.setState({name: e.target.value})}} <Input allowClear placeholder="请输入真实姓名" value={name} onChange={(e) => {this.setState({name: e.target.value})}}
style={{ width: '200px', marginRight: '18px' }}> style={{ width: '200px', marginRight: '18px' }}>
</Input> </Input>
<span className="label" style={{ minWidth: '36px', flex: '0 0 40px' }}>单位:</span> <span className="label" style={{ minWidth: '36px', flex: '0 0 40px' }}>单位:</span>
<SchoolSelect <SchoolSelect
value={school_name} value={school_name}
onChange={this.onOrgNameChange} onChange={this.onOrgNameChange}
></SchoolSelect> ></SchoolSelect>
{/* <Select allowClear placeholder="" value={school_name} {/* <Select allowClear placeholder="" value={school_name}
style={{ width: '200px'}} showArrow={false} style={{ width: '200px'}} showArrow={false}
filterOption={false} onSearch={this.onOrgNameSearch} filterOption={false} onSearch={this.onOrgNameSearch}
onChange={this.onOrgNameChange} notFoundContent={null} onChange={this.onOrgNameChange} notFoundContent={null}
showSearch defaultActiveFirstOption={false} showSearch defaultActiveFirstOption={false}
> >
{ school_names && school_names.map((item, index) => { { school_names && school_names.map((item, index) => {
return <Option value={item} key={index}>{item}</Option> return <Option value={item} key={index}>{item}</Option>
})} })}
</Select> */} </Select> */}
<a className="task-btn task-btn-orange" onClick={() => this.fetchMemberList(1)} <a className="task-btn task-btn-orange" onClick={() => this.fetchMemberList(1)}
style={{ height: '30px', lineHeight: '30px', marginLeft: '10px', width: '70px'}} style={{ height: '30px', lineHeight: '30px', marginLeft: '10px', width: '70px'}}
>搜索</a> >搜索</a>
</div> </div>
{/* graduation_groups && !!graduation_groups.length */} {/* graduation_groups && !!graduation_groups.length */}
<p className="clearfix mb2" style={{ margin: '0px 15px 6px' }}> <p className="clearfix mb2" style={{ margin: '0px 15px 6px' }}>
<Checkbox className="fl" style={{ visibility: 'hidden' }} ></Checkbox> <Checkbox className="fl" style={{ visibility: 'hidden' }} ></Checkbox>
<span className="fl with25"><label className="task-hide fl" style={{"maxWidth":"208px;"}}>{'姓名'}</label></span> <span className="fl with25"><label className="task-hide fl" style={{"maxWidth":"208px;"}}>{'姓名'}</label></span>
<span className="fl with25"><label className="task-hide fl" style={{"maxWidth":"208px;"}}>{'昵称'}</label></span> <span className="fl with25"><label className="task-hide fl" style={{"maxWidth":"208px;"}}>{'昵称'}</label></span>
<span className="fl with35"><label className="task-hide fl" style={{"maxWidth":"208px;"}}>{'单位'}</label></span> <span className="fl with35"><label className="task-hide fl" style={{"maxWidth":"208px;"}}>{'单位'}</label></span>
<span className="fl with10"><label className="task-hide fl" style={{"maxWidth":"48px"}}>{''}</label></span> <span className="fl with10"><label className="task-hide fl" style={{"maxWidth":"48px"}}>{''}</label></span>
</p> </p>
{ loading || candidates.length ? <div> { loading || candidates.length ? <div>
{/* https://github.com/CassetteRocks/react-infinite-scroller/issues/70 */} {/* https://github.com/CassetteRocks/react-infinite-scroller/issues/70 */}
<div className="edu-back-skyblue padding10-15" style={{"height":"300px", overflowY: "scroll", overflowAnchor: 'none' }}> <div className="edu-back-skyblue padding10-15" style={{"height":"300px", overflowY: "scroll", overflowAnchor: 'none' }}>
<InfiniteScroll <InfiniteScroll
threshold={10} threshold={10}
initialLoad={false} initialLoad={false}
pageStart={0} pageStart={0}
loadMore={this.handleInfiniteOnLoad} loadMore={this.handleInfiniteOnLoad}
hasMore={!loading && hasMore} hasMore={!loading && hasMore}
useWindow={false} useWindow={false}
> >
<Checkbox.Group style={{ width: '100%' }} onChange={this.onCheckBoxChange} value={checkBoxValues}> <Checkbox.Group style={{ width: '100%' }} onChange={this.onCheckBoxChange} value={checkBoxValues}>
{ candidates && candidates.map( candidate => { { candidates && candidates.map( candidate => {
return ( return (
<p className="clearfix mb7" key={candidate.id}> <p className="clearfix mb7" key={candidate.id}>
<Checkbox className="fl" value={candidate.id} key={candidate.id}></Checkbox> <Checkbox className="fl" value={candidate.id} key={candidate.id}></Checkbox>
<span className="fl with25"> <span className="fl with25">
{/* "color":"#4c4c4c" */} {/* "color":"#4c4c4c" */}
<ConditionToolTip title={candidate.name} condition={candidate.name && candidate.name.length > 12 }> <ConditionToolTip title={candidate.name} condition={candidate.name && candidate.name.length > 12 }>
<label className="task-hide fl" style={{"maxWidth":"208px;"}} <label className="task-hide fl" style={{"maxWidth":"208px;"}}
> >
<a href={`/users/${candidate.login}`} target="_blank" <a href={`/users/${candidate.login}`} target="_blank"
style={{}} style={{}}
>{candidate.name}</a> >{candidate.name}</a>
</label> </label>
</ConditionToolTip> </ConditionToolTip>
</span> </span>
<span className="fl with25"> <span className="fl with25">
<ConditionToolTip title={candidate.nickname} condition={candidate.nickname && candidate.nickname.length > 12 }> <ConditionToolTip title={candidate.nickname} condition={candidate.nickname && candidate.nickname.length > 12 }>
<label className="task-hide fl" style={{"maxWidth":"208px;"}}>{candidate.nickname || ' '}</label> <label className="task-hide fl" style={{"maxWidth":"208px;"}}>{candidate.nickname || ' '}</label>
</ConditionToolTip> </ConditionToolTip>
</span> </span>
<span className="fl with35"><label className="task-hide fl" style={{"maxWidth":"208px;"}}>{candidate.school_name}</label></span> <span className="fl with35"><label className="task-hide fl" style={{"maxWidth":"208px;"}}>{candidate.school_name}</label></span>
<span className="fl with10"><label className="task-hide fl" style={{"maxWidth":"48px;"}}>{candidate.added ? '已加入' : ''}</label></span> <span className="fl with10"><label className="task-hide fl" style={{"maxWidth":"48px;"}}>{candidate.added ? '已加入' : ''}</label></span>
</p> </p>
) )
}) } }) }
</Checkbox.Group> </Checkbox.Group>
{loading && hasMore && ( {loading && hasMore && (
<div className="demo-loading-container"> <div className="demo-loading-container">
<Spin /> <Spin />
</div> </div>
)} )}
</InfiniteScroll> </InfiniteScroll>
</div> </div>
</div> : <NoneData></NoneData> } </div> : <NoneData></NoneData> }
<div className="df"> <div className="df">
{ this.hasGraduationModule() && <div className="df" style={{ marginTop: '24px' }} > { this.hasGraduationModule() && <div className="df" style={{ marginTop: '24px' }} >
<span className="firstLabel label" style={{ flex: '0 0 96px' }}>添加至答辩组:</span> <span className="firstLabel label" style={{ flex: '0 0 96px' }}>添加至答辩组:</span>
<Select style={{ width: 218, marginRight: '18px' }} onChange={this.handleGradationGroupChange} value={graduationGroup} <Select style={{ width: 218, marginRight: '18px' }} onChange={this.handleGradationGroupChange} value={graduationGroup}
dropdownRender={menu => ( dropdownRender={menu => (
<div> <div>
{menu} {menu}
<Divider style={{ margin: '4px 0' }} /> <Divider style={{ margin: '4px 0' }} />
{/* <ActionBtn {/* <ActionBtn
onMouseDown={() => { debugger; this.refs['addGraduationGroupModal'].setVisible(true) }} onMouseDown={() => { debugger; this.refs['addGraduationGroupModal'].setVisible(true) }}
>添加答辩组</ActionBtn> */} >添加答辩组</ActionBtn> */}
<div style={{ padding: '8px', cursor: 'pointer' }} <div style={{ padding: '8px', cursor: 'pointer' }}
onMouseDown={() => { debugger; this.refs['addGraduationGroupModal'].setVisible(true) }} onMouseDown={() => { debugger; this.refs['addGraduationGroupModal'].setVisible(true) }}
> >
<Icon type="plus" /> 添加答辩组 <Icon type="plus" /> 添加答辩组
</div> </div>
</div> </div>
)} )}
> >
{ graduation_groups && graduation_groups.map((item) => { { graduation_groups && graduation_groups.map((item) => {
return <Option value={item.id}>{item.name}</Option> return <Option value={item.id}>{item.name}</Option>
})} })}
</Select> </Select>
</div>} </div>}
{ course_groups && !!course_groups.length && <div className="df"> { course_groups && !!course_groups.length && <div className="df">
<span className="firstLabel label">管理权限:</span> <span className="firstLabel label">管理权限:</span>
<Select style={{ width: 218 }} onChange={this.handleCourseGroupChange} value={courseGroup}> <Select style={{ width: 218 }} onChange={this.handleCourseGroupChange} value={courseGroup}>
{ course_groups && course_groups.map((item) => { { course_groups && course_groups.map((item) => {
return <Option value={item.id}>{item.name}</Option> return <Option value={item.id}>{item.name}</Option>
})} })}
</Select> </Select>
</div> } </div> }
</div> </div>
</ModalWrapper> </ModalWrapper>
) )
} }
} }
export default AddTeacherModal; export default AddTeacherModal;

@ -13,12 +13,15 @@ class CreateGroupByImportModal extends Component{
constructor(props){ constructor(props){
super(props); super(props);
this.state={ this.state={
errorTip:undefined
} }
} }
fetchMemberList = (arg_page) => {
}
componentDidMount() {
}
onSendOk = () => { onSendOk = () => {
const courseId = this.props.match.params.coursesId const courseId = this.props.match.params.coursesId
let url = `/courses/${courseId}/create_group_by_importing_file.json` let url = `/courses/${courseId}/create_group_by_importing_file.json`
@ -109,7 +112,7 @@ class CreateGroupByImportModal extends Component{
render(){ render(){
const { candidates, checkBoxValues, loading, hasMore, name, school_name, school_names const { candidates, checkBoxValues, loading, hasMore, name, school_name, school_names
, graduationGroup, graduation_groups, courseGroup, course_groups , fileList , errorTip } = this.state , graduationGroup, graduation_groups, courseGroup, course_groups , fileList } = this.state
const { moduleName } = this.props const { moduleName } = this.props
const props = { const props = {
@ -129,18 +132,15 @@ class CreateGroupByImportModal extends Component{
onOk={this.onOk} onOk={this.onOk}
className="createGroupByImport" className="createGroupByImport"
> >
<Dragger {...props}> <Dragger {...props}>
<p className="ant-upload-drag-icon"> <p className="ant-upload-drag-icon">
<Icon type="inbox" /> <Icon type="inbox" />
</p> </p>
<p className="ant-upload-text">点击或拖拽文件到这里上传</p> <p className="ant-upload-text">点击或拖拽文件到这里上传</p>
<p className="ant-upload-hint"> <p className="ant-upload-hint">
单个文件最大150MB 单个文件最大150MB
</p> </p>
</Dragger> </Dragger>
<p className="color-red lineh-25 edu-txt-left" style={{height:"25px"}}>
<span className={ errorTip ? "" : "none" }>{errorTip}</span>
</p>
</ModalWrapper> </ModalWrapper>
) )
} }

@ -44,7 +44,9 @@ class CoursesNew extends Component {
fetching:false, fetching:false,
boolxinjian:false, boolxinjian:false,
checkboxgroup:undefined, checkboxgroup:undefined,
checkbofrup:["shixun_homework","common_homework","group_homework","exercise","attachment","course_group","graduation","poll","board"], 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:"分班"}],
checkbofrups:[], checkbofrups:[],
} }
} }
@ -78,32 +80,22 @@ class CoursesNew extends Component {
is_public: data.is_public === 1 ? true : false, is_public: data.is_public === 1 ? true : false,
Realnamecertification: data.authentication, Realnamecertification: data.authentication,
Professionalcertification:data.professional_certification, Professionalcertification:data.professional_certification,
checkbofrups:data.course_modules,
}); });
try { try {
var datasysl=[]; if(data.course_modules===undefined||data.course_modules.length===0){
var dataysl2=[]; this.setState({
var dataysl3=[]; checkbofrups:this.state.checkbofrup,
var checkbofrup =this.state.checkbofrup; });
dataysl2=data.course_module_types; }
datasysl=checkbofrup;
for (var k=0;k<datasysl.length;k++){
for (var i=0;i<data.course_module_types.length;i++){
if(datasysl[k]===data.course_module_type[i]){
datasysl.slice(k,1);
}
}
}
dataysl3 = dataysl2.concat(datasysl);
this.setState({
checkboxgroup: dataysl3,
})
}catch (e) { }catch (e) {
this.setState({ this.setState({
checkboxgroup:this.state.checkbofrup, checkbofrups:this.state.checkbofrup,
}) });
} }
this.handleSearchschool(data.school); this.handleSearchschool(data.school);
}).catch((error) => { }).catch((error) => {
console.log(error); console.log(error);
@ -450,6 +442,7 @@ class CoursesNew extends Component {
search: value search: value
} }
}).then((result)=>{ }).then((result)=>{
if(result){
if (result.data.status===0) { if (result.data.status===0) {
this.setState({ this.setState({
searchlistscholl: result.data.school_names, searchlistscholl: result.data.school_names,
@ -461,6 +454,7 @@ class CoursesNew extends Component {
}) })
} }
} }
}
}).catch((error)=>{ }).catch((error)=>{
console.log(error) console.log(error)
}) })
@ -469,7 +463,7 @@ class CoursesNew extends Component {
this.applyForAddOrgForm.setVisible(true) this.applyForAddOrgForm.setVisible(true)
} }
render() { render() {
let {datatime,school,searchlistscholl,checkboxgroup} = this.state; let {datatime,school,searchlistscholl,checkbofrups} = this.state;
const {getFieldDecorator} = this.props.form; const {getFieldDecorator} = this.props.form;
const propsWithoutForm = Object.assign({}, this.props) const propsWithoutForm = Object.assign({}, this.props)
delete propsWithoutForm.form delete propsWithoutForm.form
@ -699,27 +693,9 @@ class CoursesNew extends Component {
this.props.match.params.coursesId != undefined? this.props.match.params.coursesId != undefined?
<Checkbox.Group style={{width: "800px", marginTop: "10px"}}> <Checkbox.Group style={{width: "800px", marginTop: "10px"}}>
{ {
checkboxgroup===undefined?"":checkboxgroup.length===0?"":checkboxgroup.map((item,key)=>{ checkbofrups===undefined?"":checkbofrups.length===0?"":checkbofrups.map((item,key)=>{
return( return(
item ==="shixun_homework"? <Checkbox key={key} value={item.module_type} className="fl">{item.module_name}</Checkbox>
<Checkbox value={"shixun_homework"} className="fl">实训作业</Checkbox>
:item ==="common_homework"?
<Checkbox value={"common_homework"} className="fl">普通作业</Checkbox>
:item ==="group_homework"?
<Checkbox value={"group_homework"} className="fl">分组作业</Checkbox>
:item ==="exercise"?
<Checkbox value={"exercise"} className="fl">试卷</Checkbox>
:item ==="attachment"?
<Checkbox value={"attachment"} className="fl">资源</Checkbox>
:item ==="course_group"?
<Checkbox value={"course_group"} className="fl">分班</Checkbox>
:item ==="graduation"?
<Checkbox value={"graduation"} className="fl">毕业设计</Checkbox>
:item ==="poll"?
<Checkbox value={"poll"} className="fl">问卷</Checkbox>
:item ==="board"?
<Checkbox value={"board"} className="fl">讨论</Checkbox>
:""
) )
}) })
} }
@ -729,16 +705,13 @@ class CoursesNew extends Component {
<Checkbox value={"shixun_homework"} className="fl">实训作业</Checkbox> <Checkbox value={"shixun_homework"} className="fl">实训作业</Checkbox>
<Checkbox value={"common_homework"} className="fl">普通作业</Checkbox> <Checkbox value={"common_homework"} className="fl">普通作业</Checkbox>
<Checkbox value={"group_homework"} className="fl">分组作业</Checkbox> <Checkbox value={"group_homework"} className="fl">分组作业</Checkbox>
<Checkbox value={"exercise"} className="fl">试卷</Checkbox>
<Checkbox value={"attachment"} className="fl">资源</Checkbox>
<Checkbox value={"course_group"} className="fl">分班</Checkbox>
<Checkbox value={"graduation"} className="fl">毕业设计</Checkbox> <Checkbox value={"graduation"} className="fl">毕业设计</Checkbox>
<Checkbox value={"exercise"} className="fl">试卷</Checkbox>
<Checkbox value={"poll"} className="fl">问卷</Checkbox> <Checkbox value={"poll"} className="fl">问卷</Checkbox>
<Checkbox value={"attachment"} className="fl">资源</Checkbox>
<Checkbox value={"board"} className="fl">讨论</Checkbox> <Checkbox value={"board"} className="fl">讨论</Checkbox>
<Checkbox value={"course_group"} className="fl">分班</Checkbox>
</Checkbox.Group> </Checkbox.Group>
)} )}
</Form.Item> </Form.Item>
</div> </div>

@ -50,7 +50,12 @@ class Goldsubject extends Component {
subject_id:"", subject_id:"",
start_date:"", start_date:"",
Whethertocreateanewclassroom:true, 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:"分班"},],
checkbofrups:[],
} }
} }
// disabledEndDate= endValue => { // disabledEndDate= endValue => {
@ -139,7 +144,20 @@ class Goldsubject extends Component {
course_module_types: data.course_module_types, course_module_types: data.course_module_types,
school:data.school, school:data.school,
Whethertocreateanewclassroom:false, Whethertocreateanewclassroom:false,
checkbofrups:data.course_modules,
}); });
try {
if(data.course_modules===undefined||data.course_modules.length===0){
this.setState({
checkbofrups:this.state.checkbofrup,
});
}
}catch (e) {
this.setState({
checkbofrups:this.state.checkbofrup,
});
}
this.handleSearchschool(data.school); this.handleSearchschool(data.school);
}).catch((error) => { }).catch((error) => {
console.log(error); console.log(error);
@ -591,7 +609,7 @@ class Goldsubject extends Component {
this.applyForAddOrgForm.setVisible(true) this.applyForAddOrgForm.setVisible(true)
} }
render() { render() {
let {datatime,datatimetwo,school,searchlistscholl,Whethertocreateanewclassroom} = this.state; let {datatime,datatimetwo,school,searchlistscholl,Whethertocreateanewclassroom,checkbofrups} = this.state;
const {getFieldDecorator} = this.props.form; const {getFieldDecorator} = this.props.form;
const propsWithoutForm = Object.assign({}, this.props) const propsWithoutForm = Object.assign({}, this.props)
delete propsWithoutForm.form delete propsWithoutForm.form
@ -860,6 +878,25 @@ class Goldsubject extends Component {
"announcement","online_learning","shixun_homework","common_homework", "announcement","online_learning","shixun_homework","common_homework",
], ],
})( })(
this.props.match.params.coursesId != undefined?
<Checkbox.Group style={{width: "800px", marginTop: "10px"}}>
{
checkbofrups===undefined?"":checkbofrups.length===0?"":checkbofrups.map((item,key)=>{
return(
item.module_type==="announcement"?
<Checkbox value={"announcement"} className="fl" defaultChecked disabled>公告栏</Checkbox>
:
item.module_type==="online_learning"?
<Checkbox value={"online_learning"} className="fl" defaultChecked disabled>在线学习</Checkbox>
:
item.module_type==="graduation"?"":
item.module_type==="group_homework"?"":
<Checkbox key={key} value={item.module_type} className="fl">{item.module_name}</Checkbox>
)
})
}
</Checkbox.Group>
:
<Checkbox.Group style={{width: "800px", marginTop: "10px"}}> <Checkbox.Group style={{width: "800px", marginTop: "10px"}}>
<Checkbox value={"announcement"} className="fl" defaultChecked disabled>公告栏</Checkbox> <Checkbox value={"announcement"} className="fl" defaultChecked disabled>公告栏</Checkbox>
<Checkbox value={"online_learning"} className="fl" defaultChecked disabled>在线学习</Checkbox> <Checkbox value={"online_learning"} className="fl" defaultChecked disabled>在线学习</Checkbox>

@ -288,6 +288,7 @@ class Poll extends Component{
}) })
let{type,StudentList_value}=this.state let{type,StudentList_value}=this.state
this.InitList(type,StudentList_value,1); this.InitList(type,StudentList_value,1);
this.props.updataleftNavfun();
} }
}).catch((error)=>{ }).catch((error)=>{
console.log(error); console.log(error);
@ -595,7 +596,7 @@ class Poll extends Component{
{...this.state} {...this.state}
courseType={course_types} courseType={course_types}
item={item} item={item}
key={key} index={key}
onItemClick={this.onItemClick} onItemClick={this.onItemClick}
checkBox={<Checkbox value={item.id} key={item.id} onClick={() => this.onItemClick(item)}></Checkbox>} checkBox={<Checkbox value={item.id} key={item.id} onClick={() => this.onItemClick(item)}></Checkbox>}
></PollListItem> ></PollListItem>

@ -16,7 +16,7 @@ class PollListItem extends Component{
super(props); super(props);
} }
render(){ render(){
let{item,checkBox,courseType}=this.props; let{item,checkBox,courseType,index}=this.props;
let {coursesId}=this.props.match.params; let {coursesId}=this.props.match.params;
const IsAdmin =this.props.isAdmin(); const IsAdmin =this.props.isAdmin();
@ -28,10 +28,10 @@ class PollListItem extends Component{
let canNotLink = !isAdminOrStudent && item.lock_status == 0 let canNotLink = !isAdminOrStudent && item.lock_status == 0
return( return(
<div className="workList_Item polllisthover" style={{padding:"30px"}} onClick={() => this.props.onItemClick(this.props.item)}> <div className="workList_Item polllisthover" style={{cursor : IsAdmin ? "pointer" : "default",padding:"30px" }} onClick={() => this.props.onItemClick(this.props.item)}>
{ {
IsAdmin && IsAdmin &&
<span className="fl mr12"> <span className={`pollitem${index} fl mr12`}>
{checkBox} {checkBox}
</span> </span>
} }

@ -2529,14 +2529,24 @@ class PollNew extends Component {
</div> </div>
{/*suffix={String(addonAfter)}*/} {/*suffix={String(addonAfter)}*/}
<style>
{
`
.yslpollls .ant-input{
border-right: none !important;
height: 40px !important;
}
`
}
</style>
<Input placeholder="请输入问卷标题最大限制60个字符" maxLength="60" <Input placeholder="请输入问卷标题最大限制60个字符" maxLength="60"
style={{"margin-top": "15px", "text-align": "left"}} style={{"margin-top": "15px", "text-align": "left"}}
onInput={this.changeTopicName} onInput={this.changeTopicName}
readOnly={readOnlys} readOnly={readOnlys}
autoComplete="off" autoComplete="off"
suffix={String(addonAfter)+"/60"} addonAfter={String(addonAfter)+"/60"}
value={this.state.polls_nametest} value={this.state.polls_nametest}
className="searchViewAfter"></Input> className="searchViewAfter yslpollls"></Input>
</div> </div>
<div style={{ <div style={{

@ -124,13 +124,19 @@ class ShixunhomeWorkItem extends Component{
}) })
} }
editname = (name,id) => { // 实训详情,阻止冒泡
stopPro = (event) => {
event.stopPropagation()
}
editname = (name,id,event) => {
this.setState({ this.setState({
ModalsRenametype:true, ModalsRenametype:true,
NavmodalValue:name, NavmodalValue:name,
Navmodalname:"重命名", Navmodalname:"重命名",
url:`/homework_commons/${id}/alter_name.json` url:`/homework_commons/${id}/alter_name.json`
}) })
event.stopPropagation()
} }
cannerNavmoda=()=>{ cannerNavmoda=()=>{
this.setState({ this.setState({
@ -157,88 +163,74 @@ class ShixunhomeWorkItem extends Component{
const { checkBox, const { checkBox,
discussMessage, discussMessage,
taskid, taskid,index
} = this.props; } = this.props;
//
// allow_late: true //是否开启补交
// homework_id: 9250
// shixun_identifier: "25ykhpvl"
//
// console.log("this.props.isAdmin");
return( return(
<div className="graduateTopicList boardsList"> <React.Fragment>
{this.state.ModalsRenametype===true? {
<ModalsRename this.state.ModalsRenametype===true?
{...this.props} <ModalsRename
Navmodalnametype={this.state.ModalsRenametype} {...this.props}
NavmodalValue={this.state.NavmodalValue} Navmodalnametype={this.state.ModalsRenametype}
Navmodalname={this.state.Navmodalname} NavmodalValue={this.state.NavmodalValue}
Navname={"作业"} Navmodalname={this.state.Navmodalname}
url={this.state.url} Navname={"作业"}
cannerNavmoda={()=>this.cannerNavmoda()} url={this.state.url}
/> cannerNavmoda={()=>this.cannerNavmoda()}
:""} />
:""}
<Modals <Modals
modalsType={Modalstype} modalsType={Modalstype}
modalsTopval={Modalstopval} modalsTopval={Modalstopval}
modalsBottomval={Modalsbottomval} modalsBottomval={Modalsbottomval}
modalCancel={cardsModalcancel} modalCancel={cardsModalcancel}
modalSave={cardsModalsavetype} modalSave={cardsModalsavetype}
loadtype={loadtype} loadtype={loadtype}
/> />
{visible===true?<Associationmodel
{visible===true?<Associationmodel modalname={modalname}
modalname={modalname} visible={visible}
visible={visible} Cancel={this.Cancel}
Cancel={this.Cancel} taskid={taskid}
taskid={taskid} funlist={this.props.funlist}
funlist={this.props.funlist} />:""}
/>:""} <Modal
keyboard={false}
title="提示"
<Modal visible={shixunsreplace}
keyboard={false} closable={false}
title="提示" footer={null}
visible={shixunsreplace} >
closable={false} <div className="task-popup-content">
footer={null} <p className="task-popup-text-center font-16 pb20">实训已经更新了正在为您重置!</p>
> </div>
<div className="task-popup-content"> <div className="task-popup-submit clearfix">
<p className="task-popup-text-center font-16 pb20">实训已经更新了正在为您重置!</p> <a className="task-btn task-btn-orange fr mr51"
</div> onClick={() => this.hidestartshixunsreplace(hidestartshixunsreplacevalue)}>知道了</a>
<div className="task-popup-submit clearfix"> </div>
<a className="task-btn task-btn-orange fr mr51" </Modal>
onClick={() => this.hidestartshixunsreplace(hidestartshixunsreplacevalue)}>知道了</a>
</div> <Modal
</Modal> keyboard={false}
<Modal title="提示"
keyboard={false} visible={startshixunCombattype}
title="提示" closable={false}
visible={startshixunCombattype} footer={null}
closable={false} >
footer={null} <div className="task-popup-content">
> <p className="task-popup-text-center font-16 pb20">本实训的开启时间{shixunsmessage} <br/>开启时间之前不能挑战
<div className="task-popup-content"> </p>
<p className="task-popup-text-center font-16 pb20">本实训的开启时间{shixunsmessage} <br/>开启时间之前不能挑战 </div>
</p> <div className="task-popup-submit clearfix">
</div> {/*<a onClick={this.hidestartshixunCombattype} className="task-btn fl">取消</a>*/}
<div className="task-popup-submit clearfix"> <a className="task-btn task-btn-orange fr mr51" onClick={this.hidestartshixunCombattype}>知道啦</a>
{/*<a onClick={this.hidestartshixunCombattype} className="task-btn fl">取消</a>*/} </div>
<a className="task-btn task-btn-orange fr mr51" onClick={this.hidestartshixunCombattype}>知道啦</a> {/*<p className="inviteTipbtn with100 fl">*/}
</div> {/*<a onClick={this.hidestartshixunCombattype}>知道了</a>*/}
{/*<p className="inviteTipbtn with100 fl">*/} {/*</p>*/}
{/*<a onClick={this.hidestartshixunCombattype}>知道了</a>*/} </Modal>
{/*</p>*/}
</Modal>
<div className="graduateTopicList boardsList" style={{cursor : this.props.isAdmin ? "pointer" : "default"}} onClick={() => window.$(`.shixunitem${index} input`).click() } >
<style>{` <style>{`
.boardsList .ant-checkbox-wrapper{ .boardsList .ant-checkbox-wrapper{
margin-top: -35px; margin-top: -35px;
@ -284,7 +276,11 @@ class ShixunhomeWorkItem extends Component{
`}</style> `}</style>
{this.props.isAdmin?checkBox:""} {this.props.isAdmin?
<span className={`shixunitem${index} fl`} style={{"height":"55px"}}>{checkBox}</span>
:
""
}
<div className="clearfix ds pr pt5 contentSection" > <div className="clearfix ds pr pt5 contentSection" >
<style>{` <style>{`
@ -299,23 +295,23 @@ class ShixunhomeWorkItem extends Component{
{/*to={`/courses/${this.props.match.params.coursesId}/${discussMessage.homework_id}/jobsettings`}*/} {/*to={`/courses/${this.props.match.params.coursesId}/${discussMessage.homework_id}/jobsettings`}*/}
{ {
this.props.isAdmin?<a href={"/courses/"+this.props.match.params.coursesId+"/"+this.state.shixuntypes+"/"+discussMessage.homework_id+"/list?tab=0"} this.props.isAdmin?<Link to={"/courses/"+this.props.match.params.coursesId+"/"+this.state.shixuntypes+"/"+discussMessage.homework_id+"/list?tab=0"}
title={discussMessage.name} title={discussMessage.name}
className="fl mt3 font-16 font-bd color-dark maxwidth580">{discussMessage.name}</a>:"" className="fl mt3 font-16 font-bd color-dark maxwidth580">{discussMessage.name}</Link>:""
} }
{ {
this.props.isStudent? <a href={`/courses/${this.props.match.params.coursesId}/${this.state.shixuntypes}/${discussMessage.homework_id}/list?tab=0`} this.props.isStudent? <Link to={`/courses/${this.props.match.params.coursesId}/${this.state.shixuntypes}/${discussMessage.homework_id}/list?tab=0`}
title={discussMessage.name} title={discussMessage.name}
className="fl mt3 font-16 font-bd color-dark maxwidth580">{discussMessage.name}</a>:"" className="fl mt3 font-16 font-bd color-dark maxwidth580">{discussMessage.name}</Link>:""
} }
{ {
this.props.isNotMember===true? this.props.discussMessage.private_icon===true? this.props.isNotMember===true? this.props.discussMessage.private_icon===true?
<span className="fl mt3 font-16 font-bd color-dark maxwidth580" title={discussMessage.name}>{discussMessage.name}</span> <span className="fl mt3 font-16 font-bd color-dark maxwidth580" title={discussMessage.name}>{discussMessage.name}</span>
: <a href={`/courses/${this.props.match.params.coursesId}/${this.state.shixuntypes}/${discussMessage.homework_id}/list?tab=0`} : <Link to={`/courses/${this.props.match.params.coursesId}/${this.state.shixuntypes}/${discussMessage.homework_id}/list?tab=0`}
title={discussMessage.name} title={discussMessage.name}
className="fl mt3 font-16 font-bd color-dark maxwidth580">{discussMessage.name}</a>:"" className="fl mt3 font-16 font-bd color-dark maxwidth580">{discussMessage.name}</Link>:""
} }
@ -383,9 +379,9 @@ class ShixunhomeWorkItem extends Component{
` `
} }
</style> </style>
{this.props.isAdmin?<div className={this.props.isAdminOrCreator()?"homepagePostSetting homepagePostSettingname":"homepagePostSetting homepagePostSettingbox"} style={{"right":"-2px","top":"44px","display":"block"}}> {this.props.isAdmin?<div onClick={(event)=>this.stopPro(event)} className={this.props.isAdminOrCreator()?"homepagePostSetting homepagePostSettingname":"homepagePostSetting homepagePostSettingbox"} style={{"right":"-2px","top":"44px","display":"block"}}>
<a className="btn colorblue font-16" href={"/shixuns/"+discussMessage.shixun_identifier+"/challenges"} target={"_blank"}>实训详情</a> <Link className="btn colorblue font-16" to={"/shixuns/"+discussMessage.shixun_identifier+"/challenges"} target={"_blank"}>实训详情</Link>
{this.props.isAdminOrCreator()?<a onClick={()=>this.editname(discussMessage.name,discussMessage.homework_id)} className={"btn colorblue ml20 font-16"}>重命名</a>:""} {this.props.isAdminOrCreator()?<a onClick={(event)=>this.editname(discussMessage.name,discussMessage.homework_id,event)} className={"btn colorblue ml20 font-16"}>重命名</a>:""}
{/*<WordsBtn className="btn colorblue ml20 font-16" to={`/courses/${this.props.match.params.coursesId}/${this.state.shixuntypes}/${discussMessage.homework_id}/settings?tab=3`} > 设置</WordsBtn>*/} {/*<WordsBtn className="btn colorblue ml20 font-16" to={`/courses/${this.props.match.params.coursesId}/${this.state.shixuntypes}/${discussMessage.homework_id}/settings?tab=3`} > 设置</WordsBtn>*/}
<WordsBtn className="btn colorblue font-16 ml15" to={`/courses/${this.props.match.params.coursesId}/${this.state.shixuntypes}/${discussMessage.homework_id}/settings?tab=3`} > 设置</WordsBtn> <WordsBtn className="btn colorblue font-16 ml15" to={`/courses/${this.props.match.params.coursesId}/${this.state.shixuntypes}/${discussMessage.homework_id}/settings?tab=3`} > 设置</WordsBtn>
</div>:""} </div>:""}
@ -408,6 +404,7 @@ class ShixunhomeWorkItem extends Component{
</div> </div>
</div> </div>
</React.Fragment>
) )
} }
} }

@ -587,6 +587,8 @@ class ShixunHomework extends Component{
let {Coursename,page}=this.state; let {Coursename,page}=this.state;
this.setState({ this.setState({
order: e.key, order: e.key,
checkBoxValues:[],
checkedtype:false,
isSpin:true isSpin:true
}); });
let newkey=e.key; let newkey=e.key;
@ -1029,8 +1031,8 @@ class ShixunHomework extends Component{
<div className="edu-back-white"> <div className="edu-back-white">
<p className="clearfix padding30 bor-bottom-greyE"> <p className="clearfix padding30 bor-bottom-greyE">
<p style={{height: '20px'}}> <p style={{height: '20px'}}>
<span className="font-18 fl color-dark-21">{datas&&datas.category_name===undefined||datas&&datas.category_name===null?datas&&datas.main_category_name:datas&&datas.category_name+" 作业列表"}</span> {/*<span className="font-18 fl color-dark-21">{datas&&datas.category_name===undefined||datas&&datas.category_name===null?datas&&datas.main_category_name:datas&&datas.category_name+" 作业列表"}</span>*/}
{/* <span className="font-18 fl color-dark-21">实训作业</span>*/} <span className="font-18 fl color-dark-21">实训作业</span>
<li className="fr"> <li className="fr">
{this.props.isAdmin()===true?datas&&datas.category_name===undefined||datas&&datas.category_name===null? {this.props.isAdmin()===true?datas&&datas.category_name===undefined||datas&&datas.category_name===null?
<span> <span>
@ -1175,6 +1177,7 @@ class ShixunHomework extends Component{
isClassManagement={this.props.isClassManagement()} isClassManagement={this.props.isClassManagement()}
checkBox={this.props.isAdmin()?<Checkbox value={item.homework_id} key={item.homework_id}></Checkbox>:""} checkBox={this.props.isAdmin()?<Checkbox value={item.homework_id} key={item.homework_id}></Checkbox>:""}
match={this.props.match} match={this.props.match}
index={index}
coursedata={this.props.coursedata} coursedata={this.props.coursedata}
coursupdata={()=>this.homeworkupdatalist(Coursename,page,order)} coursupdata={()=>this.homeworkupdatalist(Coursename,page,order)}
course_identity={datas.course_identity} course_identity={datas.course_identity}

@ -224,12 +224,15 @@ class MainContentContainer extends Component {
} }
componentDidUpdate(prevProps, prevState, snapshot) { componentDidUpdate(prevProps, prevState, snapshot) {
const { game } = this.props const { game, challenge } = this.props
if (game && prevProps.game if (game && prevProps.game
&& prevProps.game.identifier !== game.identifier) { && prevProps.game.identifier !== game.identifier) {
// 切换关卡时,停止轮训 // 切换关卡时,停止轮训
this.oldGameIdentifier = prevProps.game.identifier; this.oldGameIdentifier = prevProps.game.identifier;
this.doFileUpdateRequestOnCodeMirrorBlur(prevProps)
} else if (challenge && (challenge.pathIndex || prevProps.challenge.pathIndex) && challenge.pathIndex != prevProps.challenge.pathIndex) {
this.doFileUpdateRequestOnCodeMirrorBlur(prevProps)
} }
} }
@ -386,8 +389,8 @@ class MainContentContainer extends Component {
} }
doFileUpdateRequestOnCodeMirrorBlur = () => { doFileUpdateRequestOnCodeMirrorBlur = (props) => {
var fileUpdatePromise = this.doFileUpdateRequest(true) var fileUpdatePromise = this.doFileUpdateRequest(true, undefined, props)
if (fileUpdatePromise) { if (fileUpdatePromise) {
fileUpdatePromise.then((resData) => { fileUpdatePromise.then((resData) => {
if (resData.status === -1) { // 保存文件出现异常 if (resData.status === -1) { // 保存文件出现异常
@ -496,7 +499,8 @@ class MainContentContainer extends Component {
} }
// forTest true 是评测时触发的file_update // forTest true 是评测时触发的file_update
doFileUpdateRequest(checkIfCodeChanged, forTest) { doFileUpdateRequest(checkIfCodeChanged, forTest, props) {
const _props = props || this.props;
const { codeStatus } = this.state; const { codeStatus } = this.state;
if (!forTest && codeStatus !== UPDATED) { // 已修改状态才能保存 if (!forTest && codeStatus !== UPDATED) { // 已修改状态才能保存
return; return;
@ -521,7 +525,7 @@ class MainContentContainer extends Component {
}) })
return null; return null;
} }
const { challenge, output_sets, onRunCodeTestFinish, myshixun } = this.props const { challenge, output_sets, onRunCodeTestFinish, myshixun } = _props
// var url = `${locationPath}/file_update?path=${encodeURIComponent(challenge.path)}` // var url = `${locationPath}/file_update?path=${encodeURIComponent(challenge.path)}`
var url = `/myshixuns/${myshixun.identifier}/update_file.json` var url = `/myshixuns/${myshixun.identifier}/update_file.json`

@ -37,6 +37,8 @@ export function ImageLayerOfCommentHOC(options = {}) {
} }
// jQuery._data( $('.newMain')[0], "events" ) // jQuery._data( $('.newMain')[0], "events" )
componentDidMount() { componentDidMount() {
this.props.wrappedComponentRef && this.props.wrappedComponentRef(this.refs['wrappedComponentRef'])
// commentsDelegateParent #game_left_contents #tab_con_4 // commentsDelegateParent #game_left_contents #tab_con_4
setTimeout(() => { setTimeout(() => {
$(options.parentSelector || ".commentsDelegateParent") $(options.parentSelector || ".commentsDelegateParent")
@ -60,7 +62,7 @@ export function ImageLayerOfCommentHOC(options = {}) {
<React.Fragment> <React.Fragment>
<ImageLayer {...this.state} onImageLayerClose={this.onImageLayerClose}></ImageLayer> <ImageLayer {...this.state} onImageLayerClose={this.onImageLayerClose}></ImageLayer>
<WrappedComponent {...this.props} > <WrappedComponent {...this.props} ref="wrappedComponentRef">
</WrappedComponent> </WrappedComponent>
</React.Fragment> </React.Fragment>
) )

@ -1,45 +1,45 @@
.ml350 { .ml350 {
margin-left: 40%; margin-left: 40%;
} }
.ml32 { .ml32 {
margin-left: 32%; margin-left: 32%;
} }
.square-Item{ .square-Item{
/*min-height: 324px;*/ /*min-height: 324px;*/
} }
.square-img{ .square-img{
min-height: 210px; min-height: 210px;
} }
.task-hide{ .task-hide{
margin-bottom: 0em; margin-bottom: 0em;
} }
.backFAFAFA{ .backFAFAFA{
background:#FAFAFA; background:#FAFAFA;
} }
.demo { .demo {
width: 500px; width: 500px;
background-color: #0dcecb; background-color: #0dcecb;
text-align: center; text-align: center;
padding:50px; padding:50px;
} }
.next-loading { .next-loading {
margin-bottom: 5px; margin-bottom: 5px;
width:100%; width:100%;
} }
.next-rating-overlay .next-icon{ .next-rating-overlay .next-icon{
color: #FFA800!important; color: #FFA800!important;
} }
.custom-pagination { .custom-pagination {
display: inline-block; display: inline-block;
margin-left: 10px; margin-left: 10px;
} }
.ml425{ .ml425{
margin-left:42.5%; margin-left:42.5%;
margin-top:20px; margin-top:20px;
} }

@ -1103,6 +1103,10 @@ class LoginRegisterComponent extends Component {
right: 12px; right: 12px;
height: 20px; height: 20px;
} }
.ant-input{
border-right: none !important;
height: 40px !important;
}
` `
} }
</style> </style>
@ -1112,7 +1116,7 @@ class LoginRegisterComponent extends Component {
autoComplete="new-password" autoComplete="new-password"
onClick={this.changeType} onClick={this.changeType}
value={this.state.passwords} onChange={this.passwordonChanges} value={this.state.passwords} onChange={this.passwordonChanges}
suffix={ addonAfter={
<img className={"mt5"} src={passopens} onClick={(key) => this.Showandhide(key)}> <img className={"mt5"} src={passopens} onClick={(key) => this.Showandhide(key)}>
</img> </img>
}></Input> }></Input>

@ -492,7 +492,17 @@ class AccountBasic extends Component {
} }
`}</style> `}</style>
<div className="title">基本信息</div> <div className="title">基本信息</div>
<style>
{
`
.exercicenewinputysl .ant-input{
border-right: none !important;
height: 40px !important;
}
`
}
</style>
<Form onSubmit={this.handleSubmit}> <Form onSubmit={this.handleSubmit}>
<Form.Item <Form.Item
label="昵称" label="昵称"
@ -505,12 +515,22 @@ class AccountBasic extends Component {
message: '请输入您的昵称', message: '请输入您的昵称',
}], }],
})( })(
<Input placeholder={`请输入您的昵称,最大限制${MAX_NICKNAME_LENGTH}个字符`} onInput={this.changeNickName} maxLength={MAX_NICKNAME_LENGTH} suffix ={ <Input placeholder={`请输入您的昵称,最大限制${MAX_NICKNAME_LENGTH}个字符`} className="exercicenewinputysl" onInput={this.changeNickName} maxLength={MAX_NICKNAME_LENGTH} addonAfter ={
<span className="color-grey-6 font-13">{String(nameLength)}/{MAX_NICKNAME_LENGTH}</span> <span className="color-grey-6 font-13">{String(nameLength)}/{MAX_NICKNAME_LENGTH}</span>
}></Input> }></Input>
)} )}
</Form.Item> </Form.Item>
<style>
{
`
.yslgraduainputedit .ant-input{
border-right: none !important;
height: 40px !important;
}
`
}
</style>
<Form.Item <Form.Item
label="姓名" label="姓名"
className="formItemInline" className="formItemInline"
@ -523,7 +543,7 @@ class AccountBasic extends Component {
validator: this.checkNameLength validator: this.checkNameLength
}], }],
})( })(
<Input placeholder={`请输入真实姓名,最大限制${MAX_NAME_LENGTH}个字符`} disabled={!showRealName && this.state.forDisable == true } suffix={ <Input placeholder={`请输入真实姓名,最大限制${MAX_NAME_LENGTH}个字符`} className="yslgraduainputedit" disabled={!showRealName && this.state.forDisable == true } addonAfter={
<i className={showRealName?"iconfont icon-xianshi font-18 color-blue":"iconfont icon-yincang font-18 color-blue"} <i className={showRealName?"iconfont icon-xianshi font-18 color-blue":"iconfont icon-yincang font-18 color-blue"}
onClick={()=>this.showOrHide(showRealName)}></i> onClick={()=>this.showOrHide(showRealName)}></i>
}></Input> }></Input>

@ -1,249 +1,249 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import {Pagination,Spin,Checkbox,Modal} from 'antd'; import {Pagination,Spin,Checkbox,Modal} from 'antd';
import moment from 'moment'; import moment from 'moment';
import axios from 'axios'; import axios from 'axios';
import NoneData from '../../courses/coursesPublic/NoneData' import NoneData from '../../courses/coursesPublic/NoneData'
import {getImageUrl} from 'educoder'; import {getImageUrl} from 'educoder';
import "./usersInfo.css" import "./usersInfo.css"
import Modals from '../../modals/Modals' import Modals from '../../modals/Modals'
const dateFormat ="YYYY-MM-DD HH:mm" const dateFormat ="YYYY-MM-DD HH:mm"
class InfosBank extends Component{ class InfosBank extends Component{
constructor(props){ constructor(props){
super(props); super(props);
this.state={ this.state={
category:"common", category:"common",
type:"publicly", type:"publicly",
page:1, page:1,
per_page:16, per_page:16,
sort_by:"updated_at", sort_by:"updated_at",
CoursesId:undefined, CoursesId:undefined,
totalCount:undefined, totalCount:undefined,
data:undefined, data:undefined,
isSpin:false, isSpin:false,
dialogOpen:false, dialogOpen:false,
modalsTopval:undefined, modalsTopval:undefined,
modalsBottomval:undefined, modalsBottomval:undefined,
modalSave:undefined modalSave:undefined
} }
} }
componentDidMount=()=>{ componentDidMount=()=>{
this.setState({ this.setState({
isSpin:true isSpin:true
}) })
let{category,type,page,sort_by,CoursesId}=this.state; let{category,type,page,sort_by,CoursesId}=this.state;
this.getCourses(category,type,page,sort_by,CoursesId); this.getCourses(category,type,page,sort_by,CoursesId);
} }
getCourses=(category,type,page,sort_by,CoursesId)=>{ getCourses=(category,type,page,sort_by,CoursesId)=>{
let url=`/users/${this.props.match.params.username}/question_banks.json`; let url=`/users/${this.props.match.params.username}/question_banks.json`;
axios.get((url),{params:{ axios.get((url),{params:{
category, category,
type, type,
page, page,
sort_by, sort_by,
per_page:category && page ==1?17:16, per_page:category && page ==1?17:16,
course_list_id:CoursesId course_list_id:CoursesId
}}).then((result)=>{ }}).then((result)=>{
if(result){ if(result){
this.setState({ this.setState({
totalCount:result.data.count, totalCount:result.data.count,
data:result.data, data:result.data,
isSpin:false isSpin:false
}) })
} }
}).catch((error)=>{ }).catch((error)=>{
console.log(error); console.log(error);
}) })
} }
//切换种类 //切换种类
changeCategory=(cate)=>{ changeCategory=(cate)=>{
this.setState({ this.setState({
category:cate, category:cate,
page:1, page:1,
isSpin:true isSpin:true
}) })
let{type,sort_by,CoursesId}=this.state; let{type,sort_by,CoursesId}=this.state;
this.getCourses(cate,type,1,sort_by,CoursesId); this.getCourses(cate,type,1,sort_by,CoursesId);
} }
//切换状态 //切换状态
changeType=(type)=>{ changeType=(type)=>{
this.setState({ this.setState({
type:type, type:type,
page:1, page:1,
isSpin:true isSpin:true
}) })
let{category,sort_by,CoursesId}=this.state; let{category,sort_by,CoursesId}=this.state;
this.getCourses(category,type,1,sort_by,CoursesId); this.getCourses(category,type,1,sort_by,CoursesId);
} }
//切换页数 //切换页数
changePage=(page)=>{ changePage=(page)=>{
this.setState({ this.setState({
page, page,
isSpin:true isSpin:true
}) })
let{category,type,sort_by,CoursesId}=this.state; let{category,type,sort_by,CoursesId}=this.state;
this.getCourses(category,type,page,sort_by,CoursesId); this.getCourses(category,type,page,sort_by,CoursesId);
} }
// 进入课堂 // 进入课堂
turnToCourses=(url)=>{ turnToCourses=(url)=>{
this.props.history.push(url); this.props.history.push(url);
} }
// 切换排序方式 // 切换排序方式
changeOrder= (sort)=>{ changeOrder= (sort)=>{
this.setState({ this.setState({
sort_by:sort, sort_by:sort,
isSpin:true isSpin:true
}) })
let{category,type,page,CoursesId}=this.state; let{category,type,page,CoursesId}=this.state;
this.getCourses(category,type,page,sort,CoursesId); this.getCourses(category,type,page,sort,CoursesId);
} }
changeCourseListId =(CoursesId)=>{ changeCourseListId =(CoursesId)=>{
this.setState({ this.setState({
CoursesId, CoursesId,
isSpin:true isSpin:true
}) })
let{category,type,sort,page}=this.state; let{category,type,sort,page}=this.state;
this.getCourses(category,type,page,sort,CoursesId); this.getCourses(category,type,page,sort,CoursesId);
} }
//设为公开/删除 //设为公开/删除
setPublic=(index)=>{ setPublic=(index)=>{
this.setState({ this.setState({
dialogOpen:true, dialogOpen:true,
modalsTopval:index==1?"您确定要公开吗?":"确定要删除该题吗?", modalsTopval:index==1?"您确定要公开吗?":"确定要删除该题吗?",
modalsBottomval:index==1?"公开后不能重设为私有":"", modalsBottomval:index==1?"公开后不能重设为私有":"",
modalSave:()=>this.sureOperation(index) modalSave:()=>this.sureOperation(index)
}) })
} }
// 确定--设为公开/删除 // 确定--设为公开/删除
sureOperation=()=>{ sureOperation=()=>{
} }
//弹框隐藏 //弹框隐藏
handleDialogClose=()=>{ handleDialogClose=()=>{
this.setState({ this.setState({
dialogOpen:false dialogOpen:false
}) })
} }
render(){ render(){
let{ let{
category, category,
type, type,
page, page,
data, data,
totalCount, totalCount,
sort_by, sort_by,
isSpin, isSpin,
CoursesId, CoursesId,
dialogOpen, dialogOpen,
modalsTopval, modalsTopval,
modalsBottomval,modalSave modalsBottomval,modalSave
} = this.state; } = this.state;
let isStudent = this.props.isStudent(); let isStudent = this.props.isStudent();
let is_current=this.props.is_current; let is_current=this.props.is_current;
return( return(
<div className="educontent"> <div className="educontent">
<Modals <Modals
modalsType={dialogOpen} modalsType={dialogOpen}
modalsTopval={modalsTopval} modalsTopval={modalsTopval}
modalsBottomval={modalsBottomval} modalsBottomval={modalsBottomval}
modalCancel={this.handleDialogClose} modalCancel={this.handleDialogClose}
modalSave={modalSave} modalSave={modalSave}
></Modals> ></Modals>
<Spin size="large" spinning={isSpin}> <Spin size="large" spinning={isSpin}>
<div className="white-panel edu-back-white pt20 pb20 clearfix "> <div className="white-panel edu-back-white pt20 pb20 clearfix ">
<li className={type=="publicly" ? "active" : ""}><a href="javascript:void(0)" onClick={()=>this.changeType("publicly")}>{is_current ? "我":"TA"}的题库</a></li> <li className={type=="publicly" ? "active" : ""}><a href="javascript:void(0)" onClick={()=>this.changeType("publicly")}>{is_current ? "我":"TA"}的题库</a></li>
<li className={type=="personal" ? "active" : ""}><a href="javascript:void(0)" onClick={()=>this.changeType("personal")}>公共题库</a></li> <li className={type=="personal" ? "active" : ""}><a href="javascript:void(0)" onClick={()=>this.changeType("personal")}>公共题库</a></li>
</div> </div>
<div className="edu-back-white padding20-30 bor-top-greyE"> <div className="edu-back-white padding20-30 bor-top-greyE">
<ul className="clearfix secondNav"> <ul className="clearfix secondNav">
<li className={category=="common" ? "active" : ""}><a href="javascript:void(0)" onClick={()=>this.changeCategory("common")}>普通作业</a></li> <li className={category=="common" ? "active" : ""}><a href="javascript:void(0)" onClick={()=>this.changeCategory("common")}>普通作业</a></li>
<li className={category=="group" ? "active" : ""}><a href="javascript:void(0)" onClick={()=>this.changeCategory("group")}>分组作业</a></li> <li className={category=="group" ? "active" : ""}><a href="javascript:void(0)" onClick={()=>this.changeCategory("group")}>分组作业</a></li>
<li className={category=="exercise" ? "active" : ""}><a href="javascript:void(0)" onClick={()=>this.changeCategory("exercise")}>试卷</a></li> <li className={category=="exercise" ? "active" : ""}><a href="javascript:void(0)" onClick={()=>this.changeCategory("exercise")}>试卷</a></li>
<li className={category=="poll" ? "active" : ""}><a href="javascript:void(0)" onClick={()=>this.changeCategory("poll")}>问卷</a></li> <li className={category=="poll" ? "active" : ""}><a href="javascript:void(0)" onClick={()=>this.changeCategory("poll")}>问卷</a></li>
</ul> </ul>
<div className="edu-txt-left mt10 bankTag"> <div className="edu-txt-left mt10 bankTag">
<ul className="inline" id="sourceTag"> <ul className="inline" id="sourceTag">
<li className={ CoursesId ? "" : "active" } onClick={()=>this.changeCourseListId()}> <li className={ CoursesId ? "" : "active" } onClick={()=>this.changeCourseListId()}>
<a href="javascript:void(0)">全部</a> <a href="javascript:void(0)">全部</a>
</li> </li>
{ {
data && data.course_list && data.course_list.map((item,key)=>{ data && data.course_list && data.course_list.map((item,key)=>{
return( return(
<li className={CoursesId==item.id?"active":""} key={key} onClick={()=>this.changeCourseListId(`${item.id}`)}> <li className={CoursesId==item.id?"active":""} key={key} onClick={()=>this.changeCourseListId(`${item.id}`)}>
<a href="javascript:void(0)">{item.name}</a> <a href="javascript:void(0)">{item.name}</a>
</li> </li>
) )
}) })
} }
</ul> </ul>
</div> </div>
</div> </div>
<p className="pl25 pr25 clearfix font-12 mb20 mt20"> <p className="pl25 pr25 clearfix font-12 mb20 mt20">
<span className="fl color-grey-9">共参与{totalCount}个题库</span> <span className="fl color-grey-9">共参与{totalCount}个题库</span>
<div className="fr"> <div className="fr">
<li className="drop_down"> <li className="drop_down">
<span className="color-grey-9 font-12">{sort_by=="updated_at"?"时间最新":sort_by=="name"?"作业名称":"贡献者"}</span><i className="iconfont icon-xiajiantou font-12 ml2 color-grey-6"></i> <span className="color-grey-9 font-12">{sort_by=="updated_at"?"时间最新":sort_by=="name"?"作业名称":"贡献者"}</span><i className="iconfont icon-xiajiantou font-12 ml2 color-grey-6"></i>
<ul className="drop_down_normal"> <ul className="drop_down_normal">
<li onClick={()=>this.changeOrder("updated_at")}>时间最新</li> <li onClick={()=>this.changeOrder("updated_at")}>时间最新</li>
<li onClick={()=>this.changeOrder("name")}>作业名称</li> <li onClick={()=>this.changeOrder("name")}>作业名称</li>
<li onClick={()=>this.changeOrder("contributor")}>贡献者</li> <li onClick={()=>this.changeOrder("contributor")}>贡献者</li>
</ul> </ul>
</li> </li>
</div> </div>
</p> </p>
<div className="dataBank_list edu-back-white educontent"> <div className="dataBank_list edu-back-white educontent">
{ {
!data || data.question_banks.length==0 && <NoneData></NoneData> !data || data.question_banks.length==0 && <NoneData></NoneData>
} }
{ {
data && data.question_banks && data.question_banks.map((item,key)=>{ data && data.question_banks && data.question_banks.map((item,key)=>{
return( return(
<div className="dataBank_Item clearfix" key={key}> <div className="dataBank_Item clearfix" key={key}>
<div className="fl dataItemLeft"> <div className="fl dataItemLeft">
<Checkbox value={item.id} key={item.id}></Checkbox> <Checkbox value={item.id} key={item.id}></Checkbox>
</div> </div>
<div className="fr dataItemRight bank_item"> <div className="fr dataItemRight bank_item">
<p className="mb10 clearfix"> <p className="mb10 clearfix">
<span className="dataTitle fl mr80">{item.name}</span> <span className="dataTitle fl mr80">{item.name}</span>
<a href="javascript:void(0)" data-object="2599" className="bank_send fr">发送</a> <a href="javascript:void(0)" data-object="2599" className="bank_send fr">发送</a>
{ {
item.is_public ==false ? item.is_public ==false ?
<a href="javascript:void(0)" onClick={()=>this.setPublic(1)} className="bank_public color-blue_4C fr mr60">设为公开</a>:"" <a href="javascript:void(0)" onClick={()=>this.setPublic(1)} className="bank_public color-blue_4C fr mr60">设为公开</a>:""
} }
</p> </p>
<p className="itembottom clearfix"> <p className="itembottom clearfix">
<span className="fl bottomspan color-grey-9">{item.quotes_count}次引用</span> <span className="fl bottomspan color-grey-9">{item.quotes_count}次引用</span>
<span className="fl bottomspan color-grey-9">{item.solve_count}次答题</span> <span className="fl bottomspan color-grey-9">{item.solve_count}次答题</span>
<span className="fl bottomspan color-grey-9">{moment(item.updated_at).format('YYYY-MM-DD HH:mm')}</span> <span className="fl bottomspan color-grey-9">{moment(item.updated_at).format('YYYY-MM-DD HH:mm')}</span>
<span className="fr"><a href="javascript:void(0)" className="bank_delete color-grey-9" onClick={()=>this.setPublic(2)}>删除</a></span> <span className="fr"><a href="javascript:void(0)" className="bank_delete color-grey-9" onClick={()=>this.setPublic(2)}>删除</a></span>
<span className="bank_list_Tag">{item.course_list_name}</span> <span className="bank_list_Tag">{item.course_list_name}</span>
</p> </p>
</div> </div>
</div> </div>
) )
}) })
} }
</div> </div>
{ {
totalCount > 15 && totalCount > 15 &&
<div className="mt30 mb50 edu-txt-center"> <div className="mt30 mb50 edu-txt-center">
<Pagination showQuickJumper total={totalCount} onChange={this.changePage} pageSize={16} current={page}/> <Pagination showQuickJumper total={totalCount} onChange={this.changePage} pageSize={16} current={page}/>
</div> </div>
} }
</Spin> </Spin>
</div> </div>
) )
} }
} }
export default InfosBank; export default InfosBank;

@ -1,115 +1,122 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import {Link} from 'react-router-dom'; import {Link} from 'react-router-dom';
import {Tooltip,Menu} from 'antd'; import {Tooltip,Menu} from 'antd';
import {getImageUrl} from 'educoder'; import {getImageUrl} from 'educoder';
import "./usersInfo.css" import "./usersInfo.css"
import "../../courses/css/members.css" import "../../courses/css/members.css"
import "../../courses/css/Courses.css" import "../../courses/css/Courses.css"
import banner from '../../../images/account/infobanner.png' import { LinkAfterLogin } from 'educoder'
class InfosBanner extends Component{ class InfosBanner extends Component{
constructor(props){ constructor(props){
super(props); super(props);
} }
render(){ render(){
let { let {
data , data ,
id, id,
login, login,
moduleName, moduleName,
current_user, current_user,
}=this.props; }=this.props;
let is_current=this.props.is_current; let is_current=this.props.is_current;
let {username}= this.props.match.params; let {username}= this.props.match.params;
let {pathname}=this.props.location; let {pathname}=this.props.location;
moduleName=pathname.split("/")[3]; moduleName=pathname.split("/")[3];
return( return(
<div className="bannerPanel mb60"> <div className="bannerPanel mb60">
<div className="educontent"> <div className="educontent">
<div className="clearfix color-white mb25"> <div className="clearfix color-white mb25">
<p className="myPhoto mr20 fl"><img alt="头像" src={data && `${getImageUrl('images/'+data.avatar_url)}`}/></p> <p className="myPhoto mr20 fl"><img alt="头像" src={data && `${getImageUrl('images/'+data.avatar_url)}`}/></p>
<div className="fl"> <div className="fl">
<p className="clearfix mt20"> <p className="clearfix mt20">
<span className="username task-hide" style={{"maxWidth":'370px'}}>{data && data.name}</span> <span className="username task-hide" style={{"maxWidth":'370px'}}>{data && data.name}</span>
{ {
data && is_current == false && data.identity =="学生" ? "" : data && is_current == false && data.identity =="学生" ? "" :
<span className="userpost"><label>{data && data.identity}</label></span> <span className="userpost"><label>{data && data.identity}</label></span>
} }
</p> </p>
<p className="mt15"> <p className="mt15">
<Tooltip placement='bottom' title={ data && data.professional_certification ?"已职业认证":"未职业认证"}> <Tooltip placement='bottom' title={ data && data.professional_certification ?"已职业认证":"未职业认证"}>
<i className={ data && data.professional_certification ? "iconfont icon-shenfenzhenghaomaguizheng font-18 user-colorgrey-green mr20 ml2":"iconfont icon-shenfenzhenghaomaguizheng font-18 user-colorgrey-B8 mr20 ml2"}></i> <i className={ data && data.professional_certification ? "iconfont icon-shenfenzhenghaomaguizheng font-18 user-colorgrey-green mr20 ml2":"iconfont icon-shenfenzhenghaomaguizheng font-18 user-colorgrey-B8 mr20 ml2"}></i>
</Tooltip> </Tooltip>
<Tooltip placement='bottom' title={ data && data.authentication ?"已实名认证":"未实名认证"}> <Tooltip placement='bottom' title={ data && data.authentication ?"已实名认证":"未实名认证"}>
<i className={ data && data.authentication ? "iconfont icon-renzhengshangjia font-18 user-colorgrey-green":"iconfont icon-renzhengshangjia font-18 user-colorgrey-B8"}></i> <i className={ data && data.authentication ? "iconfont icon-renzhengshangjia font-18 user-colorgrey-green":"iconfont icon-renzhengshangjia font-18 user-colorgrey-B8"}></i>
</Tooltip> </Tooltip>
</p> </p>
</div> </div>
<div className="fr"> <div className="fr">
<div class="fl headtab mt20"> <div class="fl headtab mt20">
<span>{is_current ? "我":"TA"}的经验值</span> <span>{is_current ? "我":"TA"}的经验值</span>
<a style={{"cursor":"default"}}>{data && data.experience}</a> <a style={{"cursor":"default"}}>{data && data.experience}</a>
</div> </div>
<div class="fl headtab mt20 pr leftTransform pl20"> <div class="fl headtab mt20 pr leftTransform pl20">
<span>{is_current ? "我":"TA"}的金币</span> <span>{is_current ? "我":"TA"}的金币</span>
<a style={{"cursor":"default"}}>{data && data.grade}</a> <a style={{"cursor":"default"}}>{data && data.grade}</a>
</div> </div>
{ {
is_current ? is_current ?
<span className="fl mt35 ml60"> <span className="fl mt35 ml60">
{ {
data && data.attendance_signed ? data && data.attendance_signed ?
<span className="user_default_btn user_grey_btn font-18">已签到</span> <span className="user_default_btn user_grey_btn font-18">已签到</span>
: :
<a herf="javascript:void(0);" onClick={this.props.signFor} className="user_default_btn user_yellow_btn fl font-18">签到</a> <a herf="javascript:void(0);" onClick={this.props.signFor} className="user_default_btn user_yellow_btn fl font-18">签到</a>
} }
</span> </span>
: :
<span className="fl mt35 ml60"> <span className="fl mt35 ml60">
<a href={`/messages/${login}/message_detail?target_ids=${id}`} className="user_default_btn user_yellow_btn fl font-18">私信</a> <LinkAfterLogin
</span> {...this.props}
} {...this.state}
</div> className="user_default_btn user_yellow_btn fl font-18"
</div> to={`/messages/${login}/message_detail?target_ids=${id}`}
<div className="userNav"> >
<li className={`${moduleName == 'courses' ||moduleName == undefined ? 'active' : '' }`}> 私信
<Link </LinkAfterLogin>
onClick={() => this.setState({moduleName: 'courses'})} </span>
to={`/users/${username}/courses`}>翻转课堂</Link> }
</li> </div>
<li className={`${moduleName == 'shixuns' ? 'active' : '' }`}> </div>
<Link <div className="userNav">
onClick={() => this.setState({moduleName: 'shixuns'})} <li className={`${moduleName == 'courses' ||moduleName == undefined ? 'active' : '' }`}>
to={`/users/${username}/shixuns`}>实训项目</Link> <Link
</li> onClick={() => this.setState({moduleName: 'courses'})}
<li className={`${moduleName == 'paths' ? 'active' : '' }`}> to={`/users/${username}/courses`}>翻转课堂</Link>
<Link </li>
onClick={() => this.setState({moduleName: 'paths'})} <li className={`${moduleName == 'shixuns' ? 'active' : '' }`}>
to={`/users/${username}/paths`}>实践课程</Link> <Link
</li> onClick={() => this.setState({moduleName: 'shixuns'})}
<li className={`${moduleName == 'projects' ? 'active' : '' }`}> to={`/users/${username}/shixuns`}>开发社区</Link>
<Link </li>
onClick={() => this.setState({moduleName: 'projects'})} <li className={`${moduleName == 'paths' ? 'active' : '' }`}>
to={`/users/${username}/projects`}>开发项目</Link> <Link
</li> onClick={() => this.setState({moduleName: 'paths'})}
<li className={`${moduleName == 'package' ? 'active' : '' }`}> to={`/users/${username}/paths`}>实践课程</Link>
<Link </li>
onClick={() => this.setState({moduleName: 'package'})} <li className={`${moduleName == 'projects' ? 'active' : '' }`}>
to={`/users/${username}/package`}>众包</Link> <Link
</li> onClick={() => this.setState({moduleName: 'projects'})}
{((is_current && current_user && current_user.is_teacher ) || current_user && current_user.admin) to={`/users/${username}/projects`}>项目</Link>
&& <li className={`${moduleName == 'videos' ? 'active' : '' }`}> </li>
<Link <li className={`${moduleName == 'package' ? 'active' : '' }`}>
onClick={() => this.setState({moduleName: 'videos'})} <Link
to={`/users/${username}/videos`}>视频</Link> onClick={() => this.setState({moduleName: 'package'})}
</li>} to={`/users/${username}/package`}>众包</Link>
</div> </li>
</div> {((is_current && current_user && current_user.is_teacher ) || current_user && current_user.admin)
</div> && <li className={`${moduleName == 'videos' ? 'active' : '' }`}>
) <Link
} onClick={() => this.setState({moduleName: 'videos'})}
} to={`/users/${username}/videos`}>视频</Link>
</li>}
</div>
</div>
</div>
)
}
}
export default InfosBanner; export default InfosBanner;

@ -130,7 +130,7 @@ class InfosCourse extends Component{
this.props.current_user && this.props.current_user.user_identity != "学生" ? <Create href={"/courses/new"} name={"新建课堂"} index="1"></Create> : "" this.props.current_user && this.props.current_user.user_identity != "学生" ? <Create href={"/courses/new"} name={"新建课堂"} index="1"></Create> : ""
} }
{ {
(!data || data.courses.length==0) && (!is_current || (this.props.current_user && this.props.current_user.user_identity === "学生" )) && <NoneData></NoneData> (!data || (data && data.courses.length==0)) && category && <NoneData></NoneData>
} }
{ {
data && data.courses && data.courses.map((item,key)=>{ data && data.courses && data.courses.map((item,key)=>{

@ -152,7 +152,7 @@ class InfosPath extends Component{
this.props.current_user && this.props.current_user.user_identity != "学生" ? <Create href={"/paths/new"} name={"新建实践课程"} index="3"></Create>:"" this.props.current_user && this.props.current_user.user_identity != "学生" ? <Create href={"/paths/new"} name={"新建实践课程"} index="3"></Create>:""
} }
{ {
(!data || data.subjects.length==0) && (!is_current || (this.props.current_user && this.props.current_user.user_identity === "学生" )) && <NoneData></NoneData> (!data || (data && data.subjects.length==0)) && category && <NoneData></NoneData>
} }
{ {
data && data.subjects && data.subjects.map((item,key)=>{ data && data.subjects && data.subjects.map((item,key)=>{

@ -125,7 +125,7 @@ class InfosProject extends Component{
<Create href={`${this.props.Headertop && this.props.Headertop.old_url}/projects/new`} name={"新建开发项目"} index="4"></Create>:"" <Create href={`${this.props.Headertop && this.props.Headertop.old_url}/projects/new`} name={"新建开发项目"} index="4"></Create>:""
} }
{ {
(!data || data.projects.length==0) && (!is_current || (this.props.current_user && this.props.current_user.user_identity === "学生" )) && <NoneData></NoneData> (!data || (data && data.projects.length==0)) && category && <NoneData></NoneData>
} }
{ {
data && data.projects && data.projects.map((item,key)=>{ data && data.projects && data.projects.map((item,key)=>{

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save