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

dev_home
杨树林 5 years ago
commit 59326f442b

@ -16,7 +16,7 @@ class Cooperative::BaseController < ApplicationController
private private
def current_laboratory def current_laboratory
@_current_laboratory ||= Laboratory.find_by_subdomain('hut' || request.subdomain) @_current_laboratory ||= Laboratory.find_by_subdomain(request.subdomain)
end end
def current_setting_or_default(name) def current_setting_or_default(name)

@ -120,21 +120,7 @@ module ExercisesHelper
if ex.question_type > Exercise::COMPLETION #当为主观题和实训题时, if ex.question_type > Exercise::COMPLETION #当为主观题和实训题时,
ex_answered_scores = effictive_users.score_reviewed.pluck(:score).sum #该问题的全部得分 ex_answered_scores = effictive_users.score_reviewed.pluck(:score).sum #该问题的全部得分
percent = (ex_total_score == 0.0 ? 0.0 : (ex_answered_scores / ex_total_score.to_f).round(3) * 100) #正确率 percent = (ex_total_score == 0.0 ? 0.0 : (ex_answered_scores / ex_total_score.to_f).round(3) * 100) #正确率
end end
# if ex.question_type != Exercise::MULTIPLE
# ex_answered_scores = effictive_users.score_reviewed.pluck(:score).sum #该问题的全部得分
# percent = (ex_total_score == 0.0 ? 0.0 : (ex_answered_scores / ex_total_score.to_f).round(3) * 100) #正确率
# else
# multiple_score = 0
# user_ids.each do |user_id|
# ex_answer_score = ex_answers.select{|answer| answer.user_id == user_id}&.first&.score.to_f
# multiple_score += ex_answer_score
# end
# percent = (ex_total_score == 0.0 ? 0.0 : (multiple_score / ex_total_score.to_f).round(3) * 100) #正确率
# end
question_answer_infos = [] question_answer_infos = []
if ex.question_type <= Exercise::JUDGMENT #选择题和判断题 if ex.question_type <= Exercise::JUDGMENT #选择题和判断题
ex_choices = ex.exercise_choices ex_choices = ex.exercise_choices
@ -178,43 +164,66 @@ module ExercisesHelper
question_answer_infos.push(answer_option) question_answer_infos.push(answer_option)
end end
elsif ex.question_type == Exercise::COMPLETION #填空题 elsif ex.question_type == Exercise::COMPLETION #填空题
effictive_users_ids = effictive_users.where("answer_text is not null and answer_text !=''").pluck(:user_id).uniq
effictive_users_count = effictive_users_ids.size
user_wrong_count = 0
effictive_users_ids.each do |s|
user_score = effictive_users.where(user_id: s).pluck(:score).sum
if user_score.to_f < ex&.question_score.to_f
user_wrong_count = user_wrong_count + 1
end
end
# user_wrong_ids = effictive_users.where()
# user_wrong_count = (user_wrong_ids & effictive_users_ids).uniq.size
ex_ordered = ex.is_ordered ex_ordered = ex.is_ordered
null_standard_answer = ex.exercise_standard_answers null_standard_answer = ex.exercise_standard_answers
null_stand_choice = null_standard_answer.pluck(:exercise_choice_id).uniq #一个exercise_choice_id可能对应多个answer_text null_stand_choice = null_standard_answer.pluck(:exercise_choice_id) #一个exercise_choice_id可能对应多个answer_text
null_stand_text = null_standard_answer.pluck(:answer_text) null_stand_text = null_standard_answer.pluck(:answer_text)
standard_answer_count = 0 standard_answer_count = 0
each_null_score = null_stand_choice.size > 0 ? (ex&.question_score.to_f / null_stand_choice.uniq.size).round(3) : 0.0 each_null_score = null_stand_choice.size > 0 ? (ex&.question_score.to_f / null_stand_choice.uniq.size).round(3) : 0.0
all_user_count = 0 all_user_count = 0
null_stand_choice.each_with_index do |s,index|
user_count = 0 if ex_ordered
if ex_ordered #有序排列 all_user_answers = effictive_users.pluck(:answer_text)
null_stand_choice.each_with_index do |s,index|
s_choice_text = null_stand_text[index] s_choice_text = null_stand_text[index]
user_count = 0
# user_count = user_count + effictive_users.where("exercise_choice_id = ? and answer_text = ?",s,s_choice_text).pluck(:user_id).uniq.size
user_count = user_count + effictive_users.select{|answer| answer.exercise_choice_id == s && answer.answer_text == s_choice_text}.size user_count = user_count + effictive_users.select{|answer| answer.exercise_choice_id == s && answer.answer_text == s_choice_text}.size
else answer_percent = ((effictive_users_count == 0) ? 0.0 : (user_count / effictive_users_count.to_f ).round(3))
null_stand_text = null_stand_text.uniq answer_option = {
s_choice_text = null_stand_text[index]
user_count = user_count + effictive_users.select{|answer| answer.answer_text == s_choice_text }.size #回答了标准答案的用户
end
answer_percent = ((effictive_users_count == 0) ? 0.0 : (user_count / effictive_users_count.to_f ).round(3))
answer_option = {
:choice_position => index+1, :choice_position => index+1,
:choice_text => s_choice_text, :choice_text => s_choice_text,
:choice_users_count => user_count, :choice_users_count => user_count,
:choice_percent => answer_percent.round(2).to_s, :choice_percent => answer_percent.round(2).to_s,
:right_answer => true :right_answer => true
} }
question_answer_infos.push(answer_option) question_answer_infos.push(answer_option)
all_user_count += user_count all_user_count += user_count
standard_answer_count += 1 standard_answer_count += 1
all_user_answers = all_user_answers - [s]
end
else
# cycled_stand = {}
null_stand_text.uniq.each_with_index do |stand, index|
user_count = 0
user_count = user_count + effictive_users.where("answer_text = ?",stand).pluck(:user_id).uniq.size
answer_percent = ((effictive_users_count == 0) ? 0.0 : (user_count / effictive_users_count.to_f ).round(3))
answer_option = {
:choice_position => index+1,
:choice_text => stand,
:choice_users_count => user_count,
:choice_percent => answer_percent.round(2).to_s,
:right_answer => true
}
question_answer_infos.push(answer_option)
all_user_count += user_count
standard_answer_count += 1
end
end end
answer_user_score = all_user_count * each_null_score answer_user_score = all_user_count * each_null_score
percent = (ex_total_score == 0.0 ? 0.0 : (answer_user_score / ex_total_score.to_f).round(3) * 100) #正确率 percent = (ex_total_score == 0.0 ? 0.0 : (answer_user_score / ex_total_score.to_f).round(3) * 100) #正确率
# percent = commit_user_ids > 0 ? (all_user_count / commit_user_ids.to_f).round(3)*100 : 0.0
user_wrong_count = (effictive_users_count - all_user_count)
if effictive_users_count > 0 && user_wrong_count >= 0 if effictive_users_count > 0 && user_wrong_count >= 0
wrong_percent = (user_wrong_count / effictive_users_count.to_f ).round(3) wrong_percent = (user_wrong_count / effictive_users_count.to_f ).round(3)
else else
@ -481,17 +490,28 @@ module ExercisesHelper
end end
end end
else else
st_answer_text = standard_answer_array.pluck(:answer_text).reject(&:blank?).map{|a| a.strip.downcase} st_answer_text = standard_answer_array.pluck(:answer_text).reject(&:blank?).map{|a| a.strip.downcase}.uniq
answers_content.each do |u| answers_content.each do |u|
u_answer_text = u.answer_text.strip.downcase u_answer_text = u.answer_text.strip.downcase
if st_answer_text.include?(u_answer_text) #只要标准答案包含用户的答案,就有分数。同时,下一次循环时,就会删除该标准答案。防止用户的相同答案获分 if st_answer_text.size == 1
u.update_column("score",q_score_2) if st_answer_text.first == u_answer_text
score2 = score2 + q_score_2 u.update_column("score",q_score_2)
st_answer_text.delete(u_answer_text) score2 = score2 + q_score_2
else
u.update_column('score',-1.0)
score2 += 0.0
end
else else
u.update_column('score',-1.0) if st_answer_text.include?(u_answer_text) #只要标准答案包含用户的答案,就有分数。同时,下一次循环时,就会删除该标准答案。防止用户的相同答案获分
score2 += 0.0 u.update_column("score",q_score_2)
score2 = score2 + q_score_2
st_answer_text.delete(u_answer_text)
else
u.update_column('score',-1.0)
score2 += 0.0
end
end end
end end
end end
else else

