Merge branch 'dev_aliyun' into develop

dev_jupyter
daiao 5 years ago
commit 52be80098e

@ -1297,7 +1297,7 @@ class CoursesController < ApplicationController
@is_teacher = @user_course_identity < Course::ASSISTANT_PROFESSOR
@course_modules = @course.course_modules.where(hidden: 0)
@hidden_modules = @course.course_modules.where(hidden: 1)
@second_category_type = ["shixun_homework", "graduation", "attachment", "board", "course_group", "video"]
@second_category_type = ["shixun_homework", "graduation", "attachment", "board", "course_group", "video", "common_homework", "group_homework"]
end
def board_list

@ -379,6 +379,7 @@ class ExercisesController < ApplicationController
#试卷的提交设置
def commit_setting
tip_exception("助教无权限修改本试卷") if @user_course_identity == Course::ASSISTANT_PROFESSOR && !@exercise.assistant_auth
ActiveRecord::Base.transaction do
error_count = 0 # 判断循环里是否有已发布/已截止的,且时间更改了的分班。
# course_group_ids = @course.teacher_course_group_ids(current_user.id) #当前老师的班级id数组
@ -398,6 +399,7 @@ class ExercisesController < ApplicationController
choice_random = params[:choice_random] ? true : false
score_open = params[:score_open] ? true : false #分数是否公开
answer_open = params[:answer_open] ? true : false #答案是否公开
assistant_auth = params[:assistant_auth] ? true : false # 助教权限
# 统一设置或者分班为0则更新试卷并删除试卷分组
if unified_setting || (course_group_ids.size == 0)
@ -426,7 +428,8 @@ class ExercisesController < ApplicationController
:answer_open => answer_open,
:exercise_status => exercise_status_n,
:publish_time => params_publish_time,
:end_time => params_end_time
:end_time => params_end_time,
:assistant_auth => assistant_auth
}
@exercise.update!(exercise_params)
@exercise.exercise_group_settings.destroy_all

@ -34,7 +34,7 @@ class HomeworkCommonsController < ApplicationController
module_type = @homework_type == 4 ? "shixun_homework" : @homework_type == 1 ? "common_homework" : "group_homework"
@homework_commons = @course.homework_commons.where(homework_type: @homework_type)
@main_category = @course.course_modules.find_by(module_type: module_type)
if @homework_type == 4 && !params[:category].blank?
if !params[:category].blank?
@category = @main_category.course_second_categories.find_by(id: params[:category])
tip_exception("子目录id有误") if !@category.present?
@homework_commons = @homework_commons.where(course_second_category_id: params[:category])

