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

dev_oauth
杨树林 6 years ago
commit 3e88829d01

@ -239,7 +239,7 @@ class ApplicationController < ActionController::Base
uid_logger("user_setup: " + (User.current.logged? ? "#{User.current.try(:login)} (id=#{User.current.try(:id)})" : "anonymous"))
if !User.current.logged? && Rails.env.development?
User.current = User.find 8686
User.current = User.find 1
end

@ -14,7 +14,7 @@ module RenderExpand
kit.stylesheets << Rails.root.join('app/templates', path)
end
send_data kit.to_pdf, filename: options[:filename], type: 'application/pdf'
send_data kit.to_pdf, filename: options[:filename], disposition: options[:disposition] || 'attachment', type: 'application/pdf'
end
end
end

@ -1291,7 +1291,7 @@ class ExercisesController < ApplicationController
normal_status(0,"正在下载中")
else
set_export_cookies
render pdf: 'exercise_export/blank_exercise', filename: filename_, stylesheets: stylesheets
render pdf: 'exercise_export/blank_exercise', filename: filename_, stylesheets: stylesheets, disposition: 'inline', type:"pdf_attachment.content_type",stream:false
end
end

@ -260,7 +260,12 @@ class FilesController < ApplicationController
return normal_status(-2, "该课程下没有id为 #{params[:id]}的资源") if @file.nil?
return normal_status(403, "您没有权限进行该操作") if @user != @file.author && !@user.teacher_of_course?(@course) && !@file.public?
@is_pdf = false
file_content_type = @file.content_type
file_ext_type = File.extname(@file.filename).strip.downcase[1..-1]
if (file_content_type.present? && file_content_type.downcase.include?("pdf")) || (file_ext_type.present? && file_ext_type.include?("pdf"))
@is_pdf = true
end
@attachment_histories = @file.attachment_histories
end

@ -4,7 +4,7 @@ class StudentWorksController < ApplicationController
before_action :require_login, :check_auth
before_action :find_homework, only: [:new, :create, :search_member_list, :check_project, :relate_project,
:cancel_relate_project]
:cancel_relate_project, :delete_work]
before_action :find_work, only: [:shixun_work_report, :adjust_review_score, :shixun_work, :commit_des, :update_des,
:adjust_score, :show, :adjust_score, :supply_attachments, :revise_attachment,
:comment_list, :add_score, :add_score_reply, :destroy_score, :appeal_anonymous_score,
@ -15,12 +15,12 @@ class StudentWorksController < ApplicationController
before_action :teacher_allowed, only: [:adjust_score, :adjust_review_score, :deal_appeal_score]
before_action :course_student, only: [:new, :commit_des, :update_des, :create, :edit, :update, :search_member_list, :relate_project,
:cancel_relate_project, :relate_project]
:cancel_relate_project, :relate_project, :delete_work]
before_action :my_work, only: [:commit_des, :update_des, :edit, :update, :revise_attachment, :appeal_anonymous_score,
:cancel_appeal]
before_action :edit_duration, only: [:edit, :update]
before_action :edit_duration, only: [:edit, :update, :delete_work]
before_action :end_or_late, only: [:new, :create, :search_member_list, :commit_des, :update_des]
before_action :require_score_id, only: [:destroy_score, :add_score_reply, :appeal_anonymous_score, :deal_appeal_score, :cancel_appeal]
@ -60,6 +60,20 @@ class StudentWorksController < ApplicationController
@members = @members.page(page).per(limit).includes(:course_group, user: :user_extension)
end
def delete_work
begin
work = @homework.student_works.find_by!(user_id: params[:user_id])
work.update_attributes(description: nil, project_id: 0,
late_penalty: 0, work_status: 0,
commit_time: nil, update_time: nil, group_id: 0,
commit_user_id: nil, final_score: nil, work_score: nil, teacher_score: nil, teaching_asistant_score: nil)
normal_status("删除成功")
rescue Exception => e
uid_logger(e.message)
tip_exception(e.message)
end
end
def create
student_work = @homework.student_works.find_or_create_by(user_id: current_user.id)
@ -460,7 +474,7 @@ class StudentWorksController < ApplicationController
filename_ = "#{@use&.student_id}_#{@use&.real_name}_#{@shixun&.name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}"
filename = Base64.urlsafe_encode64(filename_.strip)
stylesheets = %w(shixun_work/shixun_work.css shared/codemirror.css)
render pdf: 'shixun_work/shixun_work', filename: filename, stylesheets: stylesheets
render pdf: 'shixun_work/shixun_work', filename: filename, stylesheets: stylesheets, disposition: 'inline', type:"pdf_attachment.content_type",stream:false
end
# 作品调分