@ -13,7 +13,7 @@ module PollsHelper
end end
def poll_votes_count(votes,user_ids) def poll_votes_count(votes,user_ids)
votes.find_current_vote("user_id",user_ids.uniq).reject(&:blank?).size votes.find_current_vote("user_id",user_ids.uniq).pluck(:user_id).uniq.reject(&:blank?).size
end end
#公用tab页的相关信息 #公用tab页的相关信息

@ -14,7 +14,7 @@ if @poll_questions_count > 0
json.array! @poll_questions do |question| json.array! @poll_questions do |question|
json.partial! "polls/commit_answers_result", question: question, json.partial! "polls/commit_answers_result", question: question,
answers:question.poll_answers, answers:question.poll_answers,
question_votes:question.poll_votes.where(user_id:@poll_commit_ids) #问题的全部答案 question_votes: question.poll_votes.where(user_id:@poll_commit_ids) #问题的全部答案
end end
end end
else else

@ -0,0 +1,9 @@
class GccCourseCompetitionRankData < ActiveRecord::Migration[5.2]
def change
competition = Competition.find_by(identifier: 'gcc-course-2019')
stage = competition.competition_stages.first
return if competition.blank? || stage.blank?
competition.competition_scores.update_all(competition_stage_id: stage.id)
end
end