@ -154,7 +154,7 @@ class ShixunsController < ApplicationController
@can_fork = {can_fork: "已经职业认证的教师才能fork实训",
certi_url: "/account/certification"}
end
@current_myshixun = @shixun.current_myshixun(current_user)
@current_myshixun = @shixun.current_myshixun(current_user.id)
if @shixun.fork_from
fork_shixun = Shixun.select(:id, :user_id, :name, :identifier).where(id: @shixun.fork_from).first
@fork_from = {name: fork_shixun.name, username: fork_shixun.owner.try(:full_name),

@ -89,6 +89,10 @@ module CoursesHelper
case category.category_type
when "shixun_homework"
"/classrooms/#{course.id}/shixun_homework/#{category.id}"
when "common_homework"
"/classrooms/#{course.id}/common_homework/#{category.id}"
when "group_homework"
"/classrooms/#{course.id}/group_homework/#{category.id}"
when "graduation"
if category.name == "毕设选题"
"/classrooms/#{course.id}/graduation_topics/#{category.course_module_id}"
@ -107,6 +111,10 @@ module CoursesHelper
case category.category_type
when "shixun_homework"
get_homework_commons_count(course, 4, category.id)
when "common_homework"
get_homework_commons_count(course, 1, category.id)
when "group_homework"
get_homework_commons_count(course, 3, category.id)
when "graduation"
if category.name == "毕设选题"
course.graduation_topics_count
@ -238,7 +246,9 @@ module CoursesHelper
# 获取课堂的资源数
def get_attachment_count(course, category_id)
category_id.to_i == 0 ? course.attachments.size : course.attachments.where(course_second_category_id: category_id).size
identity = current_user.course_identity(course)
attachments = category_id.to_i == 0 ? course.attachments : course.attachments.where(course_second_category_id: category_id)
identity > Course::ASSISTANT_PROFESSOR ? attachments.published.size : attachments.size
end
# 获取课堂的视频数

@ -23,7 +23,8 @@ module AliyunVod::Service::Base
result
rescue => ex
::Util.logger_error(ex)
raise AliyunVod::Error, ex.message
""
#raise AliyunVod::Error, ex.message
end
def base_params

@ -26,7 +26,7 @@ module AliyunVod::Service::VideoManage
result
end
# 读取视频编码格式
# 读取视频编码格式与视频格式
def get_meta_code_info(video_id)
params = {
Action: 'GetMezzanineInfo',
@ -36,10 +36,14 @@ module AliyunVod::Service::VideoManage
result = request(:post, params)
Rails.logger.info("#######:#{result['Mezzanine']['VideoStreamList'][0]['CodecName']}")
result['Mezzanine']['VideoStreamList'][0]['CodecName']
codecnamne = result['Mezzanine']['VideoStreamList'].first['CodecName']
file_url = result['Mezzanine']['FileURL']
format = file_url&.split(".")&.last
{codecnamne: codecnamne, format: format}
rescue => e
Rails.logger.info "读取视频编码信息失败: #{video_id}, #{e.message}"
{codecnamne: "", format: ""}
end
# 删除视频信息

@ -24,6 +24,7 @@ class Attachment < ApplicationRecord
scope :simple_columns, -> { select(:id, :filename, :filesize, :created_on, :cloud_url, :author_id, :content_type, :container_type, :container_id) }
scope :search_by_container, -> (ids) {where(container_id: ids)}
scope :unified_setting, -> {where("unified_setting = ? ", 1)}
scope :published, -> {where(is_publish: 1)}
validates_length_of :description, maximum: 100, message: "不能超过100个字符"

@ -210,9 +210,8 @@ class Shixun < ApplicationRecord
end
# 当前用户开启的实训
def current_myshixun(user)
return nil unless user.logged?
myshixuns.find_by(user_id: user.id)
def current_myshixun(user_id)
myshixuns.find_by(user_id: user_id)
end
# 实训技术平台

@ -29,13 +29,14 @@ class Videos::BatchPublishService < ApplicationService
video.status = "published"
end
# 标清转码为h264
if AliyunVod::Service.get_meta_code_info(video.uuid).start_with?('h264', 'h265')
# 非MP4 H264编码的都转码
code_info = AliyunVod::Service.get_meta_code_info(video.uuid)
Rails.logger.info("code_info: #{code_info[:format]}, #{code_info[:codecnamne]}")
if code_info[:format] == "mp4" && code_info[:codecnamne].present? && code_info[:codecnamne].start_with?('h264')
video.transcoded = true
#Rails.logger.info("####video.uuid:#{video.uuid}")
#result = AliyunVod::Service.get_play_info(video.uuid)
# Rails.logger.info("####video.result:#{result}")
#video.play_url = result['PlayInfoList']['PlayInfo'][0]['PlayURL']
result = AliyunVod::Service.get_play_info(video.uuid) rescue nil
play_url = result['PlayInfoList']['PlayInfo'].first['PlayURL'] if result.present?
video.play_url = play_url
else
AliyunVod::Service.submit_transcode_job(video.uuid, Video::NORMAL_TRANSCODE_GROUP_ID)
end

@ -18,9 +18,7 @@ class Videos::DispatchCallbackService < ApplicationService
video.save!
when 'SnapshotComplete' then # 封面截图完成
return if video.cover_url.present?
result = AliyunVod::Service.get_play_info(video.uuid) rescue nil
play_url = result['PlayInfoList']['PlayInfo'][0]['PlayURL'] if result
video.update!(cover_url: params['CoverUrl'], play_url: play_url)
video.update!(cover_url: params['CoverUrl'])
when 'StreamTranscodeComplete' then # 转码完成
#return if video.play_url.present?
video.update!(play_url: params['FileUrl'], transcoded: true)

@ -1,5 +1,5 @@
json.course_is_end @course.is_end # true表示已结束false表示未结束
json.extract! @exercise, :id,:exercise_name,:exercise_description,:show_statistic
json.extract! @exercise, :id,:exercise_name,:exercise_description,:show_statistic,:assistant_auth
json.time (@user_left_time.to_i / 60)
json.exercise_status @ex_status

@ -2,7 +2,7 @@
if @exercises_count > 0
json.exercises do
json.array! @exercises do |exercise|
json.extract! exercise, :id, :exercise_name,:is_public,:created_at
json.extract! exercise, :id, :exercise_name,:is_public,:created_at,:assistant_auth
if @is_teacher_or == 2
second_left = get_exercise_left_time(exercise,@current_user_)
json.time second_left.present? ? (second_left / 60) : nil

@ -0,0 +1,5 @@
class AddAuthToExercise < ActiveRecord::Migration[5.2]
def change
add_column :exercises, :assistant_auth, :boolean, default: 1
end
end

@ -0,0 +1,9 @@
class AddIndexUserIdChallengeIdForGames < ActiveRecord::Migration[5.2]
def change
delete_games = Game.where.not(myshixun_id: Myshixun.all).reorder(nil)
puts "delete_games: #{delete_games.pluck(:id)}"
delete_games.destroy_all
add_index :games, [:user_id, :challenge_id], unique: true
end
end

@ -4,4 +4,4 @@ You are allowed to:
1. Remove rake task
2. Add existing rake tasks
To add existing rake tasks automatically delete this file and reload the project.
--><RakeGroup description="" fullCmd="" taksId="rake"><RakeTask description="Build gitlab-3.2.0.gem into the pkg directory" fullCmd="build" taksId="build" /><RakeTask description="Build and install gitlab-3.2.0.gem into system gems" fullCmd="install" taksId="install" /><RakeTask description="Create tag v3.2.0 and build and push gitlab-3.2.0.gem to Rubygems" fullCmd="release" taksId="release" /><RakeTask description="Run RSpec code examples" fullCmd="spec" taksId="spec" /><RakeTask description="" fullCmd="default" taksId="default" /></RakeGroup></Settings>
--><RakeGroup description="" fullCmd="" taksId="rake"><RakeTask description="Build gitlab-3.2.0.gem into the pkg directory" fullCmd="build" taksId="build" /><RakeTask description="Remove any temporary products" fullCmd="clean" taksId="clean" /><RakeTask description="Remove any generated files" fullCmd="clobber" taksId="clobber" /><RakeTask description="Build and install gitlab-3.2.0.gem into system gems" fullCmd="install" taksId="install" /><RakeGroup description="" fullCmd="" taksId="install"><RakeTask description="Build and install gitlab-3.2.0.gem into system gems without network access" fullCmd="install:local" taksId="local" /></RakeGroup><RakeTask description="Create tag v3.2.0 and build and push gitlab-3.2.0.gem to rubygems.org" fullCmd="release[remote]" taksId="release[remote]" /><RakeTask description="Run RSpec code examples" fullCmd="spec" taksId="spec" /><RakeTask description="" fullCmd="default" taksId="default" /><RakeTask description="" fullCmd="release" taksId="release" /><RakeGroup description="" fullCmd="" taksId="release"><RakeTask description="" fullCmd="release:guard_clean" taksId="guard_clean" /><RakeTask description="" fullCmd="release:rubygem_push" taksId="rubygem_push" /><RakeTask description="" fullCmd="release:source_control_push" taksId="source_control_push" /></RakeGroup></RakeGroup></Settings>

@ -62,7 +62,7 @@ namespace :video do
end
task :get_play_url => :environment do
Video.all.each do |video|
Video.where(play_url: nil).each do |video|
result = AliyunVod::Service.get_play_info(video.uuid) rescue nil
if result.present? && result["PlayInfoList"]["PlayInfo"].present?
puts result

@ -3,7 +3,7 @@ namespace :video_transcode do
desc "视频转码成h264"
task :submit => :environment do
Video.find_each do |v|
if v.uuid && !v.transcoded && !v.file_url.include?('.mp4') && !AliyunVod::Service.get_meta_code_info(v.uuid).start_with?("h264", "h265")
if v.uuid && !v.transcoded && !v.file_url.include?('.mp4') && !AliyunVod::Service.get_meta_code_info(v.uuid)[:codecnamne].start_with?("h264", "h265")
p "--- Start submit video trans code #{v.uuid}"
AliyunVod::Service.submit_transcode_job(v.uuid, 'a0277c5c0c7458458e171b0cee6ebf5e')
else

@ -907,7 +907,7 @@ class College extends Component {
<div className="jibenshiyong100 sortinxdirection yinyin">
<div className="yslstatistic-base-item-labels">
{
teachers_count?
teachers_count || teachers_count===0?
<div className="yslstatistic-base-item-labelsp"> {teachers_count}<span className="yslstatistic-base-item-labelsspan"></span></div>
:
<Spin/>
@ -915,7 +915,7 @@ class College extends Component {
</div>
<div className="yslstatistic-base-item-labels">
{
students_count?
students_count || students_count===0?
<div className="yslstatistic-base-item-labelsp">{students_count}<span className="yslstatistic-base-item-labelsspan"></span></div>
:
<Spin/>
@ -923,7 +923,7 @@ class College extends Component {
</div>
<div className="yslstatistic-base-item-labels">
{
courses_count?
courses_count || courses_count === 0?
<div className="yslstatistic-base-item-labelsp">{courses_count}<span className="yslstatistic-base-item-labelsspan"></span></div>
:
<Spin/>
@ -931,7 +931,7 @@ class College extends Component {
</div>
<div className="yslstatistic-base-item-labels">
{
shixuns_count?
shixuns_count || shixuns_count === 0?
<div className="yslstatistic-base-item-labelsp">{shixuns_count}<span className="yslstatistic-base-item-labelsspan"></span></div>
:
<Spin/>
@ -939,7 +939,7 @@ class College extends Component {
</div>
<div className="yslstatistic-base-item-labels">
{
shixun_report_count?
shixun_report_count || shixun_report_count===0?
<div className="yslstatistic-base-item-labelsp">{shixun_report_count}<span className="yslstatistic-base-item-labelsspan"></span></div>
:
<Spin/>
@ -947,7 +947,7 @@ class College extends Component {
</div>
<div className="yslstatistic-base-item-labels">
{
shixun_time?
shixun_time || shixun_time === 0 ?
<div className="yslstatistic-base-item-labelsp">{shixun_time}<span className="yslstatistic-base-item-labelsspan"></span></div>
:
<Spin/>

@ -13,14 +13,14 @@ class WordsBtn extends Component {
<React.Fragment>
{
to==undefined&&targets==undefined ?
<a href={href || "javascript:void(0)"} onClick={this.props.onClick} className={"btn "+`${map[this.props.style]} ${this.props.className}`}
<a href={href || "javascript:void(0)"} onClick={this.props.onClick} className={"btn "+`${map[this.props.style]} ${this.props.className || ""}`}
style={style2} {...others}
>{this.props.children}</a>:
targets!=undefined? <a href={to} target="_blank" className={"btn "+`${map[this.props.style]} ${this.props.className}`}
style={style2} {...others}
>{this.props.children}</a>
:
<Link to={to} className={"btn "+`${map[this.props.style]} ${this.props.className}`}
<Link to={to} className={"btn "+`${map[this.props.style]} ${this.props.className || ""}`}
style={style2} {...others}
>{this.props.children}</Link>
}

@ -16,7 +16,7 @@ function ImageLayer2(props) {
const imageSrc = event.target.src || event.target.getAttribute('src') || event.target.getAttribute('href')
// 判断imageSrc是否是图片
const fileName = event.target.innerHTML.trim()
if (isImageExtension(imageSrc.trim()) || isImageExtension(fileName) || event.target.tagName == 'IMG' || imageSrc.indexOf('base64,') != -1) {
if (isImageExtension((imageSrc && imageSrc.trim())) || isImageExtension(fileName) || event.target.tagName == 'IMG' || (imageSrc && imageSrc.indexOf('base64,')) != -1) {
// 非回复里的头像图片; 非emoticons
if (imageSrc.indexOf('/images/avatars/User') === -1 &&
imageSrc.indexOf('kindeditor/plugins/emoticons') === -1 ) {

@ -17,9 +17,14 @@ export default class ImageBlot extends BlockEmbed {
const node = super.create();
node.setAttribute('alt', value.alt);
node.setAttribute('src', value.url);
console.log('~~~~~~~~~~~', node, value);
node.addEventListener('click', function () {
value.onclick(value.url);
}, false);
try {
value.onclick(value.url);
}catch (e) {
}
}, false);
if (value.width) {
node.setAttribute('width', value.width);
}
@ -35,6 +40,16 @@ export default class ImageBlot extends BlockEmbed {
node.setAttribute('width', '100%');
}
// node.setAttribute('style', { cursor: 'pointer' });
// if (node.onclick) {
// console.log('image 有图片点击事件======》》》》》》');
// // node.setAttribute('onclick', node.onCLick);
// }
// 给图片添加点击事件
// node.onclick = () => {
// value.onClick && value.onClick(value.url);
// }
return node;
}

@ -64,6 +64,7 @@ class Fileslists extends Component{
});
}
componentDidMount=()=>{
this.getcourse_groupslists()
this.setState({
isSpin:true,
@ -85,43 +86,45 @@ class Fileslists extends Component{
this.seactall(parseInt(this.props.match.params.Id),"desc")
}
this.updadatalist();
on('updateNavSuccess', this.updateNavSuccess)
on('updateNavSuccess',this.updadatalist)
on('files', this.updateNavSuccess)
on('files',this.updadatalist)
}
updateNavSuccess=()=>{
let{sort}=this.state;
this.setState({
isSpin:true
})
if(this.props.match.params.main_id){
this.seactall(undefined,sort);
}else if(this.props.match.params.Id){
this.seactall(parseInt(this.props.match.params.Id),sort)
}
}
componentDidUpdate = (prevProps) => {
if(prevProps.coursesidtype!=this.props.coursesidtype||prevProps.match.params.main_id!=this.props.match.params.main_id||prevProps.match.params.Id!=this.props.match.params.Id){
if(prevProps.coursesidtype!=this.props.coursesidtype||prevProps.match.params.Id!=this.props.match.params.Id&&this.props.coursesidtype!="node") {
if(this.props.coursesidtype==="node") {
if(this.props.match.params.main_id){
this.getcourse_groupslists()
this.setState({
isSpin:true,
checkBoxValues:[],
checkAllValue:false,
isSpin: true,
checkBoxValues: [],
checkAllValue: false,
})
if(this.props.match.params.main_id!=undefined){
if (this.props.match.params.main_id != undefined) {
this.setState({
child:false,
sort:"desc"
child: false,
sort: "desc"
})
this.seactall(undefined,"desc");
this.seactall(undefined, "desc");
}
}
}else{
if(this.props.match.params.Id){
this.getcourse_groupslists()
this.setState({
isSpin:true,
@ -136,8 +139,12 @@ class Fileslists extends Component{
this.seactall(parseInt(this.props.match.params.Id),"desc")
}
}
}
}
updadatalist=(id)=>{
@ -174,6 +181,7 @@ class Fileslists extends Component{
}
updatafiled=()=>{
let{sort}=this.state;
if(this.props.match.params.main_id){
this.seactall(undefined,sort);
@ -640,7 +648,7 @@ class Fileslists extends Component{
}
Settingtypess=(id,title,link)=>{
debugger
this.setState({
Addanexternallink:true,
Exterchainname:"资源设置",
@ -951,10 +959,12 @@ class Fileslists extends Component{
}
secondRowLeft={
<div style={{"display":"inline-block", "marginTop": "22px"}}>
this.props.isAdmin()?<div style={{"display":"inline-block", "marginTop": "22px"}}>
<span> {total_count} 个资源</span>
<span style={{"marginLeft":"16px"}}>已发布{publish_count}</span>
<span style={{"marginLeft":"16px"}}>未发布{unpublish_count}</span>
</div>:<div style={{"display":"inline-block", "marginTop": "22px"}}>
<span> {publish_count} 个资源</span>
</div>
}
onPressEnter={this.onPressEnter}

@ -158,18 +158,18 @@ class LiveItem extends Component{
{ item.live_time && <span className="mr50">开播时间{item.live_time}</span>}
{ item.duration && <span className="mr50">直播预计时长{item.duration}分钟</span> }
</span>
<span>
{
item.op_auth ?
<WordsBtn style="grey" onClick={()=>setLiveId(item.id)}>编辑</WordsBtn>:""
}
{
item.delete_auth ?
<WordsBtn style="grey" className="ml30" onClick={()=>this.deleteLive(item.id)}>删除</WordsBtn>
:""
}
</span>
</p>
<span className="edu-txt-right" style={{width:"80px"}}>
{
item.op_auth ?
<WordsBtn style="grey" onClick={()=>setLiveId(item.id)}>编辑</WordsBtn>:""
}
{
item.delete_auth ?
<WordsBtn style="grey" className="ml30" onClick={()=>this.deleteLive(item.id)}>删除</WordsBtn>
:""
}
</span>
</p>
</div>
)
}

@ -378,7 +378,8 @@ function buildColumns(that, student_works, studentData) {
{/* /classrooms/"+courseId+"/common_homeworks/"+workId+ '/' + record.id +"/appraise */}
<a style={{color: '#4CACFF', marginLeft: '4px'}} id={"asdasdasdasd"}
onMouseDown={(e) => that.props.toWorkDetailPage2(e, courseId, workId, record.id)}
onClick={() => that.props.toWorkDetailPage(courseId, workId, record.id)}>{isAdmin ? '评阅' : '查看'}</a>
// onClick={() => that.props.toWorkDetailPage(courseId, workId, record.id)}
>{isAdmin ? '评阅' : '查看'}</a>
</div>
@ -775,7 +776,7 @@ class CommonWorkList extends Component{
const hasData = this.state.homework_status && this.state.homework_status.indexOf("未发布") == -1 // student_works && !!student_works.length && page == 1 &&
console.log(StudentData)
//console.log(StudentData)
// console.log(student_works)
return(
<React.Fragment>

@ -706,7 +706,7 @@ class CoursesBanner extends Component {
{this.props.isStudent()?this.props.current_user&&this.props.current_user.course_is_end===true?"":<a className="fr user_default_btn user_blue_btn mr20 font-18"
onClick={() => this.exitclass()}
> 退出课堂 </a>:""}
> 永久退出课堂 </a>:""}
</div>

@ -536,7 +536,7 @@ class Coursesleftnav extends Component{
successFunc && successFunc(1);
}
saveNavmodapost=(url,value,positiontype,coursesId)=>{
saveNavmodapost=(url,value,positiontype,coursesId,type)=>{
axios.post(url,
{name:value}).then((result)=>{
@ -548,16 +548,29 @@ class Coursesleftnav extends Component{
description:result.data.message
});
if(positiontype==="shixun_homeworks"){
this.updasaveNavmoda()
trigger('updateNavSuccess')
this.props.history.push(`/classrooms/${coursesId}/shixun_homework/${result.data.category_id}`);
if(positiontype==="shixun_homeworks"||positiontype==="shixun_homework"){
if(type===true){
this.updasaveNavmoda()
trigger('shixun')
}else{
this.updasaveNavmoda()
this.props.history.push(`/classrooms/${coursesId}/shixun_homework/${result.data.category_id}`);
}
}
if(positiontype==="files"){
this.updasaveNavmoda()
trigger('updateNavSuccess')
this.props.history.push(`/classrooms/${coursesId}/file/${result.data.category_id}`);
}
if(positiontype==="files"||positiontype==="file"){
if(type===true){
this.updasaveNavmoda()
trigger('files')
}else{
this.updasaveNavmoda()
this.props.history.push(`/classrooms/${coursesId}/file/${result.data.category_id}`);
}
}
if(positiontype==="boards"){
this.updasaveNavmoda()
@ -565,7 +578,7 @@ class Coursesleftnav extends Component{
this.props.history.push(`/classrooms/${coursesId}/boards/${result.data.category_id}`);
}
if(positiontype!="course_groups"&&positiontype!="shixun_homeworks"){
if(positiontype!="course_groups"&&positiontype!="shixun_homeworks"&&positiontype!="shixun_homework"){
this.updasaveNavmoda()
}
@ -640,12 +653,12 @@ class Coursesleftnav extends Component{
}else if(Navmodaltypename===3){
let url="/course_modules/"+id+"/rename_module.json"
this.saveNavmodapost(url,NavmodalValue)
this.saveNavmodapost(url,NavmodalValue,this.state.positiontype,null,true)
}else if(Navmodaltypename===4){
let url="/course_second_categories/"+id+"/rename_category.json";
this.saveNavmodapost(url,NavmodalValue)
this.saveNavmodapost(url,NavmodalValue,this.state.positiontype,null,true)
}else if(Navmodaltypename===5){

@ -502,7 +502,8 @@ class Listofworksstudentone extends Component {
<a style={{textAlign: "center"}}
className="color-blue"
onMouseDown={(e) => this.Viewstudenttraininginformationtysl2(e, record)}
onClick={() => this.Viewstudenttraininginformation(record)}>{record.operating}</a>
// onClick={() => this.Viewstudenttraininginformation(record)}
>{record.operating}</a>
}
</span>
@ -897,7 +898,8 @@ class Listofworksstudentone extends Component {
<a style={{textAlign: "center"}}
className="color-blue"
onMouseDown={(e) => this.Viewstudenttraininginformationtysl2(e, record)}
onClick={() => this.Viewstudenttraininginformation(record)}>{record.operating}</a>
// onClick={() => this.Viewstudenttraininginformation(record)}
>{record.operating}</a>
}
</span>
@ -1295,11 +1297,13 @@ class Listofworksstudentone extends Component {
record.submitstate === "未开启" ?
<a style={{textAlign: "center",width: '40px'}} className="color-blue"
onMouseDown={(e) => this.Viewstudenttraininginformationtysl2(e, record)}
onClick={() => this.Viewstudenttraininginformationt(record)}>{record.has_comment===true?"详情":"评阅 "}</a> :
// onClick={() => this.Viewstudenttraininginformationt(record)}
>{record.has_comment===true?"详情":"评阅 "}</a> :
<span>
<a style={{textAlign: "center"}} className="color-blue maxnamewidth120"
onMouseDown={(e) => this.Viewstudenttraininginformationtysl2(e, record)}
onClick={() => this.Viewstudenttraininginformationt(record)}>{record.has_comment===true?"详情":"评阅 "}</a>
// onClick={() => this.Viewstudenttraininginformationt(record)}
>{record.has_comment===true?"详情":"评阅 "}</a>
</span>
)
},
@ -1657,11 +1661,13 @@ class Listofworksstudentone extends Component {
record.submitstate === "未开启" ?
<a style={{textAlign: "center",width: '40px'}} className="color-blue"
onMouseDown={(e) => this.Viewstudenttraininginformationtysl2(e, record)}
onClick={() => this.Viewstudenttraininginformationt(record)}>{record.has_comment===true?"详情":"评阅"}</a> :
// onClick={() => this.Viewstudenttraininginformationt(record)}
>{record.has_comment===true?"详情":"评阅"}</a> :
<span>
<a style={{textAlign: "center"}} className="color-blue"
onMouseDown={(e) => this.Viewstudenttraininginformationtysl2(e, record)}
onClick={() => this.Viewstudenttraininginformationt(record)}>{record.has_comment===true?"详情":"评阅"}</a>
// onClick={() => this.Viewstudenttraininginformationt(record)}
>{record.has_comment===true?"详情":"评阅"}</a>
</span>
)
},

@ -58,6 +58,7 @@ class ShixunHomework extends Component{
}
}
updateNavSuccess=()=>{
debugger
this.setState({
isSpin:true
})
@ -111,7 +112,7 @@ class ShixunHomework extends Component{
this.updadatalist()
}
}
on('updateNavSuccess', this.updateNavSuccess)
on('shixun', this.updateNavSuccess)
}
seactall=(id)=>{
this.setState({
@ -146,7 +147,7 @@ class ShixunHomework extends Component{
componentDidUpdate = (prevProps) => {
if(prevProps.coursesidtype!=this.props.coursesidtype||prevProps.match.params.main_id!=this.props.match.params.main_id||prevProps.match.params.category_id!=this.props.match.params.category_id) {
if(prevProps.coursesidtype!=this.props.coursesidtype||prevProps.match.params.category_id!=this.props.match.params.category_id&&this.props.coursesidtype!="node") {
if(this.props.match.params.main_id){
if(this.props.match.params.main_id!=undefined){

@ -19,7 +19,7 @@ class ImageLayer extends Component {
{showImage ?
<div className="taskResultLayer" onClick={onImageLayerClose} style={{overflow: 'auto'}}>
<div className="passContent">
<div><img src={ imageSrc } className="passImg" unselectable="on"/></div>
<img src={ imageSrc } className="passImg" unselectable="on" alt=""/>
</div>
</div>
:

@ -188,6 +188,7 @@ class sendPanel extends Component{
</Tooltip>:''
}
<Modal
keyboard={false}
title="发送至课堂"
@ -197,11 +198,18 @@ class sendPanel extends Component{
destroyOnClose={true}
>
<div className="newupload_conbox">
<style>{`
{
sentShixunPath&&sentShixunPath===true?<style>
{
`
body{
overflow:hidden!important;
width: calc(100%) !important;
}
`
}
</style>:""
}
`}</style>
<div className="mb20"
// onMouseLeave={this.closeList}
>

@ -22,6 +22,7 @@ import JudquestionEditor from "./component/JudquestionEditor";
import Bottomsubmit from "../../modules/modals/Bottomsubmit";
import { connect } from 'react-redux';
import actions from "../../redux/actions";
import QuestionModalPicture from "./component/QuestionModalPicture";
var restricte=false;
class Questionitem_banks extends Component {
constructor(props) {
@ -38,6 +39,7 @@ class Questionitem_banks extends Component {
knowledgepoints: [],
disciplmy:[],
pages:1,
url:''
}
@ -526,14 +528,33 @@ class Questionitem_banks extends Component {
this.scrollToAnchor("Itembankstopid");
}
handleShowUploadImage=(url)=>{
debugger
this.setState({
url:url
})
}
handleClose=()=>{
this.setState({
url:'',
})
}
render() {
let {page, limit, count, Headertop, visible, placement, modalsType, item_type,restricte} = this.state;
let {page, limit, count, Headertop, visible, placement, modalsType, item_type,restricte,url} = this.state;
const params = this.props && this.props.match && this.props.match.params;
// ////console.log(params);
return (
<div>
<div id={"Itembankstopid"} className="newMain clearfix intermediatecenter "
>
{url?
<QuestionModalPicture url={url} {...this.props} {...this.state} handleClose={()=>this.handleClose()}></QuestionModalPicture>
:
""
}
{
restricte===false?
<Prompt
@ -584,6 +605,7 @@ class Questionitem_banks extends Component {
{...this.state}
{...this.props}
getanswerMdRef={(ref) => this.getanswerMdRef(ref)}
handleShowUploadImage={(url)=>this.handleShowUploadImage(url)}
>
</SingleEditor>
@ -594,6 +616,7 @@ class Questionitem_banks extends Component {
{...this.state}
{...this.props}
getanswerMdRef={(ref) => this.getChoquesEditor(ref)}
handleShowUploadImage={(url)=>this.handleShowUploadImage(url)}
>
</ChoquesEditor>

@ -79,6 +79,8 @@ class ChoquesEditor extends Component{
question_titlesysl:this.props.question_titlesysl||'',
question_titleysl:this.props.question_title || '',
item_banksedit:[],
bindinginputs:null,
url:"",
}
}
addOption = () => {
@ -174,8 +176,30 @@ class ChoquesEditor extends Component{
onCancel = () => {
this.props.onEditorCancel()
}
handleShowUploadImages=(url)=>{
this.setState({
url:url,
})
try {
this.props.handleShowUploadImage(url)
}catch (e) {
}
}
handleShowUploadImage = (url,i) => {
this.setState({
url:url,
bindinginputs:i
})
try {
this.props.handleShowUploadImage(url)
}catch (e) {
}
}
componentDidMount = () => {
try {
@ -228,10 +252,22 @@ class ChoquesEditor extends Component{
}
var texts;
const _text = quill.getText();
// console.log("onOptionContentChange");
// console.log(value);
// console.log(value.ops.length);
// console.log(_text);
const reg = /^[\s\S]*.*[^\s][\s\S]*$/;
if (!reg.test(_text)) {
// 处理编辑器内容为空
texts="";
try {
if(value.ops.length>1){
//单独图片的话 _text是为空的
texts=JSON.stringify(value);
}
}catch (e) {
}
} else {
if(_text.length>=500){
var result = _text.substring(0,450);
@ -288,40 +324,68 @@ class ChoquesEditor extends Component{
if (!reg.test(_text)) {
// 处理编辑器内容为空
this.setState({
question_titleysl:""
question_titleysl:"",
})
try {
if(value.ops.length>1) {
this.setState({
question_titleysl:JSON.stringify(value),
})
}
}catch (e) {
}
} else {
// 提交到后台的内容需要处理一下;
try {
let texts = JSON.stringify(value);
this.setState({
question_titleysl:texts
question_titleysl:texts,
})
}catch (e) {
this.setState({
question_titleysl:""
question_titleysl:"",
})
}
}
}
bindinginputs=(i)=>{
this.setState({
bindinginputs:i
})
}
onContentChanges=(value,quill)=>{
const _text = quill.getText();
const reg = /^[\s\S]*.*[^\s][\s\S]*$/;
if (!reg.test(_text)) {
// 处理编辑器内容为空
this.setState({
question_titlesysl:""
question_titlesysl:"",
})
try {
if(value.ops.length>1){
//单独图片的话 _text是为空的
this.setState({
question_titlesysl:JSON.stringify(value),
})
}
}catch (e) {
}
} else {
// 提交到后台的内容需要处理一下;
try {
let texts = JSON.stringify(value);
this.setState({
question_titlesysl:texts
question_titlesysl:texts,
})
}catch (e) {
this.setState({
question_titlesysl:""
question_titlesysl:"",
})
}
@ -330,7 +394,7 @@ class ChoquesEditor extends Component{
render() {
let { question_title, question_score, question_type, question_choices, standard_answers,question_titles} = this.state;
let { question_title, question_score, question_type, question_choices, standard_answers,question_titles,bindinginputs} = this.state;
let { question_id, index, exerciseIsPublish,
// question_title,
// question_type,
@ -382,6 +446,20 @@ class ChoquesEditor extends Component{
.signleEditor .quill_editor_for_react_area .ql-container .ql-editor p{
font-family: MicrosoftYaHei;
}
.content_editorMd_show{
display: flex !important;
margin-top:0px !important;
border-radius:2px !important;
max-width: 1056px !important;
word-break:break-all !important;
border:1px solid rgba(221,221,221,1) !important;
}
.contestedtext{
font-size:14px;
font-family:MicrosoftYaHei;
color:rgba(172,172,172,1);
}
`}</style>
<p className="mb10 clearfix">
{/* {!question_id ? '新建' : '编辑'} */}
@ -391,12 +469,14 @@ class ChoquesEditor extends Component{
<QuillForEditor
autoFocus={true}
imgAttrs={{width: '146px', height: '136px'}}
imgAttrs={{width: '200px', height: '200px'}}
style={{ height: '155px'}}
placeholder="请您输入题干"
options={options}
value={question_title}
onContentChange={this.onContentChange}
showUploadImage={(url)=>this.handleShowUploadImages(url)}
/>
@ -407,6 +487,8 @@ class ChoquesEditor extends Component{
</div>
{question_choices.map( (item, index) => {
// console.log("question_choices");
// console.log(item);
const bg = standard_answers[index] ? 'check-option-bg' : ''
return <div key={index} className={index>0?"df optionRow mt15": "df optionRow"} >
{/* 点击设置答案 */}
@ -423,25 +505,51 @@ class ChoquesEditor extends Component{
{
item===undefined||item===null||item===""?
<QuillForEditor
autoFocus={false}
imgAttrs={{width: '146px', height: '136px'}}
style={{ height: '166px'}}
placeholder="请您输入选项"
options={options}
value={item}
onContentChange={(value,quill) => this.onOptionContentChange(value,quill,index)}
/>
<div style={{width:'100%'}}>
{
bindinginputs===null||bindinginputs!==index?
<div className="content_editorMd_show" onClick={()=>this.bindinginputs(index)}>
{/*<p className="contestedtext">请您输入选项</p>*/}
</div>:
<QuillForEditor
autoFocus={false}
imgAttrs={{width: '200px', height: '200px'}}
style={{ height: '166px'}}
placeholder="请您输入选项"
options={options}
value={item}
onContentChange={(value,quill) => this.onOptionContentChange(value,quill,index)}
showUploadImage={(url)=>this.handleShowUploadImage(url,index)}
/>
}
</div>
:
<QuillForEditor
autoFocus={false}
imgAttrs={{width: '146px', height: '136px'}}
style={{ height: '166px'}}
placeholder="请您输入选项"
options={options}
value={JSON.parse(item)}
onContentChange={(value,quill) => this.onOptionContentChange(value,quill,index)}
/>
<div style={{width:'100%'}}>
{
bindinginputs===null||bindinginputs!==index?
<div className="content_editorMd_show" onClick={()=>this.bindinginputs(index)}>
<QuillForEditor
readOnly={true}
value={JSON.parse(item)}
showUploadImage={(url)=>this.handleShowUploadImage(url,index)}
/>
</div>
:
<QuillForEditor
autoFocus={false}
imgAttrs={{width: '200px', height: '200px'}}
style={{ height: '166px'}}
placeholder="请您输入选项"
options={options}
value={JSON.parse(item)}
onContentChange={(value,quill) => this.onOptionContentChange(value,quill,index)}
showUploadImage={(url)=>this.handleShowUploadImage(url,index)}
/>
}
</div>
}
</div>
@ -474,12 +582,14 @@ class ChoquesEditor extends Component{
<div className="mt10"></div>
<QuillForEditor
autoFocus={false}
imgAttrs={{width: '146px', height: '136px'}}
imgAttrs={{width: '200px', height: '200px'}}
style={{height: '166px' }}
placeholder="请您输入题目解析"
options={options}
value={question_titles}
onContentChange={this.onContentChanges}
showUploadImage={(url)=>this.handleShowUploadImages(url)}
/>
</div>

@ -58,6 +58,7 @@ class JudquestionEditor extends Component{
zqda:null,
item_banksedit:[],
mychoicess:[],
url:''
}
}
addOption = () => {
@ -310,7 +311,16 @@ class JudquestionEditor extends Component{
this.setState({
question_titleysl:""
})
// console.log("空");
try {
if(value.ops.length>1){
//单独图片的话 _text是为空的
this.setState({
question_titleysl:JSON.stringify(value),
})
}
}catch (e) {
}
} else {
// 提交到后台的内容需要处理一下;
try {
@ -325,6 +335,16 @@ class JudquestionEditor extends Component{
}
}
}
handleShowUploadImages=(url)=>{
this.setState({
url:url,
})
try {
this.props.handleShowUploadImage(url)
}catch (e) {
}
}
onContentChanges=(value,quill)=>{
const _text = quill.getText();
const reg = /^[\s\S]*.*[^\s][\s\S]*$/;
@ -334,6 +354,16 @@ class JudquestionEditor extends Component{
this.setState({
question_titlesysl:""
})
try {
if(value.ops.length>1){
//单独图片的话 _text是为空的
this.setState({
question_titlesysl:JSON.stringify(value),
})
}
}catch (e) {
}
} else {
// 提交到后台的内容需要处理一下;
try {
@ -412,12 +442,14 @@ class JudquestionEditor extends Component{
<QuillForEditor
autoFocus={true}
imgAttrs={{width: '146px', height: '136px'}}
imgAttrs={{width: '200px', height: '200px'}}
style={{ height: '155px'}}
placeholder="请您输入题干"
options={options}
value={question_title}
onContentChange={this.onContentChange}
showUploadImage={(url)=>this.handleShowUploadImages(url)}
/>
@ -462,12 +494,14 @@ class JudquestionEditor extends Component{
<QuillForEditor
autoFocus={false}
imgAttrs={{width: '146px', height: '136px'}}
imgAttrs={{width: '200px', height: '200px'}}
style={{height: '166px' }}
placeholder="请您输入题目解析"
options={options}
value={question_titles}
onContentChange={this.onContentChanges}
showUploadImage={(url)=>this.handleShowUploadImages(url)}
/>
</div>

@ -82,6 +82,8 @@ class SingleEditor extends Component{
question_titlesysl:this.props.question_titlesysl||'',
question_titleysl:this.props.question_title || '',
item_banksedit:[],
url:"",
bindinginputs:null
}
}
addOption = () => {
@ -249,8 +251,37 @@ class SingleEditor extends Component{
// standard_answers[index] = !standard_answers[index];
this.setState({ standard_answers })
}
handleShowUploadImages=(url)=>{
this.setState({
url:url,
})
try {
this.props.handleShowUploadImage(url)
}catch (e) {
}
}
handleShowUploadImage = (url,i) => {
this.setState({
url:url,
bindinginputs:i
})
try {
this.props.handleShowUploadImage(url)
}catch (e) {
}
}
bindinginputs=(i)=>{
this.setState({
bindinginputs:i
})
}
onOptionContentChange = (value,quill,index) => {
debugger
if (index >= this.state.question_choices.length) {
// TODO 新建然后删除CD选项再输入题干会调用到这里且index是3
return;
@ -261,6 +292,14 @@ class SingleEditor extends Component{
if (!reg.test(_text)) {
// 处理编辑器内容为空
texts="";
try {
if(value.ops.length>1){
//单独图片的话 _text是为空的
texts=JSON.stringify(value);
}
}catch (e) {
}
} else {
if(_text.length>=500){
var result = _text.substring(0,450);
@ -318,6 +357,16 @@ class SingleEditor extends Component{
this.setState({
question_titleysl:""
})
try {
if(value.ops.length>1){
//单独图片的话 _text是为空的
this.setState({
question_titleysl:JSON.stringify(value),
})
}
}catch (e) {
}
} else {
try {
let texts = JSON.stringify(value);
@ -341,6 +390,16 @@ class SingleEditor extends Component{
this.setState({
question_titlesysl:""
})
try {
if(value.ops.length>1){
//单独图片的话 _text是为空的
this.setState({
question_titlesysl:JSON.stringify(value),
})
}
}catch (e) {
}
} else {
try {
let texts = JSON.stringify(value);
@ -363,7 +422,7 @@ class SingleEditor extends Component{
}
render() {
let { question_title, question_score, question_type, question_choices, standard_answers,question_titles,question_titlesysl} = this.state;
let { question_title, question_score, question_type, question_choices, standard_answers,question_titles,question_titlesysl,bindinginputs} = this.state;
let { question_id, index, exerciseIsPublish,
// question_title,
// question_type,
@ -417,6 +476,19 @@ class SingleEditor extends Component{
.signleEditor .quill_editor_for_react_area .ql-container .ql-editor p{
font-family: MicrosoftYaHei;
}
.content_editorMd_show{
display: flex !important;
margin-top:0px !important;
border-radius:2px !important;
max-width: 1056px !important;
word-break:break-all !important;
border:1px solid rgba(221,221,221,1) !important;
}
.contestedtext{
font-size:14px;
font-family:MicrosoftYaHei;
color:rgba(172,172,172,1);
}
`}</style>
<p className="mb10 clearfix">
{/* {!question_id ? '新建' : '编辑'} */}
@ -426,12 +498,13 @@ class SingleEditor extends Component{
<QuillForEditor
autoFocus={true}
imgAttrs={{width: '146px', height: '136px'}}
imgAttrs={{width: '200px', height: '200px'}}
style={{ height: '155px'}}
placeholder="请您输入题干"
options={options}
value={question_title}
onContentChange={this.onContentChange}
showUploadImage={(url)=>this.handleShowUploadImages(url)}
/>
<div className="mb10 mt10 sortinxdirection">
@ -456,25 +529,51 @@ class SingleEditor extends Component{
<div style={{ flex: '0 0 1038px'}}>
{
item===undefined||item===null||item===""?
<QuillForEditor
autoFocus={false}
imgAttrs={{width: '146px', height: '136px'}}
style={{ height: '166px'}}
placeholder="请您输入选项"
options={options}
value={item}
onContentChange={(value,quill) => this.onOptionContentChange(value,quill,index)}
/>
<div style={{width:'100%'}}>
{
bindinginputs===null||bindinginputs!==index?
<div className="content_editorMd_show" onClick={()=>this.bindinginputs(index)}>
{/*<p className="contestedtext">请您输入选项</p>*/}
</div>:
<QuillForEditor
autoFocus={false}
imgAttrs={{width: '200px', height: '200px'}}
style={{ height: '166px'}}
placeholder="请您输入选项"
options={options}
value={item}
onContentChange={(value,quill) => this.onOptionContentChange(value,quill,index)}
showUploadImage={(url)=>this.handleShowUploadImage(url,index)}
/>
}
</div>
:
<QuillForEditor
autoFocus={false}
imgAttrs={{width: '146px', height: '136px'}}
style={{ height: '166px'}}
placeholder="请您输入选项"
options={options}
value={JSON.parse(item)}
onContentChange={(value,quill) => this.onOptionContentChange(value,quill,index)}
/>
<div style={{width:'100%'}}>
{
bindinginputs===null||bindinginputs!==index?
<div className="content_editorMd_show" onClick={()=>this.bindinginputs(index)}>
<QuillForEditor
readOnly={true}
value={JSON.parse(item)}
showUploadImage={(url)=>this.handleShowUploadImage(url,index)}
/>
</div>
:
<QuillForEditor
autoFocus={false}
imgAttrs={{width: '200px', height: '200px'}}
style={{ height: '166px'}}
placeholder="请您输入选项"
options={options}
value={JSON.parse(item)}
onContentChange={(value,quill) => this.onOptionContentChange(value,quill,index)}
showUploadImage={(url)=>this.handleShowUploadImage(url,index)}
/>
}
</div>
}
@ -509,12 +608,13 @@ class SingleEditor extends Component{
<div className="mt10"></div>
<QuillForEditor
autoFocus={false}
imgAttrs={{width: '146px', height: '136px'}}
imgAttrs={{width: '200px', height: '200px'}}
style={{height: '166px' }}
placeholder="请您输入题目解析"
options={options}
value={question_titles}
onContentChange={this.onContentChanges}
showUploadImage={(url)=>this.handleShowUploadImages(url)}
/>
</div>

@ -83,7 +83,7 @@ export default ({ middleshixundata, pagination, typepvisible, pages, totalcount,
</div>
<div className="both"></div>
<div className={"ml425"}
<div className={"educontent edu-txt-center mt10"}
style={{ display: pagination ? "block" : "none" }}>
<Pagination defaultCurrent={1} current={pages} total={totalcount || 1299} type="mini" pageSize={16} onChange={onPageChange} />
</div>

@ -443,7 +443,7 @@ function VideoUploadList (props) {
<div class="description ">
<div>上传说明目前不支持断点续传单个视频文件最大限制500M单次最多支持3个视频文件上传 </div>
<div>视频规格aviflvf4vm4vmovmp4rmvbswfwebm </div>
<div>温馨提示<span class="color-orange-tip">为了更好播放体验建议您优先上传MP4格式如果您是自己录制视频建议您保存的时候将视频编码设置为AVC(H264)</span></div></div>
<div>温馨提示<span class="color-orange-tip">为了更好播放体验建议您优先上传MP4格式如果您是自己录制视频建议您保存的时候将视频编码设置为AVC(H264)</span></div></div>
</div>
{!noUploads && <React.Fragment>

Loading…
Cancel
Save