@ -146,8 +146,8 @@ module ExportHelper
w_6 = "--"
end
w_7 = w.work_status == 0 ? '--' : myshixun.try(:passed_count).to_s+"/"+shixun.challenges_count.to_s
w_8 = myshixun ? myshixun.try(:passed_time) == "--" ? "--" : format_time(myshixun.try(:passed_time)) : "--" # 通关时间
w_9 = myshixun ? (myshixun.try(:passed_count) > 0 ? myshixun.total_spend_time : '--') : "--" #总耗时
w_8 = myshixun ? myshixun.try(:passed_time).to_s == "--" ? "--" : format_time(myshixun.try(:passed_time)) : "--" # 通关时间
w_9 = myshixun ? (myshixun.try(:passed_count).to_i > 0 ? myshixun.total_spend_time : '--') : "--" #总耗时
w_10 = myshixun ? myshixun.output_times : 0 #评测次数
w_11 = myshixun ? myshixun.total_score : "--" #获得经验值
w_12 = w.final_score.present? ? w.final_score : 0
@ -543,7 +543,7 @@ module ExportHelper
end
def format_sheet_name name
name = name.gsub(":", "-")
name = name.gsub(":", "-").gsub("/", "_")
end
def rename_same_file(name, index)

@ -82,7 +82,7 @@ class Myshixun < ApplicationRecord
# 通关时间
def passed_time
self.status == 1 ? self.games.map(&:end_time).max : "--"
self.status == 1 ? self.games.select{|game| game.status == 2}.map(&:end_time).max : "--"
end
# 耗时

@ -0,0 +1,3 @@
class Partner < ApplicationRecord
has_many :users
end

