Merge branch 'dev_aliyun' into develop

dev_cs_new
daiao 6 years ago
commit 8288fb4a8f

@ -1336,7 +1336,7 @@ class HomeworkCommonsController < ApplicationController
shixun = @homework.shixuns.take
# 通过代码文件来判断语言
language = shixun.challenges.practice_type.pluck(:path).first
language = language.split("")[0].split(".")[1].downcase if language.present?
language = language.split("")[0].split(".").last.downcase if language.present?
user_lists = []
if language.present? && (language == "java" || language == "py")
user_ids = @course.course_members.where(course_group_id: params[:group_ids]).distinct(:user_id).pluck(:user_id)

@ -81,6 +81,7 @@ class SubjectsController < ApplicationController
def show
@user = current_user
@is_creator = current_user.creator_of_subject?(@subject)
@is_manager = @user.manager_of_subject?(@subject)
# 合作团队
@members = @subject.subject_members.includes(:user)
@shixuns = @subject.shixuns.published.pluck(:id)
@ -281,7 +282,7 @@ class SubjectsController < ApplicationController
# 删除实训
# DELETE: /api/subejcts/:id/delete_member
def delete_member
tip_exception(403, "没权限操作") if !current_user.admin?
tip_exception(403, "没权限操作") unless current_user.manager_of_subject?(@subject)
tip_exception('用户id不能为空') if params[:user_id].blank?
user = @subject.subject_members.where(:user_id => params[:user_id], :role => 2).first
tip_exception("管理员用户不允许删除,或用户不存在") if user.blank?

@ -103,6 +103,10 @@ module StudentWorksHelper
# 对结果进行排序
efficiency_list =
results.sort {|x, y| x[:efficiency] <=> y[:efficiency]}.each_with_index.map do |result, index|
if result[:user_id] == work.user.id
myself_eff = [index+1, result[:efficiency]]
myself_object = [result[:consume_time], result[:eff_score], result[:round_size]]
end
[index + 1, result[:efficiency], result[:user_id]]
end

@ -263,9 +263,9 @@ class User < ApplicationRecord
course&.course_members.exists?(user_id: id)
end
# 实训路径管理员创建者或admin
# 实训路径管理员
def creator_of_subject?(subject)
subject.user_id == id || admin?
subject.user_id == id
end
# 实训路径合作者、admin

@ -5,15 +5,16 @@ json.challenges_count @subject.subject_challenge_count
json.subject_score @subject.all_score
json.member_count @subject.member_count
json.allow_delete @is_creator && (@subject.status != 2 || @user.admin?)
json.publish_status publish_status(@subject, @is_creator, @user, @shixuns)
json.allow_statistics @user.manager_of_subject?(@subject)
json.allow_delete (@subject.status != 2 && @is_creator) || @user.admin?
json.publish_status publish_status(@subject, @is_manager, @user, @shixuns)
json.allow_statistics @is_manager
json.allow_send @user.logged?
json.allow_visit @user.manager_of_subject?(@subject) || @user.admin? || @subject.status > 1
json.allow_add_member @user.manager_of_subject?(@subject)
json.allow_visit @subject.status > 1 || @is_manager
json.allow_add_member @is_manager
json.members @members do |member|
json.partial! 'subject_member', locals: { user: member.user }
json.role member.role
end
# 技能标签

@ -1,3 +1,4 @@
json.members @subject.subject_members do |member|
json.partial! 'subject_member', locals: { user: member.user }
json.role member.role
end