@ -246,13 +246,13 @@ class PollDetailTabFirst extends Component{
dataIndex: 'No', dataIndex: 'No',
key: 'No', key: 'No',
className:"edu-txt-center", className:"edu-txt-center",
width:110 width:120
}, { }, {
title: '姓名', title: '姓名',
dataIndex: 'name', dataIndex: 'name',
key: 'name', key: 'name',
className:"edu-txt-center", className:"edu-txt-center",
width:160 width:170
}, { }, {
title: '学号', title: '学号',
dataIndex: 'StudentNo', dataIndex: 'StudentNo',
@ -269,11 +269,11 @@ class PollDetailTabFirst extends Component{
title: '分班', title: '分班',
key: 'classes', key: 'classes',
dataIndex: 'classes', dataIndex: 'classes',
width:160, width:220,
className:poll_types && poll_types.groups_count > 0 ? "edu-txt-center":"edu-txt-center none", className:poll_types && poll_types.groups_count > 0 ? "edu-txt-center":"edu-txt-center none",
render:(classes,item,index)=>{ render:(classes,item,index)=>{
return( return(
item.classes ? <span>{item.classes}</span> : <span className="color-grey-9">--</span> item.classes ? <span style={{maxWidth:'208px',display:"block"}} title={item.classes} className="task-hide">{item.classes}</span> : <span className="color-grey-9">--</span>
) )
} }
}, { }, {
@ -281,7 +281,7 @@ class PollDetailTabFirst extends Component{
dataIndex: 'status', dataIndex: 'status',
key: 'status', key: 'status',
className:"edu-txt-center", className:"edu-txt-center",
width:160, width:170,
render:(status,item,index)=>{ render:(status,item,index)=>{
return( return(
item.status == 1 ?<span className='color-green'>按时提交</span>:<span></span> item.status == 1 ?<span className='color-green'>按时提交</span>:<span></span>
@ -292,7 +292,7 @@ class PollDetailTabFirst extends Component{
dataIndex: 'time', dataIndex: 'time',
key: 'time', key: 'time',
className:"edu-txt-center", className:"edu-txt-center",
width:160, width:170,
sorter: true, sorter: true,
defaultSortOrder: 'descend', defaultSortOrder: 'descend',
sortDirections: sortDirections, sortDirections: sortDirections,
@ -395,7 +395,7 @@ class PollDetailTabFirst extends Component{
{/* </div>*/} {/* </div>*/}
{/*}*/} {/*}*/}
</div>} </div>}
<div className="edu-table edu-back-white minH-560"> <div className="edu-table edu-back-white minH-560 pollResultList">
{ {
data && data.length > 0 ? <Table columns={columns} dataSource={data} pagination={false} data && data.length > 0 ? <Table columns={columns} dataSource={data} pagination={false}
onChange={this.table1handleChange}></Table> : <NoneData></NoneData> onChange={this.table1handleChange}></Table> : <NoneData></NoneData>

@ -338,7 +338,9 @@ textarea:read-only{
border:1px solid #FF0000; border:1px solid #FF0000;
border-radius: 5px; border-radius: 5px;
} }
.pollResultList .ant-table-thead > tr > th,.pollResultList .ant-table-tbody > tr > td{
padding:15px 6px;
}
/* 试卷 */ /* 试卷 */
.setScoreInput{ .setScoreInput{
width: 60px!important;height: 30px!important;box-sizing: border-box; width: 60px!important;height: 30px!important;box-sizing: border-box;

@ -118,21 +118,24 @@ class ShixunsHome extends Component {
let shixuntype=false; let shixuntype=false;
let pathstype=false; let pathstype=false;
if(this.props&&this.props.mygetHelmetapi!=null){ if(this.props&&this.props.mygetHelmetapi!=null){
console.log(this.props.mygetHelmetapi.navbar)
let shixun="/shixuns"; let shixun="/shixuns";
let paths="/paths"; let paths="/paths";
this.props.mygetHelmetapi.navbar.map((item,key)=>{ this.props.mygetHelmetapi.navbar.map((item,key)=>{
var reg = RegExp(item.link); var reg = RegExp(item.link);
if(shixun.match(reg)){ if(shixun.match(reg)){
shixuntype=true if(item.hidden===true){
shixuntype=true
}
} }
if(paths.match(reg)){ if(paths.match(reg)){
pathstype=true if(item.hidden===true){
pathstype=true
}
} }
}) })
}
}
return ( return (
<div className="newMain clearfix backFAFAFA shixunsHome"> <div className="newMain clearfix backFAFAFA shixunsHome">
{this.state.updata===undefined?"":<UpgradeModals {this.state.updata===undefined?"":<UpgradeModals
@ -232,7 +235,7 @@ class ShixunsHome extends Component {
</div> </div>
{/*实训路径*/} {/*实训路径*/}
{pathstype===true?<div className="clearfix pt20 educontent pr pb20"> {pathstype===true?"":<div className="clearfix pt20 educontent pr pb20">
<div className="edu-txt-center"> <div className="edu-txt-center">
<p className="color-dark edu-txt-center font-24" style={{lineHeight: '30px'}}>实践课程</p> <p className="color-dark edu-txt-center font-24" style={{lineHeight: '30px'}}>实践课程</p>
<p className="color-grey-cd font-12">TRAINING COURSE</p> <p className="color-grey-cd font-12">TRAINING COURSE</p>
@ -308,10 +311,10 @@ class ShixunsHome extends Component {
} }
</div> </div>
</div>:""} </div>}
{/*精选实训 改为 开发社区*/} {/*精选实训 改为 开发社区*/}
{shixuntype===true?<div className="clearfix pt20 educontent pr pb20"> {shixuntype===true?"":<div className="clearfix pt20 educontent pr pb20">
<div className="edu-txt-center"> <div className="edu-txt-center">
<p className="color-dark edu-txt-center font-24" style={{lineHeight: '30px'}}>实训项目</p> <p className="color-dark edu-txt-center font-24" style={{lineHeight: '30px'}}>实训项目</p>
<p className="color-grey-cd font-12">DEVELOPMENT COMMUNITY</p> <p className="color-grey-cd font-12">DEVELOPMENT COMMUNITY</p>
@ -403,7 +406,7 @@ class ShixunsHome extends Component {
</div> </div>
</div>:""} </div>}

@ -77,7 +77,7 @@
} }
.Breadcrumbfont{ .Breadcrumbfont{
color:#4CACFF; color:#4CACFF !important;
} }
.ant-breadcrumb-separator{ .ant-breadcrumb-separator{

@ -20,6 +20,7 @@ class Osshackathon extends Component {
hackathonedit:false, hackathonedit:false,
Osshackathonmodeltype:false, Osshackathonmodeltype:false,
spinning:false, spinning:false,
opentitletype:true
} }
} }
@ -218,8 +219,14 @@ class Osshackathon extends Component {
search:e.target.value search:e.target.value
}) })
} }
opentitle=()=>{
this.setState({
opentitletype:false
})
}
render() { render() {
let {page,data,hackathonedit}=this.state; let {page,data,hackathonedit,opentitletype}=this.state;
return ( return (
@ -288,11 +295,23 @@ class Osshackathon extends Component {
{hackathonedit===true?"":<Divider />} {hackathonedit===true?"":<Divider />}
{opentitletype===true?<style>
{
`
.Osshackathonfontlist{
height: 180px;
overflow: hidden;
}
`
}
</style>:""}
{hackathonedit===true?"":<p className={"Osshackathonfontlist mb30"}> {hackathonedit===true?"":<p className={"Osshackathonfontlist mb30"}>
{data&&data.hackathon.description===null?"":<div className={"markdown-body"} {data&&data.hackathon.description===null?"":<div className={"markdown-body"}
dangerouslySetInnerHTML={{__html: markdownToHTML(data&&data.hackathon.description).replace(/▁/g, "▁▁▁")}}></div>} dangerouslySetInnerHTML={{__html: markdownToHTML(data&&data.hackathon.description).replace(/▁/g, "▁▁▁")}}></div>}
</p>} </p>}
{opentitletype===true?<Divider dashed={true} onClick={()=>this.opentitle()} className={"pointer Breadcrumbfont"}>展开阅读全文<Icon type="down" /></Divider>:""}
{hackathonedit===true?<Osshackathonmd {hackathonedit===true?<Osshackathonmd
getosshackathon={()=>this.getosshackathonlist()} getosshackathon={()=>this.getosshackathonlist()}
hidehackathonedit={()=>this.hidehackathonedit()} hidehackathonedit={()=>this.hidehackathonedit()}
@ -305,7 +324,7 @@ class Osshackathon extends Component {
{...this.props} {...this.props}
{...this.state} {...this.state}
/>:""} />:""}
{this.props.user&&this.props.user.admin===true?<Row className={"mb20"}> {this.props.user&&this.props.user.admin===true?<Row className={"mb20 mt30"}>
<Col span={8}></Col> <Col span={8}></Col>
<Col span={8}><Button type="primary" className={"OsshackprimaryButton OsshackprimaryButtonsyle"} onClick={()=>this.editSignupentry()}><Icon type="plus" />新建项目</Button></Col> <Col span={8}><Button type="primary" className={"OsshackprimaryButton OsshackprimaryButtonsyle"} onClick={()=>this.editSignupentry()}><Icon type="plus" />新建项目</Button></Col>
<Col span={8}></Col> <Col span={8}></Col>

@ -875,8 +875,33 @@ submittojoinclass=(value)=>{
// console.log("NewHeadergetHelmetapi432423423423"); // console.log("NewHeadergetHelmetapi432423423423");
// console.log(mygetHelmetapi2); // console.log(mygetHelmetapi2);
// console.log("NewHeadermygetHelmetapi123123123123"); // console.log("NewHeadermygetHelmetapi123123123123");
// console.log(mygetHelmetapi2);
let shixuntype=false;
let pathstype=false;
let coursestypes=false;
if(this.props&&this.props.mygetHelmetapi!=null){
let shixun="/shixuns";
let paths="/paths";
let courses="/courses";
this.props.mygetHelmetapi.navbar.map((item,key)=>{
var reg = RegExp(item.link);
if(shixun.match(reg)){
if(item.hidden===true){
shixuntype=true
}
}
if(paths.match(reg)){
if(item.hidden===true){
pathstype=true
}
}
if(courses.match(reg)){
if(item.hidden===true){
coursestypes=true
}
}
})
}
return ( return (
<div className="newHeaders" id="nHeader" > <div className="newHeaders" id="nHeader" >
@ -1260,18 +1285,18 @@ submittojoinclass=(value)=>{
<div className="edu-menu-list" style={{top: '60px',width:"240px"}}> <div className="edu-menu-list" style={{top: '60px',width:"240px"}}>
<div className="overPart"></div> <div className="overPart"></div>
<ul className="fl with50 edu-txt-center pr ul-leftline"> <ul className="fl with50 edu-txt-center pr ul-leftline">
{this.props.current_user&&this.props.current_user.user_identity==="学生"?"":<li><a onClick={(url)=>this.getUser("/courses/new")}>新建翻转课堂</a></li>} {this.props.current_user&&this.props.current_user.user_identity==="学生"?"":coursestypes===true?"":<li><a onClick={(url)=>this.getUser("/courses/new")}>新建翻转课堂</a></li>}
<li><a onClick={(url)=>this.getUser("/shixuns/new")}>新建实训项目</a></li> {shixuntype===true?"":<li><a onClick={(url)=>this.getUser("/shixuns/new")}>新建实训项目</a></li>}
{this.props.Headertop===undefined?"": {this.props.Headertop===undefined?"":
<li><a onClick={(url)=>this.getUser("/paths/new")} >新建实践课程</a></li> pathstype===true?"":<li><a onClick={(url)=>this.getUser("/paths/new")} >新建实践课程</a></li>
} }
<li><a onClick={(url)=>this.getUser("/projects/new","projects")} target="_blank">新建开发项目</a></li> <li><a onClick={(url)=>this.getUser("/projects/new","projects")} target="_blank">新建开发项目</a></li>
</ul> </ul>
<ul className="fl with50 edu-txt-center"> <ul className="fl with50 edu-txt-center">
<li> {coursestypes===true?"":<li>
<a onClick={this.tojoinclass}>加入翻转课堂</a> <a onClick={this.tojoinclass}>加入翻转课堂</a>
</li> </li>}
{Addcoursestypes===true?<Addcourses {Addcoursestypes===true?<Addcourses
Addcoursestype={Addcoursestypes} Addcoursestype={Addcoursestypes}

@ -34,6 +34,32 @@ class InfosBanner extends Component{
// console.log(is_current) // console.log(is_current)
// console.log(current_user) // console.log(current_user)
// console.log(current_user.is_teacher) // console.log(current_user.is_teacher)
let shixuntype=false;
let pathstype=false;
let coursestypes=false;
if(this.props&&this.props.mygetHelmetapi!=null){
let shixun="/shixuns";
let paths="/paths";
let courses="/courses";
this.props.mygetHelmetapi.navbar.map((item,key)=>{
var reg = RegExp(item.link);
if(shixun.match(reg)){
if(item.hidden===true){
shixuntype=true
}
}
if(paths.match(reg)){
if(item.hidden===true){
pathstype=true
}
}
if(courses.match(reg)){
if(item.hidden===true){
coursestypes=true
}
}
})
}
return( return(
<div className="bannerPanel mb60"> <div className="bannerPanel mb60">
@ -91,21 +117,21 @@ class InfosBanner extends Component{
</div> </div>
</div> </div>
<div className="userNav"> <div className="userNav">
<li className={`${moduleName == 'courses' ||moduleName == undefined ? 'active' : '' }`}> {coursestypes===true?"":<li className={`${moduleName == 'courses' ||moduleName == undefined ? 'active' : '' }`}>
<Link <Link
onClick={() => this.setState({moduleName: 'courses'})} onClick={() => this.setState({moduleName: 'courses'})}
to={`/users/${username}/courses`}>翻转课堂</Link> to={`/users/${username}/courses`}>翻转课堂</Link>
</li> </li>}
<li className={`${moduleName == 'shixuns' ? 'active' : '' }`}> {shixuntype===true?"":<li className={`${moduleName == 'shixuns' ? 'active' : '' }`}>
<Link <Link
onClick={() => this.setState({moduleName: 'shixuns'})} onClick={() => this.setState({moduleName: 'shixuns'})}
to={`/users/${username}/shixuns`}>实训项目</Link> to={`/users/${username}/shixuns`}>实训项目</Link>
</li> </li>}
<li className={`${moduleName == 'paths' ? 'active' : '' }`}> {pathstype===true?"":<li className={`${moduleName == 'paths' ? 'active' : '' }`}>
<Link <Link
onClick={() => this.setState({moduleName: 'paths'})} onClick={() => this.setState({moduleName: 'paths'})}
to={`/users/${username}/paths`}>实践课程</Link> to={`/users/${username}/paths`}>实践课程</Link>
</li> </li>}
<li className={`${moduleName == 'projects' ? 'active' : '' }`}> <li className={`${moduleName == 'projects' ? 'active' : '' }`}>
<Link <Link
onClick={() => this.setState({moduleName: 'projects'})} onClick={() => this.setState({moduleName: 'projects'})}

Loading…
Cancel
Save