@ -21,8 +21,8 @@ module Searchable::Course
def to_searchable_json
{
id: id,
author_name: teacher.real_name,
author_school_name: teacher.school_name,
author_name: teacher&.real_name,
author_school_name: teacher&.school_name,
visits_count: visits,
members_count: members_count,
is_public: is_public == 1

@ -138,6 +138,9 @@ class User < ApplicationRecord
# 视频
has_many :videos, dependent: :destroy
# 客户管理
belongs_to :partner
# Groups and active users
scope :active, lambda { where(status: STATUS_ACTIVE) }

@ -1,2 +1,3 @@
json.is_pdf @is_pdf
json.partial! 'attachments/attachment_small', attachment: @file
json.partial! "attachment_histories/list", attachment_histories: @attachment_histories

@ -1,4 +1,4 @@
json.id user.id
json.name user.full_name
json.name user.real_name
json.login user.login
json.image_url url_to_avatar(user)

@ -16,6 +16,9 @@ json.top do
json.moop_cases_url "#{@old_domain}/moop_cases"
json.crowdsourcing_url "/crowdsourcing"
# 客户管理
json.customer_management_url current_user.partner ? "#{@old_domain}/cooperates/#{current_user.partner.try(:id)}/partner_list" : nil
json.career_url do
json.array! @career.to_a do |c|
if c[1].present?

@ -0,0 +1,16 @@
defaults: &defaults
access_key_id: 'test'
access_key_secret: 'test'
base_url: 'http://vod.cn-shanghai.aliyuncs.com'
cate_id: '-1'
callback_url: 'http://47.96.87.25:48080/api/callbacks/aliyun_vod.json'
signature_key: 'test12345678'
development:
<<: *defaults
test:
<<: *defaults
production:
<<: *defaults

@ -436,6 +436,7 @@ Rails.application.routes.draw do
get :check_project
get :cancel_relate_project
post :relate_project
delete :delete_work
end
end
end

@ -0,0 +1,8 @@
class ModifyClassPeriodForCourses < ActiveRecord::Migration[5.2]
def change
Course.find_each do |c|
c.update_column(:class_period, c.class_period.to_i)
end
change_column :courses, :class_period, :integer
end
end

@ -261,9 +261,9 @@ class Fileslistitem extends Component{
</p>}
<p className="color-grey panel-lightgrey mt8 fl ml30" style={{width:'100%'}}>
<p className={this.props.isAdmin===true?"color-grey panel-lightgrey mt8 fl ml30":"color-grey panel-lightgrey mt8 fl ml13"} style={{width:'100%'}}>
<span className="mr50">
<span className="mr15 color-dark">{discussMessage.author.login}</span>
<span className="mr15 color-dark">{discussMessage.author.name}</span>
<span className="mr15 color-grey9">大小 {discussMessage.filesize}</span>
<span className="mr15 color-grey9">下载 {discussMessage.downloads_count}</span>
<span className="mr15 color-grey9">引用 {discussMessage.quotes}</span>
@ -302,7 +302,7 @@ class Fileslistitem extends Component{
<p className="color-grey panel-lightgrey mt8 fl ml30" style={{width:'100%'}}>
<p className={this.props.isAdmin===true?"color-grey panel-lightgrey mt8 fl ml30":"color-grey panel-lightgrey mt8 fl ml13"} style={{width:'100%'}}>
<pre className="color-dark">资源描述 :{discussMessage.description===null?"暂无描述":discussMessage.description}</pre>
{/*<span className="mr50">*/}
{/*/!*<span className="mr15 color-dark"></span>*!/*/}

@ -5,6 +5,8 @@ import TPMMDEditor from '../../tpm/challengesnew/TPMMDEditor';
import { WordsBtn, getUploadActionUrl, appendFileSizeToUploadFile, appendFileSizeToUploadFileAll } from 'educoder';
import axios from 'axios';
import Modals from '../../modals/Modals';
import _ from 'lodash'
const Search = Input.Search;
const CheckboxGroup = Checkbox.Group;
@ -67,15 +69,19 @@ class CommonWorkPost extends Component{
status: 'done'
}
})
const _memebers = response.data.members.slice(0);
this._edit_init_memebers = _memebers
delete response.data.members;
this.setState({
...response.data,
selectmemberslist: response.data.members || [],
selectmemberslist: _memebers || [],
// members: [],
task_status: response.data.members ? response.data.members.map(item => item.user_id) : [],
task_status: [], //_memebers ? _memebers.map(item => item.user_id) : [],
fileList: _fileList,
memberNumMin: response.data.min_num,
memberNumMax: response.data.max_num,
})
this.mine = _memebers.length ? _memebers[0] : null
// 分组
// this.setState({
// task_status:checkedValues,
@ -99,6 +105,11 @@ class CommonWorkPost extends Component{
group_name: response.data.group_name,
}
this.mine = mine
// const _memebers = response.data.members.slice(0);
if (response.data.members) {
delete response.data.members;
}
this.setState({
...response.data,
selectmemberslist: [mine],
@ -157,7 +168,7 @@ class CommonWorkPost extends Component{
}
if(isGroup){
if(userids!=undefined){
if(userids.length + 1<memberNumMin){
if(userids.length < memberNumMin){
this.setState({
minvalue: memberNumMin,
setvalue:"小于",
@ -165,7 +176,7 @@ class CommonWorkPost extends Component{
})
return
}else if(userids.length + 1>memberNumMax){
}else if(userids.length > memberNumMax){
this.setState({
minvalue: memberNumMax,
setvalue:"大于",
@ -424,30 +435,53 @@ class CommonWorkPost extends Component{
}
funtaskstatus=(checkedValues)=>{
let{members}=this.state;
let newlist =members.concat(this.state.selectmemberslist);
let newcheckedValues=checkedValues;
let selects=[];
// const selectobjct = this._findByUserId(check)
// selects.push(selectobjct)
for(var z=0; z<newcheckedValues.length; z++){
for(var i=0; i<newlist.length; i++){
if(newlist[i].user_id===newcheckedValues[z]){
selects.push(newlist[i])
break;
/**
比较 checkedValues this.state.selectmemberslist
checkedValues length > this.state.task_status.length 是新增 反之是删除
比较找到不同的id
去除重复的checkedValues留下的是新增task_status留下的是删除
*/
const _checkedValues = checkedValues.slice(0)
const _task_status = this.state.task_status.slice(0);
checkedValues.forEach(item => {
this.state.task_status.forEach(_item => {
if (item == _item) {
_.remove(_checkedValues, (item)=> item == _item)
_.remove(_task_status, (item)=> item == _item)
}
}
}
})
})
let _selectmemberslist = this.state.selectmemberslist.slice(0)
if (_checkedValues.length) { // 新增
_selectmemberslist.push( this.state.members.filter(item => item.user_id == _checkedValues[0])[0])
} else if (_task_status.length) { // 删除
_.remove(_selectmemberslist, (item)=> item.user_id == _task_status[0])
}
// let{members}=this.state;
// let newlist =members.concat(this.state.selectmemberslist);
// let newcheckedValues=checkedValues;
// let selects= this.mine ? [this.mine] : [];
// // const selectobjct = this._findByUserId(check)
// // selects.push(selectobjct)
// for(var z=0; z<newcheckedValues.length; z++){
// for(var i=0; i<newlist.length; i++){
// if(newlist[i].user_id===newcheckedValues[z]){
// selects.push(newlist[i])
// break;
// }
// }
// }
this.setState({
task_status:checkedValues,
selectmemberslist: selects
selectmemberslist: _selectmemberslist
// selectmemberslist:checkedValues
})
}
delecttask_status=(id)=>{
doDelete = (id) => {
let{selectmemberslist,task_status}=this.state;
let newlist=task_status.slice(0);
let selects=selectmemberslist;
@ -468,6 +502,52 @@ class CommonWorkPost extends Component{
selectmemberslist:selects
})
}
delecttask_status=(id)=>{
if (this.isEdit) {
let deleteOldMemberIndex = -1;
if (this._edit_init_memebers && this._edit_init_memebers.length) {
this._edit_init_memebers.some((item, index) => {
if (item.user_id == id) {
deleteOldMemberIndex = index;
return true
}
})
if (deleteOldMemberIndex == -1) {
this.doDelete(id)
return;
} else {
}
}
this.props.confirm({
content: <div>
<div>TA的作品将被删除</div>
<div>是否确认删除</div>
</div>,
onOk: () => {
let workId=this.props.match.params.workId;
const url = `/homework_commons/${workId}/student_works/delete_work.json`;
axios.delete(url, { data: {
user_id: id
}})
.then((response) => {
if (response.data.status == 0) {
this.searchValue()
this.doDelete(id)
deleteOldMemberIndex != -1 && this._edit_init_memebers.splice(deleteOldMemberIndex, 1)
}
})
.catch(function (error) {
console.log(error);
});
}
})
} else {
this.doDelete(id)
}
}
gocannel=()=>{
this.props.history.goBack()

@ -336,6 +336,16 @@ class ExerciseReviewAndAnswer extends Component{
}
// 选择题,切换答案
changeOption = (index,ids) =>{
//console.log(index+" "+ids);
this.setState(
(prevState) => ({
exercise_questions : update(prevState.exercise_questions, {[index]: { user_answer: {$set: ids} }}),
})
)
}
//简答题 显示和隐藏答案
changeA_flag=(index,status)=>{
this.setState(
@ -726,6 +736,7 @@ class ExerciseReviewAndAnswer extends Component{
exercise={exercise}
questionType={item}
user_exercise_status={user_exercise_status}
changeOption={(index,ids)=>this.changeOption(index,ids)}
changeQuestionStatus={(No,flag)=>this.changeQuestionStatus(No,flag)}
index={key}
></Single>
@ -739,6 +750,7 @@ class ExerciseReviewAndAnswer extends Component{
exercise={exercise}
questionType={item}
user_exercise_status={user_exercise_status}
changeOption={(index,ids)=>this.changeOption(index,ids)}
changeQuestionStatus={(No,flag)=>this.changeQuestionStatus(No,flag)}
index={key}

@ -163,6 +163,10 @@ class Testpapersettinghomepage extends Component{
}
}
//打开pdf
confpdf = (url) =>{
window.open(url);
}
/// 确认是否下载
confirmysl(url,child){
let params ={}
@ -372,7 +376,7 @@ class Testpapersettinghomepage extends Component{
导出<i className="iconfont icon-xiajiantou font-12 ml2"></i>
<ul className="drop_down_menu" style={{"right":"-34px","left":"unset","height":"auto"}}>
<li><a onClick={()=>this.confirmysl(`/exercises/${this.props.match.params.Id}/exercise_lists.xlsx`,this.child)}>学生成绩</a></li>
<li><a onClick={()=>this.confirmysl(`/exercises/${this.props.match.params.Id}/export_exercise`,this.child)} >空白试卷</a></li>
<li><a onClick={()=>this.confpdf(`/api/exercises/${this.props.match.params.Id}/export_exercise`)} >空白试卷</a></li>
{/*<li><a onClick={()=>this.confirmysl(`/zip/export_exercises?exercise_id=${this.props.match.params.Id}${this.state.groupyslsval===null||this.state.groupyslsval===undefined?null:this.state.groupyslsval}`)}>学生答题试卷</a></li>*/}
</ul>
</li></Spin>:""}

@ -15,6 +15,7 @@ class Multiple extends Component{
saveId=(value)=>{
let question_id=this.props.questionType.question_id;
let url=`/exercise_questions/${question_id}/exercise_answers.json`;
let {index}=this.props;
axios.post((url),{
exercise_choice_id:value
}).then((result)=>{
@ -25,6 +26,7 @@ class Multiple extends Component{
}else{
k=0;
}
this.props.changeOption && this.props.changeOption(index,value);
this.props.changeQuestionStatus && this.props.changeQuestionStatus(parseInt(this.props.questionType.q_position)-1,k);
}
}).catch((error)=>{
@ -42,14 +44,14 @@ class Multiple extends Component{
console.log(questionType);
return(
<div className="pl30 pr30 singleDisplay">
<Checkbox.Group disabled={ user_exercise_status == 1 ? true : false } onChange={this.saveId} defaultValue={questionType.user_answer}>
<Checkbox.Group disabled={ user_exercise_status == 1 ? true : false } onChange={this.saveId} value={questionType.user_answer}>
{
questionType.question_choices && questionType.question_choices.map((item,key)=>{
let prefix = `${tagArray[key]}.`
return(
<p className="clearfix mb15 df">
<Checkbox className="fl lineh-20 " value={item.choice_id}>{prefix}</Checkbox>
<Checkbox className="fl lineh-15 df mr8 mt2" value={item.choice_id}>{prefix}</Checkbox>
{/* <span class="fl lineh-20 mt1"></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)}

@ -16,11 +16,13 @@ class single extends Component{
changeItem=(e)=>{
let choiceId=e.target.value;
let question_id=this.props.questionType.question_id;
let {index}=this.props;
let url=`/exercise_questions/${question_id}/exercise_answers.json`;
axios.post((url),{
exercise_choice_id:choiceId
}).then((result)=>{
if(result){
this.props.changeOption && this.props.changeOption(index,[choiceId]);
this.props.changeQuestionStatus && this.props.changeQuestionStatus(parseInt(this.props.questionType.q_position)-1,1);
}
}).catch((error)=>{
@ -38,12 +40,12 @@ class single extends Component{
let isJudge = questionType.question_type == 2
return(
<div className="pl30 pr30 singleDisplay">
<Radio.Group disabled={ user_exercise_status == 1 ? true : false } defaultValue={questionType.user_answer[0]} onChange={this.changeItem}>
<Radio.Group disabled={ user_exercise_status == 1 ? true : false } value={questionType.user_answer[0]} onChange={this.changeItem}>
{
questionType.question_choices && questionType.question_choices.map((item,key)=>{
let prefix = isJudge ? undefined : `${tagArray[key]}.`
return(
<p className={parseInt(questionType.question_type) == 0 ? "clearfix mb15 df" : "fl mr40"}>
<p className={parseInt(questionType.question_type) == 0 ? "clearfix mb15 df" : "fl mr40 df"}>
<Radio className="fl lineh-20" value={item.choice_id}>{prefix}</Radio>
{/* <span className="fl lineh-20 mr3 "></span> */}
{/* <span style={{display:"inline-block", 'margin-top': '-1px'}} className="markdown-body fl " dangerouslySetInnerHTML={{__html: markdownToHTML1(item.choice_text)}}></span> */}

@ -439,10 +439,24 @@ class GraduationTasksSubmitnew extends Component{
).then((response) => {
this.setState({
spinnings:false
})
if(response!==undefined){
this.goback()
});
// /courses/2915/graduation_tasks/1301/appraise
// window.location.href
if(response){
if(response.data){
if(response.data.work_id){
window.location.href=`/courses/${this.props.match.params.coursesId}/graduation_tasks/${response.data.work_id}/appraise`
}
}
}
// console.log(this.props);
// console.log(response);
// 新需求
// https://www.trustie.net/issues/23015
// if(response!==undefined){
// this.goback()
// }
// if(response.status===200) {
// GraduationTasksnewtype=false;
// if(response.data.status===0){

@ -367,9 +367,9 @@ class Listofworksstudentone extends Component {
render: (text, record) => (
<span>
{
record.submitstate === "未提交" ?<span style={{ color: '#9A9A9A'}}>--</span>
record.submitstate === "未提交" ?<span style={{ color: '#9A9A9A',cursor:"default"}}>--</span>
:
<span style={{"text-align": "center"}}
<span style={{textAlign: "center",cursor:"default"}}
className="color-blue"
onClick={() => this.Viewstudenttraininginformation(record)}>{record.operating}</span>
}
@ -691,9 +691,9 @@ class Listofworksstudentone extends Component {
align: 'center',
className:'font-14',
render: (text, record) => (
record.submitstate === "未提交" ? <span style={{ color: '#9A9A9A'}}>--</span> :
record.submitstate === "未提交" ? <span style={{ color: '#9A9A9A',cursor:"default"}}>--</span> :
<span>
<a style={{"text-align": "center"}} className="color-blue"
<a style={{textAlign: "center",cursor:"default"}} className="color-blue"
onClick={() => this.Viewstudenttraininginformationt(record)}>{record.operating}</a>
</span>
)
@ -985,9 +985,9 @@ class Listofworksstudentone extends Component {
align: 'center',
className:'font-14',
render: (text, record) => (
record.submitstate === "未提交" ? <span style={{ color: '#9A9A9A'}}>--</span> :
record.submitstate === "未提交" ? <span style={{ color: '#9A9A9A',cursor:"default"}}>--</span> :
<span>
<a style={{"text-align": "center"}} className="color-blue"
<a style={{textAlign: "center",cursor:"default"}} className="color-blue"
onClick={() => this.Viewstudenttraininginformationt(record)}>{record.operating}</a>
</span>
)

@ -686,6 +686,7 @@ class ShixunHomework extends Component{
ModalSave:this.cancelmodel,
Loadtype:false,
checkBoxValues:[],
checkedtype:false,
})
this.props.showNotification(response.data.message)
this.homeworkupdatalist(Coursename,page,order);
@ -1018,8 +1019,9 @@ class ShixunHomework extends Component{
<div className="edu-back-white">
<p className="clearfix padding30 bor-bottom-greyE">
<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>
<li className="fr">
{/*<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>
<li className="fr">
{this.props.isAdmin()===true?datas&&datas.category_name===undefined||datas&&datas.category_name===null?
<span>
<WordsBtn style="blue" onClick={()=>this.addDir()} className={"mr30 font-16"}>添加目录</WordsBtn>

File diff suppressed because it is too large Load Diff

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe Partner, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end
Loading…
Cancel
Save