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

* 'dev_aliyun' of https://bdgit.educoder.net/Hjqreturn/educoder:
  作品重置时删除相关的评阅记录
  普通/分组作业前端老师视角的评阅详情页增加浮动显示“下一个评阅”功能
  去掉视频实际时长检测
  视频检测判断是否看完
  观看时长去除小数
  讨论数
  导出excel报错
  视频观看时长
  讨论数直播数
courseware
harry 5 years ago
commit 826c0553ff

@ -13,7 +13,9 @@ class Admins::CoursesController < Admins::BaseController
format.js
format.html
format.xlsx do
@courses = courses.not_deleted.includes(:school, :students, :teacher_course_members, :informs, :course_videos, :attachments, :homework_commons, :course_activities, teacher: [user_extension: :department])
@courses = courses.not_deleted.includes(:school, :students, :teacher_course_members, :informs, :course_videos,
:live_links, :attachments, :homework_commons,
teacher: [user_extension: :department])
filename = "课堂列表_#{Time.current.strftime('%Y%m%d%H%M%S')}.xlsx"
render xlsx: 'index', filename: filename
end

@ -27,9 +27,15 @@ class MyshixunsController < ApplicationController
ActiveRecord::Base.transaction do
@myshixun.destroy!
StudentWork.where(:myshixun_id => @myshixun.id).includes(:shixun_work_comments, :student_works_scores, :challenge_work_scores).each do |work|
work.shixun_work_comments.destroy_all
work.student_works_scores.destroy_all
work.challenge_work_scores.destroy_all
end
StudentWork.where(:myshixun_id => @myshixun.id)
.update_all(myshixun_id: 0, work_status: 0, work_score: nil,
final_score: nil, efficiency: 0, eff_score: 0, calculation_time: nil, cost_time: 0, compelete_status: -1)
final_score: nil, efficiency: 0, eff_score: 0, calculation_time: nil, ultimate_score: 0, cost_time: 0, compelete_status: -1)
end
# 删除版本库
GitService.delete_repository(repo_path: @repo_path) unless @shixun.is_choice_type?

@ -16,11 +16,11 @@ class CreateWatchVideoService < ApplicationService
if params[:log_id].present?
watch_video_history = user.watch_video_histories.find(params[:log_id])
if params[:total_duration] < params[:watch_duration]
return watch_video_history
end
# if params[:total_duration] < params[:watch_duration]
# return watch_video_history
# end
# 更新观看时长
if watch_video_history.present? && !watch_video_history.is_finished && watch_video_history.watch_duration <= params[:watch_duration] && watch_video_history.total_duration <= params[:total_duration]
if watch_video_history.present? && !watch_video_history.is_finished && watch_video_history.total_duration <= params[:total_duration]
# 如果观看总时长没变,说明视频没有播放,无需再去记录
watch_video_history.end_at = current_time
watch_video_history.total_duration = params[:total_duration]
@ -49,7 +49,9 @@ class CreateWatchVideoService < ApplicationService
if !watch_course_video.is_finished
# 更新课程视频的时长及是否看完状态
watch_course_video.watch_duration = params[:watch_duration] if watch_course_video.watch_duration < params[:watch_duration]
watch_course_video.is_finished = watch_course_video.total_duration >= watch_course_video.duration if params[:ed].present?
if params[:ed].present? || (watch_course_video.duration >= 300 && (watch_course_video.duration - params[:point].to_i) <= 20)
watch_course_video.is_finished = watch_course_video.total_duration >= watch_course_video.duration
end
end
watch_course_video.save!
end

@ -3,9 +3,11 @@ wb = xlsx_package.workbook
wb.styles do |s|
blue_cell = s.add_style :bg_color => "FAEBDC", :sz => 10,:height => 25,:b => true, :border => { :style => :thin, :color =>"000000" },:alignment => {wrap_text: true,:horizontal => :center,:vertical => :center}
wb.add_worksheet(name: "课堂列表") do |sheet|
sheet.add_row %w(ID 课堂名称 老师 学生 分班数 资源 公告 视频 普通作业 分组作业 实训作业 实训作业已发布数 作品数 试卷 评测次数 私有 状态 单位 部门 创建者 创建时间 动态时间), :height => 25,:style => blue_cell
sheet.add_row %w(ID 课堂名称 老师 学生 分班数 资源 公告 视频 视频学习时长 直播 普通作业 分组作业 实训作业 实训作业已发布数 作品数 试卷 评测次数 讨论数 私有 状态 单位 部门 创建者 创建时间), :height => 25,:style => blue_cell
@courses.each do |course|
course_board = course.course_board
topic_count = course_board.present? ? course_board.messages.size : 0
data = [
course.id,
course.name,
@ -15,6 +17,8 @@ wb.styles do |s|
get_attachment_count(course, 0),
course.informs.size,
course.course_videos.size,
course.course_videos.map{|cv| cv.watch_course_videos.map(&:total_duration).sum }.sum.round,
course.live_links.size,
course.course_homework_count("normal"),
course.course_homework_count("group"),
course.course_homework_count("practice"),
@ -22,13 +26,13 @@ wb.styles do |s|
course.student_works_count,
course.exercises_count,
course.evaluate_count,
topic_count,
course.is_public == 1 ? "--" : "√",
course.is_end ? "已结束" : "正在进行",
course.school&.name,
course.teacher&.department_name,
course.teacher&.real_name,
course.created_at&.strftime('%Y-%m-%d %H:%M'),
course.max_activity_time ? course.max_activity_time&.strftime('%Y-%m-%d %H:%M') : "--"
]
sheet.add_row(data)
end