@ -0,0 +1,25 @@
#coding=utf-8
# 执行示例 bundle exec rake public_course:student args=149,2903
# args 第一个参数是subject_id第二个参数是课程course_id
desc "同步精品课数据"
namespace :public_course do
task :student => :environment do
subject_id = ENV['args'].split(",").first
course_id = ENV['args'].split(",").last
puts "subject_id is #{subject_id}"
puts "course_id is #{course_id}"
user_ids = Myshixun.find_by_sql("select distinct(user_id) from myshixuns where shixun_id in (select shixun_id from stage_shixuns
where stage_id in (select id from stages where subject_id=#{subject_id}))").map(&:user_id)
puts user_ids
if user_ids.present?
user_ids.each do |user_id|
puts user_id
CourseMember.create!(course_id: course_id, user_id: user_id, role: 4)
end
end
end
end

File diff suppressed because one or more lines are too long

@ -5,6 +5,13 @@ import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import { Spin } from 'antd';
class Loading extends Component {
componentDidUpdate(prevProps, prevState) {
if (!prevProps.error && this.props.error) {
console.log(this.props.error)
window.location.reload()
}
}
render() {
// Loading
return (

@ -64,3 +64,4 @@ export { default as ImageLayerHook } from './hooks/ImageLayerHook'
// 外部
export { default as CBreadcrumb } from '../modules/courses/common/CBreadcrumb'
export { CNotificationHOC as CNotificationHOC } from '../modules/courses/common/CNotificationHOC'

@ -119,17 +119,17 @@ class ListPageIndex extends Component{
{/*头部banner*/}
<CoursesBanner {...this.props}></CoursesBanner>
{mysearch!==undefined?
(
mysearch===true?
<Guide
setwindowlocal={(b)=>this.setwindowlocal(b)}
>
</Guide>
:""
)
:""
}
{/*{mysearch!==undefined?*/}
{/*(*/}
{/* mysearch===true?*/}
{/* <Guide*/}
{/* setwindowlocal={(b)=>this.setwindowlocal(b)}*/}
{/* >*/}
{/* </Guide>*/}
{/* :""*/}
{/* )*/}
{/* :""*/}
{/*}*/}
<div className="educontent clearfix" style={{flex: "1 0 auto"}}>
<div className="stud-class-set">

@ -246,9 +246,18 @@ class CoursesBanner extends Component {
})
var url = `/courses/${id}/duplicate_course.json`
axios.post(url).then((response) => {
// window.location.href = "/courses/" + response.data.new_course_id;
if(response!==undefined){
window.location.href = "/courses/" + response.data.new_course_id+"/students";
})
return
}
this.modalCancel();
// window.location.href = "/courses/" + response.data.new_course_id;
}).catch( (error)=> {
this.modalCancel();
console.log(252);
console.log(error);
});
}
if(this.state.metype===6){

@ -72,7 +72,8 @@ class ShixunStudentWork extends Component {
showmodel:false,
jobsettingsdata:undefined,
DownloadType:false,
DownloadMessageval:undefined
DownloadMessageval:undefined,
lunxun:true,
}
}
@ -121,6 +122,7 @@ class ShixunStudentWork extends Component {
getupdata=(pages)=>{
let {order,b_order,page,limit,group_infolist,search}=this.state;
var homeworkid = this.props.match.params.homeworkid;
let url = "/homework_commons/" + homeworkid + "/code_review_results.json";
@ -151,10 +153,11 @@ class ShixunStudentWork extends Component {
}
this.setState({
data: response.data,
datalist:datas
})
datalist:datas,
lunxun:false,
duplicatechecking:false,
});
}
}
}
@ -174,7 +177,13 @@ class ShixunStudentWork extends Component {
description: response.data.message
});
}
setInterval(() => {
console.log("开始轮询了");
if(this.state.lunxun===true){
console.log("开始轮询了getupdata");
this.getupdatasysk();
}
}, 5000);
}).catch((error) => {
@ -186,6 +195,55 @@ class ShixunStudentWork extends Component {
this.setState({
shixuntypes:type[3]
})
};
getupdatasysk=(pages)=>{
let {order,b_order,page,limit,group_infolist,search}=this.state;
var homeworkid = this.props.match.params.homeworkid;
let url = "/homework_commons/" + homeworkid + "/code_review_results.json";
axios.get(url,{params:{
order:order,
sort:b_order,
page:pages===undefined?page:pages,
limit:limit,
group_ids:group_infolist,
search:search
},
paramsSerializer: function(params) {
return qs.stringify(params, {arrayFormat: 'brackets'})
}}).then((response) => {
if (response.data.status === undefined || response.data.status === 0) {
if(response.data!=undefined){
if(response.data.status!=-2){
console.log();
let datas=[];
let list=response.data.users_reviews;
for(var i=0; i<list.length; i++){
datas.push({
number:i+1,
name:list[i].username,
stduynumber:list[i].student_id,
classroom:parseInt(list[i].code_rate),
operating:list[i].user_id
})
}
this.setState({
data: response.data,
datalist:datas,
lunxun:false,
duplicatechecking:false,
});
}
}
}
}).catch((error) => {
console.log(error)
});
}
getcode_review_results=(order,b_order,page,limit,group_infolist,search)=>{

@ -24,7 +24,8 @@ function startechart(data){
// trigger: 'axis',
showDelay : 0,
formatter : function (params) {
if(params.name == data.username){
if(params.name === data.username){
return "姓名:"+data.username + "<br/>"+'学号: '+data.user_id + "<br/>"+'效率:'+ data.echart_data.myself_eff[1];
}else if (params.value.length > 1) {
/* return '学生ID: ' + params.value[2] + '<br/>'
@ -34,6 +35,7 @@ function startechart(data){
return params.name + ":" + params.value +" ";
}
},
axisPointer:{
show: true,
type : 'cross',
@ -106,7 +108,7 @@ function startechart(data){
markPoint : {
data : [
{
name: data.username,
name: data===undefined?"":data.username,
xAxis:data.echart_data===undefined?"":data.echart_data.myself_eff[0],
yAxis:data.echart_data===undefined?"":data.echart_data.myself_eff[1],
value:data.echart_data===undefined?"":data.echart_data.myself_eff[1],
@ -130,13 +132,13 @@ function startechart(data){
]
}
},
{
name:'二班',
type:'scatter',
data: data.echart_data===undefined?"":data.echart_data.myself_eff,
itemStyle:{
color:'#c23531'
}}
// {
// name:'二班',
// type:'scatter',
// data: data.echart_data===undefined?"":data.echart_data.myself_eff,
// itemStyle:{
// color:'#c23531'
// }}
]};
effChart.setOption(option);
@ -189,7 +191,7 @@ function startechart(data){
borderWidth: 1,
formatter: function (obj) {
var value = obj.value;
if(obj.name ==data.username){
if(obj.name ===data.username){
return "姓名:"+data.username + "<br/>"+'学号: '+data.user_id + "<br/>"+'得分:'+ data.echart_data===undefined?"":data.echart_data.myself_object[1];
}
@ -242,7 +244,7 @@ function startechart(data){
markPoint : {
data : [
{
name: data.username,
name: data===undefined?"":data.username,
xAxis: data.echart_data===undefined?"":data.echart_data.myself_object[0],
yAxis:data.echart_data===undefined?"":data.echart_data.myself_object[1],
value:data.echart_data===undefined?"":data.echart_data.myself_object[1]
@ -255,15 +257,15 @@ function startechart(data){
}
}
},
{
name: '能力1',
type: 'scatter',
data: data.echart_data===undefined?"":data.echart_data.myself_object,
itemStyle:itemStyle1,
symbolSize: function (val){
return Math.round(val[2]);
}
}
// {
// name: '能力1',
// type: 'scatter',
// data: data.echart_data===undefined?"":data.echart_data.myself_object,
// itemStyle:itemStyle1,
// symbolSize: function (val){
// return Math.round(val[2]);
// }
// }
]
};
// 使用刚指定的配置项和数据显示图表。
@ -368,7 +370,7 @@ class Shixunechart extends Component {
</div>
<div className="fl with65" style={{paddingLeft: "5%"}}>
<li className="mt5 mb5">{data&&data.username}</li>
<li className="mt5 mb5">{data&&data.user_id}</li>
<li className="mt5 mb5">{data!==undefined?"--":data.student_id===undefined?"--":data.student_id===null?"--":data.student_id}</li>
<li className="mt5 mb5 color-orange03"><span className="color-orange03">{data&&data.echart_data===undefined?"":data&&data.echart_data.myself_eff[1]}</span></li>
<li className="mt5 mb5 color-orange03"><span className="color-orange03">{data&&data.echart_data===undefined?"":data&&data.echart_data.myself_eff[0]}</span></li>
</div>
@ -394,7 +396,7 @@ class Shixunechart extends Component {
</div>
<div className="fl with65" style={{paddingLeft: "5%"}}>
<li className="mt5 mb5">{data&&data.username}</li>
<li className="mt5 mb5">{data&&data.user_id}</li>
<li className="mt5 mb5">{data!==undefined?"--":data.student_id===undefined?"--":data.student_id===null?"--":data.student_id}</li>
<li className="mt5 mb5 color-orange03"><span className="color-orange03">{data&&data.echart_data===undefined?"":data&&data.echart_data.myself_object[1]}</span></li>
</div>
</div>

@ -1,6 +1,6 @@
import React, { Component } from 'react';
import { SnackbarHOC } from 'educoder';
import { SnackbarHOC, CNotificationHOC } from 'educoder';
import {BrowserRouter as Router,Route,Switch} from 'react-router-dom';
@ -55,4 +55,4 @@ class Index extends Component{
)
}
}
export default SnackbarHOC() ( TPMIndexHOC(Index) );
export default CNotificationHOC() (SnackbarHOC() ( TPMIndexHOC(Index) ));

@ -171,7 +171,9 @@ class DetailCards extends Component{
delecttype:false,
editdelectid:undefined
})
this.getPathCardsList();
// this.getPathCardsList();
this.updatapathCardsedit()
}
}).catch((error) => {
console.log(error)

@ -209,7 +209,7 @@ class DetailTop extends Component{
>删除路径</a>:""}
{
detailInfoList.publish_status===0&&detailInfoList.allow_statistics===true?
detailInfoList.publish_status===0&&detailInfoList.allow_add_member===true?
<a className="user_default_btn user_bluebg_btn font-18 fl ml40 userbluebgfont"
onClick={this.applyissuePath}
>申请发布</a>:""

@ -112,6 +112,10 @@ class PathDetailIndex extends Component{
this.setState({
Modalstype:false,
})
// TODO 这个是临时处理,还需要优化,这里要看怎么区分处理
if (this.state.Modalstopval == '你确定要删除该成员吗?') {
return;
}
this.props.history.goBack()
}
@ -248,11 +252,16 @@ class PathDetailIndex extends Component{
let param={user_id:user_id};
axios.delete(url,{data:param}).then((response) => {
if(response.data.status===1){
if (this.props.current_user.user_id == user_id) {
this.props.history.push('/paths')
return;
}
this.props.showNotification(response.data.message)
this.setState({
Modalstype:true,
Modalstopval:response.data.message,
loadtype:true,
cardsModalsave:this.cardsModalsave,
Modalstype:false,
// Modalstopval:response.data.message,
loadtype:false,
// cardsModalsave:this.cardsModalsave,
})
this.updatadetailInfoList();
}
@ -479,8 +488,10 @@ class PathDetailIndex extends Component{
<div className="fl ml15 flex1">
<p className="mb10 mt5">{item.name}
{/* 新增role 判断是否能删除 1 管理员 2 合作者 */}
{
detailInfoList===undefined?"":detailInfoList.allow_add_member===true?
detailInfoList===undefined?"":detailInfoList.allow_add_member===true && item.role == 2?
<a className="fr" onClick={()=>this.shanchuallow(item.id)}><i className="iconfont icon-shanchu color-grey-c font-14 font-n"></i></a>:""
}
</p>

@ -329,6 +329,10 @@ class Collaborators extends Component {
let id = this.props.match.params.shixunId;
let url = "/shixuns/" + id + "/collaborators_delete.json?user_id=" + collaborators_deletevalue;
axios.delete(url).then((response) => {
if (this.props.current_user.user_id == collaborators_deletevalue) {
this.props.history.push('/shixuns')
return;
}
this.props.showSnackbar(response.data.message);
this.updatacomponentDiddata();
this.setState({
@ -576,7 +580,7 @@ class Collaborators extends Component {
{/*</span>*/}
</p>
<p className="color-grey-B2 task-hide">{item.user.brief_introduction}</p>
{/* <p className="color-grey-B2 task-hide">{item.user.brief_introduction}</p> */}
</div>

@ -327,17 +327,18 @@ class Infos extends Component{
</div>
</div>
<div className="mt15 educontent clearfix edu-txt-center">
<p className="mb20" style={{"height": "28px"}}>
{sign && <p className="mb20" style={{"height": "28px"}}>
{/* 这家伙很懒,什么都没留下~ */}
{
is_edit && is_current ?
<input type="text" id="mysign" class="mysign-input" placeholder="请输入您的个性签名" style={{height:"20px"}} value={sign} onInput={this.inputSign} onBlur={this.savemysign}/>
:
is_current ?
<a className="mysign-span" onClick={this.editmysign} style={{"display": "block"}}>{sign || "这家伙很懒,什么都没留下~"}</a>
<a className="mysign-span" onClick={this.editmysign} style={{"display": "block"}}>{sign || ""}</a>
:
<span className="mysign-span" style={{"display": "block","cursor":"default"}}>{sign || "这家伙很懒,什么都没留下~"}</span>
<span className="mysign-span" style={{"display": "block","cursor":"default"}}>{sign || ""}</span>
}
</p>
</p>}
{
is_current ?
<div className="inline">

Loading…
Cancel
Save