Merge branch 'dev_aliyun' of https://bdgit.educoder.net/Hjqreturn/educoder into dev_aliyun

dev_daiao
daiao 5 years ago
commit b3f8b74411

@ -26,6 +26,15 @@ $(document).on('turbolinks:load', function() {
});
});
// 清空
searchForm.on('click', '.clear-btn', function () {
searchForm.find('select[name="status"]').val('');
searchForm.find('.school-select').val('').trigger('change');
searchForm.find('input[name="keyword"]').val('');
searchForm.find('#homepage_show').attr('checked', false);
searchForm.find('input[type="submit"]').trigger('click');
});
// ************** 学校选择 *************
searchForm.find('.school-select').select2({
theme: 'bootstrap4',

@ -0,0 +1,11 @@
$(document).on('turbolinks:load', function () {
if ($('body.admins-projects-index-page').length > 0) {
var $form = $('.search-form');
// 清空
$form.on('click', '.clear-btn', function () {
$form.find('input[name="search"]').val('');
$form.find('input[type="submit"]').trigger('click');
});
}
});

@ -0,0 +1,12 @@
$(document).on('turbolinks:load', function () {
if ($('body.admins-shixun-modify-records-index-page').length > 0) {
var $form = $('.search-form');
// 清空
$form.on('click', '.clear-btn', function () {
$form.find('select[name="date"]').val('weekly');
$form.find('input[name="user_name"]').val('');
$form.find('input[type="submit"]').trigger('click');
});
}
});

@ -0,0 +1,14 @@
.diff{overflow:auto;}
.diff ul{background:#fff;overflow:auto;font-size:13px;list-style:none;margin:0;padding:0 1rem;display:table;width:100%;}
.diff del, .diff ins{display:block;text-decoration:none;}
.diff li{padding:0; display:table-row;margin: 0;height:1em;}
.diff li.ins{background:#dfd; color:#080}
.diff li.del{background:#fee; color:#b00}
.diff li:hover{background:#ffc}
/* try 'whitespace:pre;' if you don't want lines to wrap */
.diff del, .diff ins, .diff span{white-space:pre-wrap;font-family:courier;}
.diff del strong{font-weight:normal;background:#fcc;}
.diff ins strong{font-weight:normal;background:#9f9;}
.diff li.diff-comment { display: none; }
.diff li.diff-block-info { background: none repeat scroll 0 0 gray; }

@ -0,0 +1,9 @@
class Admins::ShixunModifyRecordsController < Admins::BaseController
def index
records = Admins::ShixunModifyRecordQuery.call(params)
@records = paginate records.includes(:diff_record_content)
end
end

@ -0,0 +1,33 @@
class Admins::ShixunModifyRecordQuery < ApplicationQuery
attr_reader :params
def initialize(params)
@params = params
end
def call
if params[:user_name].blank? || params[:date].blank?
records = DiffRecord.none
else
records = DiffRecord.joins(:user).where("concat(users.lastname, users.firstname) like ?", "%#{params[:user_name].strip}%")
if time_range.present?
records = records.where(created_at: time_range)
end
end
records.order("diff_records.created_at desc")
end
private
def time_range
@_time_range ||= begin
case params[:date]
when 'weekly' then 1.weeks.ago..Time.now
when 'monthly' then 1.months.ago..Time.now
when 'quarterly' then 3.months.ago..Time.now
when 'yearly' then 1.years.ago..Time.now
else ''
end
end
end
end

@ -27,8 +27,9 @@
<li><%= sidebar_item(admins_shixun_settings_path, '实训配置', icon: 'cog', controller: 'admins-shixun_settings') %></li>
<li><%= sidebar_item(admins_mirror_repositories_path, '镜像管理', icon: 'cubes', controller: 'admins-mirror_repositories') %></li>
<li><%= sidebar_item(admins_myshixuns_path, '学员实训列表', icon: 'server', controller: 'admins-myshixuns') %></li>
<li><%= sidebar_item(admins_shixun_recycles_path, '实训回收站', icon: 'recycle', controller: 'admins-myshixuns') %></li>
<% end %>
<li><%= sidebar_item(admins_shixun_modify_records_path, '实训修改记录', icon: 'eraser', controller: 'admins-shixun_modify_records') %></li>
<li><%= sidebar_item(admins_shixun_recycles_path, '实训回收站', icon: 'recycle', controller: 'admins-shixun_recycles') %></li>
<% end %>
</li>
<li>

@ -0,0 +1,25 @@
<% define_admin_breadcrumbs do %>
<% add_admin_breadcrumb('实训修改记录') %>
<% end %>
<div class="box search-form-container shixun-modify-record-list-form">
<%= form_tag(admins_shixun_modify_records_path, method: :get, class: 'form-inline search-form flex-1', remote: true) do %>
<div class="form-group col-12 col-md-4">
<label for="user_name">用户名:</label>
<%= text_field_tag :user_name, params[:user_name], class: 'form-control flex-1', placeholder: '真实姓名搜索' %>
</div>
<div class="form-group col-12 col-md-auto">
<label for="status">时间范围:</label>
<% data_arrs = [['最近一周', 'weekly'], ['最近一个月', 'monthly']] %>
<%= select_tag(:date, options_for_select(data_arrs, params[:date]), class: 'form-control') %>
</div>
<%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %>
<input type="reset" class="btn btn-secondary clear-btn" value="清空"/>
<% end %>
</div>
<div class="box admin-list-container shixun-modify-record-list-container">
<%= render partial: 'admins/shixun_modify_records/shared/list', locals: { records: @records } %>
</div>

@ -0,0 +1 @@
$('.shixun-modify-record-list-container').html("<%= j( render partial: 'admins/shixun_modify_records/shared/list', locals: { records: @records } ) %>");

@ -0,0 +1,36 @@
<% if records.present? %>
<% records.each do |record| %>
<div class="card mb-5">
<div class="card-header font-16">
<span><%= record.user.real_name %></span>
<span class="ml-3"><%= format_time record.created_at %></span>
</div>
<div class="mt-2 mb-3 ml-3 font-14">
<span>实训名称:<%= record.container&.shixun&.name %></span>
<% if record.container_type == "Challenge" %>
<span class="ml-3">/</span>
<span class="ml-3">关卡名:<%= record.container&.subject %></span>
<% end %>
</div>
<div class="diff font-12">
<ul>
<% record.diff_record_content&.content&.split("\n").each do |line| %>
<% if line =~ /^[\+]/ %>
<li class="ins"><ins><%= line %></ins></li>
<% elsif line =~ /^[\-]/ %>
<li class="del"><del><%= line %></del></li>
<% else %>
<li class="unchanged"><span><%= line %></span></li>
<% end %>
<% end %>
</ul>
</div>
</div>
<% end %>
<% else %>
<%= render 'admins/shared/no_data_for_table' %>
<% end %>
<%= render partial: 'admins/shared/paginate', locals: { objects: records } %>

@ -1057,6 +1057,7 @@ Rails.application.routes.draw do
resources :shixun_recycles, only: [:index, :destroy] do
post :resume, on: :member
end
resources :shixun_modify_records, only: [:index]
resources :department_applies,only: [:index,:destroy] do
collection do
post :merge

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -132,7 +132,9 @@ class Trainingjobsetting extends Component {
CalculateMax: 100,//总分值
borredszf:"ml10 color-grey-9",
borredszfl:true,
borredszfls:''
borredszfls:'',
total_scoretwo:0,
total_score:0,
}
// console.log("获取到的值")
// console.log("Trainingjobsetting")
@ -302,7 +304,10 @@ class Trainingjobsetting extends Component {
proportion: result.data.shixun_evaluation === 0 ? "均分比例" : result.data.shixun_evaluation === 1 ? "经验值比例" : result.data.shixun_evaluation === 2 ? "自定义分值" : "",
publicwork: result.data.work_public,
challenge_settings: result.data.challenge_settings,
code_review: result.data.code_review
code_review: result.data.code_review,
total_scoretwo:result.data.total_score,
total_score:result.data.total_score,
})
this.props.Getdataback(result, result.data);
@ -646,6 +651,7 @@ class Trainingjobsetting extends Component {
if (this.state.completionefficiencyscore === true) {
latedeductiontwos = this.state.latedeductiontwo;
}
//从这里开始记得等于0的时候还要做判断
if (challenge_scoredata.length > 0) {
var len = 0;
for (var k = 0; k < challenge_scoredata.length; k++) {
@ -680,6 +686,16 @@ class Trainingjobsetting extends Component {
}
}else{
try {
if(parseFloat(this.state.CalculateMax)!==parseFloat(0)){
this.props.showNotification(`分值之和必须等于总分值:${this.state.CalculateMax}`);
this.scrollToAnchor("zongfentimeid");
return;
}
}catch (e) {
}
}
var url = `/homework_commons/${homeworkid}/update_settings.json`;
@ -707,7 +723,9 @@ class Trainingjobsetting extends Component {
shixun_evaluation: this.state.proportion === "均分比例" ? 0 : this.state.proportion === "经验值比例" ? 1 : this.state.proportion === "自定义分值" ? 2 : 0,
challenge_settings: array,
score_open: this.state.publicwork,
total_score:this.state.CalculateMax
total_score:this.state.CalculateMax,
total_scoretwo:this.state.CalculateMax,//记录总分值点击取消的时候还原总分值
}
} else {
// //非统一配置
@ -738,7 +756,8 @@ class Trainingjobsetting extends Component {
shixun_evaluation: this.state.proportion === "均分比例" ? 0 : this.state.proportion === "经验值比例" ? 1 : this.state.proportion === "自定义分值" ? 2 : 0,
challenge_settings: array,
score_open: this.state.publicwork,
total_score:this.state.CalculateMax
total_score:this.state.CalculateMax,
total_scoretwo:this.state.CalculateMax
}
}
@ -1193,8 +1212,7 @@ class Trainingjobsetting extends Component {
}
//总比分
Totalscorecalculation = (value) => {
debugger
this.setState({
CalculateMax: value,
})
@ -2150,6 +2168,9 @@ class Trainingjobsetting extends Component {
})
this.refs.targetElementTrainingjobsetting.scrollIntoView();
this.getTrainingjobsetting(false);
this.setState({
CalculateMax:this.state.total_scoretwo,
})
}
rulesCheckInfo = (rules) => {

@ -179,7 +179,6 @@ class DeveloperHome extends React.PureComponent {
componentDidMount() {
// 是否是我的,如果是我的 显示编辑按钮
const { isMySource } = this.props;
console.log(this.props);
if (isMySource) {
this.handleFilterSearch({come_from: 'mine'});

@ -7,6 +7,7 @@
*/
import React from 'react';
import { TPMIndexHOC } from '../tpm/TPMIndexHOC';
import { SnackbarHOC } from 'educoder';
import DeveloperHome from './DeveloperHome';
const App = (props) => {
@ -15,4 +16,4 @@ const App = (props) => {
);
}
export default TPMIndexHOC(App);
export default SnackbarHOC()(TPMIndexHOC(App));

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-11-20 10:35:40
* @LastEditors: tangjiang
* @LastEditTime: 2019-12-04 19:56:43
* @LastEditTime: 2019-12-05 18:07:32
*/
import 'quill/dist/quill.core.css';
import 'quill/dist/quill.bubble.css';
@ -18,6 +18,7 @@ import AddTestDemo from './AddTestDemo';
import QuillEditor from '../../../quillEditor';
import actions from '../../../../../redux/actions';
import CONST from '../../../../../constants';
import { fromStore, toStore } from 'educoder'; // 保存和读取store值
const scrollIntoView = require('scroll-into-view');
const {jcLabel} = CONST;
const FormItem = Form.Item;
@ -110,6 +111,8 @@ class EditTab extends React.Component {
// 改变描述信息
handleChangeDescription = (value) => {
// console.log('获取的编辑器内容为: ', value);
// 描述信息变化时将信息保存至store中
toStore('oj_description', value);
this.props.validateOjDescription(value);
}
// 改变难易度

@ -47,7 +47,7 @@ const five_min = 5 * 60 * 1000;
倒计时为0时出现重启按钮
*/
const isSSHInIframe = false;
class WebSSHTimer extends React.PureComponent {
class WebSSHTimer extends Component {
constructor(props) {
super(props)
@ -165,7 +165,6 @@ class WebSSHTimer extends React.PureComponent {
})
}
componentDidUpdate(prevProps, prevState, snapshot) {
console.log('======',prevProps, this.state, this.startTimeRemain);
// 仅初始化一次
if (prevProps.showTimerProp === false && this.props.showTimerProp === true) {
if (this.intervalHandler) {
@ -199,8 +198,8 @@ class WebSSHTimer extends React.PureComponent {
// }
} else if (e.data.tp === "sshWorking") {
this.startTimeRemain = 60;
this.forceUpdate()
// this.startTimeRemain = 60;
// this.forceUpdate();
}
});
// } else {

@ -244,7 +244,9 @@ class TPIMonaco extends Component {
// 重要setState(因获取代码、重置代码等接口引起的调用)调用引起的变化才需要setValue
editor_monaco.setValue(this.props.repositoryCode)
}
// 代码没变也需要layout可能从命令行自动切回了代码tab
editor_monaco.layout();
// Clears the editor's undo history.
// TODO

@ -136,7 +136,7 @@ class AccountBasic extends Component {
}
handleSubmit = () => {
this.props.form.validateFieldsAndScroll((err, values) => {
this.props.form.validateFieldsAndScroll({ force: true }, (err, values) => {
console.log(values);
let {basicInfo}=this.props;
if(!err ){
@ -390,13 +390,13 @@ class AccountBasic extends Component {
this.props.showNotification("请先选择正确的单位或者学校!");
}
}
checkNameLength = (rule, value, callback) => {
if (value && value.length <= MAX_NAME_LENGTH) {
callback();
return;
}
callback(`请输入真实姓名,最大限制${MAX_NAME_LENGTH}个字符`);
}
// checkNameLength = (rule, value, callback) => {
// if (value && value.length <= MAX_NAME_LENGTH) {
// callback();
// return;
// }
// callback(`请输入真实姓名,最大限制${MAX_NAME_LENGTH}个字符`);
// }
// 切换职称
changeJob=(e)=>{
this.setState({
@ -410,7 +410,51 @@ class AccountBasic extends Component {
})
}
}
//昵称
handleSubmitName(rule, value, callback){
if (value) {
let iconRule1 = /[`~!@#$%^&*()\-+=<>?:"{}|,.\/;'\\[\]·~@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、]/im;
// 判断是否含有emoji表情
let iconRule2 = /[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF][\u200D|\uFE0F]|[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF]|[0-9|*|#]\uFE0F\u20E3|[0-9|#]\u20E3|[\u203C-\u3299]\uFE0F\u200D|[\u203C-\u3299]\uFE0F|[\u2122-\u2B55]|\u303D|[\A9|\AE]\u3030|\uA9|\uAE|\u3030/ig;
// 如果为true字符串含有emoji表情 false不含
const iconRule2s =iconRule2.test(value);
// 如果为true字符串含有特殊符号 false不
const iconRule1s =iconRule1.test(value);
if (iconRule2s===true|| iconRule1s===true) {
callback('2-20位中英文、数字及下划线');
}
else if(value.length<2){
callback('2-20位中英文、数字及下划线');
}else if(value.length>=21){
callback('2-20位中英文、数字及下划线');
}
}
callback();
}
// 姓名
handleSubmitNames(rule, value, callback){
if (value) {
let iconRule1 = /[`~!@#$%^&*()_\-+=<>?:"{}|,.\/;'\\[\]·~@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、]/im;
// 判断是否含有emoji表情
let iconRule2 = /[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF][\u200D|\uFE0F]|[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF]|[0-9|*|#]\uFE0F\u20E3|[0-9|#]\u20E3|[\u203C-\u3299]\uFE0F\u200D|[\u203C-\u3299]\uFE0F|[\u2122-\u2B55]|\u303D|[\A9|\AE]\u3030|\uA9|\uAE|\u3030/ig;
// 如果为true字符串含有emoji表情 false不含
const iconRule2s =iconRule2.test(value);
// 如果为true字符串含有特殊符号 false不
const iconRule1s =iconRule1.test(value);
if (iconRule2s===true|| iconRule1s===true) {
callback('2-10位中英文、数字');
}
else if(value.length<2){
callback('2-10位中英文、数字');
}else if(value.length>=11){
callback('2-10位中英文、数字');
}
}
callback();
}
render() {
let{
nameLength,
@ -527,7 +571,10 @@ class AccountBasic extends Component {
// initialValue: this.state.cityDefaultValue,
required: true,
message: '请输入您的昵称',
}],
},
{ validator: this.handleSubmitName },
],
validateTrigger: 'onSubmit', // 设置进行表单验证的时机为onSubmit
})(
<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>
@ -554,8 +601,11 @@ class AccountBasic extends Component {
// initialValue: this.state.cityDefaultValue,
required: true,
message: `请输入真实姓名,最大限制${MAX_NAME_LENGTH}个字符`,
validator: this.checkNameLength
}],
},
{ validator: this.handleSubmitNames },
],
validateTrigger: 'onSubmit', // 设置进行表单验证的时机为onSubmit
})(
<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"}

@ -450,6 +450,28 @@ class RealNameCertificationModal extends Component{
department_id: arr[0].id,
})
}
// 姓名
handleSubmitNames(rule, value, callback){
if (value) {
let iconRule1 = /[`~!@#$%^&*()_\-+=<>?:"{}|,.\/;'\\[\]·~@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、]/im;
// 判断是否含有emoji表情
let iconRule2 = /[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF][\u200D|\uFE0F]|[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF]|[0-9|*|#]\uFE0F\u20E3|[0-9|#]\u20E3|[\u203C-\u3299]\uFE0F\u200D|[\u203C-\u3299]\uFE0F|[\u2122-\u2B55]|\u303D|[\A9|\AE]\u3030|\uA9|\uAE|\u3030/ig;
// 如果为true字符串含有emoji表情 false不含
const iconRule2s =iconRule2.test(value);
// 如果为true字符串含有特殊符号 false不
const iconRule1s =iconRule1.test(value);
if (iconRule2s===true|| iconRule1s===true) {
callback('2-10位中英文、数字');
}
else if(value.length<2){
callback('2-10位中英文、数字');
}else if(value.length>=11){
callback('2-10位中英文、数字');
}
}
callback();
}
render(){
const { course_lists, checkBoxValues, searchValue, loading, imageUrl, imageUrl2,
@ -669,8 +691,10 @@ class RealNameCertificationModal extends Component{
// initialValue: this.state.cityDefaultValue,
required: true,
message: `请输入真实姓名,最大限制${MAX_NAME_LENGTH}个字符`,
validator: this.checkNameLength
}],
},
{ validator: this.handleSubmitNames },
],
})(
<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"}

Loading…
Cancel
Save