@ -2,6 +2,7 @@ import '../katex.css';
import '../css/Courses.css';
import React,{Component} from "react";
import {markdownToHTML, ImageLayer2 } from 'educoder';
import {Button, Row, Col} from "antd";
import axios from 'axios';
import Modals from '../../modals/Modals';
import moment from 'moment';
@ -19,10 +20,10 @@ class CommonWorkAppraise extends Component{
course_name:"",
homework_name:"",
search: '',
get_next_work:undefined,
attachments: [],
revise_attachments: [],
get_next_worktype:false
}
}
getWork = () => {
@ -87,6 +88,34 @@ class CommonWorkAppraise extends Component{
this.getReviseAttachments()
}
get_next_works=(id)=>{
let workId =this.props.match.params.workId;
let url
if(id){
url=`/homework_commons/${workId}/get_next_work.json?work_id=${id}`;
}else{
url=`/homework_commons/${workId}/get_next_work.json`;
}
axios.get(url).then((result)=> {
this.setState({
get_next_work:result.data,
get_next_worktype:true
})
}).catch((error)=>{
console.log(error)
})
}
gotoget_next_work=(id)=>{
if(this.props.match.path===`/classrooms/:coursesId/common_homeworks/:workId/:studentWorkId/appraise`){
this.props.history.replace(`/classrooms/${this.props.match.params.coursesId}/common_homeworks/${this.props.match.params.workId}/${id}/appraise`);
}
if(this.props.match.path===`/classrooms/:coursesId/group_homeworks/:workId/:studentWorkId/appraise`){
this.props.history.replace(`/classrooms/${this.props.match.params.coursesId}/common_homeworks/${this.props.match.params.workId}/${id}/appraise`);
}
}
onAttachmentRemove = (id) => {
this.setState({
Modalstype:true,
@ -128,22 +157,21 @@ class CommonWorkAppraise extends Component{
}
render(){
const dateFormat = 'YYYY-MM-DD HH:mm';
let {course_name, homework_name, search, page, loadingstate, homework_status, reference_answer,
attachments, homework_id, project_info, work_members, is_evaluation,
let {course_name, get_next_work,get_next_worktype,
attachments, project_info, work_members, is_evaluation,
description, update_user_name, commit_user_name, update_time, commit_time, author_name,
revise_attachments, revise_reason, atta_update_user, atta_update_time, atta_update_user_login,
Modalstype,Modalstopval,ModalCancel,ModalSave,loadtype, is_leader_work
} =this.state;
let courseId=this.props.match.params.coursesId;
let category_id=this.props.match.params.category_id;
// let courseId=this.props.match.params.coursesId;
// let category_id=this.props.match.params.category_id;
let studentWorkId=this.props.match.params.studentWorkId;
const isAdmin = this.props.isAdmin()
document.title=course_name&&course_name;
return(
<div>
<WorkDetailPageHeader
{...this.props} {...this.state}
noTab={true}
@ -271,12 +299,60 @@ class CommonWorkAppraise extends Component{
<CommonWorkAppraiseReply {...this.props} task_id={studentWorkId}
onReplySuccess={this.onReplySuccess} {...this.state}
wrappedComponentRef={(ref) => {this.commonWorkAppraiseReply = ref}}
get_next_works={()=>this.get_next_works()}
></CommonWorkAppraiseReply>
</div>
</WorkDetailPageHeader>
{isAdmin===true&&get_next_worktype===true?<style>
{
`
.newFooter{
display:none !important;
}
.-task-sidebar{
display:none !important;
}
.educontent{
margin-bottom: 0px !important;
}
`
}
</style>:""}
{isAdmin===true&&get_next_worktype===true?<div className="clearfix bor-bottom-greyE edu-back-white orderingbox newshixunbottombtn">
<div className={"educontent mt5"}>
<div>
<Row>
<Col span={12} className={"mt13"}>
{get_next_work&&get_next_work.work_id===null?
<Row type="flex" justify="start">
<Col span={8}><div style={{color:"#333333"}}>已全部评阅完</div></Col>
</Row>:<Row type="flex" justify="start">
<Col span={8}><div style={{color:"#333333"}}>{get_next_work&&get_next_work?`下一位待评阅人员:${get_next_work&&get_next_work.user_name}`:""}</div></Col>
<Col span={4}><a className={"ml10 color-blue font-15"} onClick={()=>this.get_next_works(get_next_work&&get_next_work.work_id)}>跳过</a></Col>
</Row>}
</Col>
{get_next_work&&get_next_work.work_id===null?"":<Col span={12} className={"mt8"}>
<Row type="flex" justify="end">
<Col span={4}>
<Button className={"newshixunmode "} type="primary"
onClick={()=>this.gotoget_next_work(get_next_work&&get_next_work.work_id)}
// loading={this.state.hometypepvisible}
>评阅</Button>
</Col>
</Row>
</Col>}
</Row>
</div>
</div>
</div>:""}
</div>
)
}
}

@ -20,7 +20,7 @@ import Modals from '../../../modals/Modals';
const REPLY_PAGE_COUNT = 10
const $ = window.$;
/*
/*
*/
class CommonWorkAppraiseReply extends Component{
@ -79,7 +79,7 @@ class CommonWorkAppraiseReply extends Component{
reply.journals.push(reply.appeal_info)
reply.journals = _.orderBy(reply.journals, 'time', 'asc')
}
return {
isSuperAdmin: isSuperAdmin,
admin: isAdmin, //
@ -93,7 +93,7 @@ class CommonWorkAppraiseReply extends Component{
// time: moment(reply.comment_time).fromNow(),
time: moment(reply.comment_time).format('YYYY-MM-DD HH:mm'),
image_url: reply.user_image_url,
image_url: reply.user_image_url,
user_id: reply.user_id,
user_login: reply.user_login,
username: reply.user_name,
@ -131,7 +131,7 @@ class CommonWorkAppraiseReply extends Component{
console.log('Cancel');
},
});
}
showModulationtype=(id)=>{
@ -221,6 +221,7 @@ class CommonWorkAppraiseReply extends Component{
if (!needNiPingEditor && comment_scores.length == 0) {
return ''
}
return(
<React.Fragment>
<div className="edu-back-white padding10-10" style={{marginTop: '16px'}}>
@ -257,13 +258,13 @@ class CommonWorkAppraiseReply extends Component{
{/*{this.props.isStudent()?<a className={"fr color-blue font-16 mt10 mr20"} onClick={this.addAccessory}>补交附件</a>:""}*/}
{/*</div>*/}
{/* {
(!!comment_scores.length &&
(!!comment_scores.length &&
<div className={"color-grey-6 mb10"}>
<span className="labal">全部评阅</span>
<span className="count">{comment_scores.length}</span>
<span className="count">{comment_scores.length}</span>
</div>)} */}
<div className={`padding20-30 ${comment_scores.length ? 'bor-bottom-greyE' : ''}`}>
{!!comment_scores.length && <div className={"color-grey-6 font-16"}>
@ -283,13 +284,14 @@ class CommonWorkAppraiseReply extends Component{
addSuccess={this.addSuccess} ref={this.editorRef} totalCount={comment_scores.length}
onReply={this.onReply} placeholder={"请在此输入对本作品的评语最大限制2000个字符"}
showSameScore={isGroup && isAdmin}
get_next_works={()=>this.props.get_next_works()}
></GraduationTasksappraiseMainEditor> }
</div>
{/* ${!!comment_scores.length ? 'bor-bottom-greyE' : ''} */}
<div className={`padding20 memoReplies commentsDelegateParent course-message`}
style={{ paddingTop: '0px', paddingBottom: '0px' }}
>
{/*
{/*
.course-message .panel-comment_item {
margin-top: ${needNiPingEditor ? 56 : 28}px;
}

@ -67,6 +67,9 @@ class GraduationTasksappraiseMainEditor extends Component{
same_score
}
if (this.props.onReply) {
if(this.props.get_next_works){
this.props.get_next_works()
}
this.props.onReply(params)
} else {
axios.post(url, params).then((response)=>{

Loading…
Cancel
Save