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

dev_winse
caishi 6 years ago
commit 414d1832c2

@ -33,7 +33,7 @@ class AccountsController < ApplicationController
uid_logger("start register: verifi_code is #{verifi_code}, code is #{code}, time is #{Time.now.to_i - verifi_code.try(:created_at).to_i}")
# check_code = (verifi_code.try(:code) == code.strip && (Time.now.to_i - verifi_code.created_at.to_i) <= 10*60)
# todo 上线前请删除万能验证码"513231"
if code != "513231"
unless code == "513231" && request.host == "47.96.87.25"
return normal_status(-2, "验证码不正确") if verifi_code.try(:code) != code.strip
return normal_status(-2, "验证码已失效") if !verifi_code&.effective?
end

@ -15,8 +15,13 @@ class AttachmentsController < ApplicationController
update_downloads(@file)
redirect_to @file.cloud_url and return
end
send_file(absolute_path(local_path(@file)), filename: @file.filename, type: @file.content_type.presence || 'application/octet-stream')
pdf_attachment = params[:disposition] || "attachment"
if pdf_attachment == "inline"
send_file absolute_path(local_path(@file)),filename: @file.filename, disposition: 'inline',type: 'application/pdf'
else
send_file(absolute_path(local_path(@file)), filename: @file.filename,stream:false, type: @file.content_type.presence || 'application/octet-stream')
end
update_downloads(@file)
end
@ -162,28 +167,30 @@ class AttachmentsController < ApplicationController
def attachment_candown
unless current_user.admin? || current_user.business?
candown = true
if @file.container && current_user.logged?
# 课堂资源、作业、毕设相关资源的权限判断
if @file.container.is_a?(Course)
course = @file.container
candown = current_user.member_of_course?(course) || @file.is_public == 1
elsif @file.container.is_a?(HomeworkCommon) || @file.container.is_a?(GraduationTask) || @file.container.is_a?(GraduationTopic)
course = @file.container&.course
candown = current_user.member_of_course?(course)
elsif @file.container.is_a?(StudentWork)
course = @file.container&.homework_common&.course
candown = current_user.member_of_course?(course)
elsif @file.container.is_a?(StudentWorksScore)
course = @file.container&.student_work&.homework_common&.course
candown = current_user.member_of_course?(course)
elsif @file.container.is_a?(GraduationWork)
course = @file.container&.graduation_task&.course
candown = current_user.member_of_course?(course)
elsif @file.container.is_a?(GraduationWorkScore)
course = @file.container&.graduation_work&.graduation_task&.course
candown = current_user.member_of_course?(course)
unless params[:type] == 'history'
if @file.container && current_user.logged?
# 课堂资源、作业、毕设相关资源的权限判断
if @file.container.is_a?(Course)
course = @file.container
candown = current_user.member_of_course?(course) || @file.is_public == 1
elsif @file.container.is_a?(HomeworkCommon) || @file.container.is_a?(GraduationTask) || @file.container.is_a?(GraduationTopic)
course = @file.container&.course
candown = current_user.member_of_course?(course)
elsif @file.container.is_a?(StudentWork)
course = @file.container&.homework_common&.course
candown = current_user.member_of_course?(course)
elsif @file.container.is_a?(StudentWorksScore)
course = @file.container&.student_work&.homework_common&.course
candown = current_user.member_of_course?(course)
elsif @file.container.is_a?(GraduationWork)
course = @file.container&.graduation_task&.course
candown = current_user.member_of_course?(course)
elsif @file.container.is_a?(GraduationWorkScore)
course = @file.container&.graduation_work&.graduation_task&.course
candown = current_user.member_of_course?(course)
end
tip_exception(403, "您没有权限进入") if course.present? && !candown
end
tip_exception(403, "您没有权限进入") if course.present? && !candown
end
end
end

@ -1129,7 +1129,7 @@ class CoursesController < ApplicationController
def validate_course_name
tip_exception("课堂名称不能为空!") if params[:course][:name].blank?
if params[:subject_id].blank? || (@course && @course.subject.blank?)
if params[:subject_id].blank? && @course.blank? || (@course && @course.subject.blank?)
tip_exception("课程名称不能为空!") if params[:course_list_name].blank?
tip_exception("课堂名称应以课程名称开头命名") unless params[:course][:name].index(params[:course_list_name]) &&
params[:course][:name].index(params[:course_list_name]) == 0

@ -1566,15 +1566,22 @@ class ExercisesController < ApplicationController
def check_user_id_start_answer #判断用户在开始答题时是否有用户id传入,如果为老师则id必需否则为当前用户的id
user_login = params[:login]
# exercise_current_user_id = params[:user_id]
if user_login.blank? && @user_course_identity < Course::STUDENT #id不存在且当前为老师/管理员等
normal_status(-1,"请输入学生登陆名!")
else
@ex_answerer = User.find_by(login: user_login) #回答者
if @user_course_identity < Course::STUDENT || @exercise.score_open
@ex_answerer = user_login.blank? ? current_user : User.find_by(login: user_login)
else
@ex_answerer = current_user
end
if @ex_answerer.blank?
normal_status(404,"答题用户不存在")
elsif @user_course_identity > Course::STUDENT && !@exercise.is_public
normal_status(403,"非公开试卷")
else
@exercise_current_user_id = @ex_answerer.id || current_user.id
# @exercise_current_user_id = @ex_answerer.id || current_user.id
@exercise_current_user_id = @ex_answerer.id
end
end
end

@ -210,6 +210,7 @@ class FilesController < ApplicationController
is_unified_setting = params[:is_unified_setting]
publish_time = params[:publish_time]
publish_time = format_time(Time.parse(publish_time)) unless publish_time.blank?
is_public = params[:is_public]
course_group_publish_times = params[:course_group_publish_times] || []
@ -221,8 +222,10 @@ class FilesController < ApplicationController
@new_attachment_history = @old_attachment.become_history
@new_attachment_history.save!
old_course_second_category_id = @old_attachment.course_second_category_id
@old_attachment.copy_attributes_from_new_attachment(@new_attachment)
@old_attachment.is_public = is_public == true ? 1 : 0 if is_public
@old_attachment.course_second_category_id = old_course_second_category_id
@old_attachment.save!
@new_attachment.delete
end
@ -260,12 +263,7 @@ 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

@ -498,44 +498,41 @@ class GamesController < ApplicationController
rescue Exception => e
# 思路: 异常首先应该考虑去恢复
# retry为1表示已经轮训完成后还没有解决问题这个时候需要检测异常
if params[:retry].to_i == 1
begin
# 如果模板没有问题,则通过中间层检测实训仓库是否异常
# 监测版本库HEAD是否存在不存在则取最新的HEAD
gitUrl = repo_url @myshixun.repo_path
gitUrl = Base64.urlsafe_encode64(gitUrl)
shixun_tomcat = edu_setting('cloud_bridge')
rep_params = {:tpiID => "#{@myshixun.id}", :tpiGitURL => "#{gitUrl}"}
# 监测版本库HEAD是否存在不存在则取最新的HEAD
uri = "#{shixun_tomcat}/bridge/game/check"
res = uri_post uri, rep_params
uid_logger("repo_content to bridge: res is #{res}")
# res值0 表示正常;-1表示有错误-2表示代码版本库没了
#
if status == 0 && res
# 版本库报错,修复不了
if res['code'] == -1 || res['code'] == -2
begin
# GitService.delete_repository(repo_path: @myshixun.repo_path) if res['code'] == -1
project_fork(@myshixun, @shixun.repo_path, current_user.login)
rescue Exception => e
uid_logger_error("#{e.message}")
tip_exception("#{e.message}")
end
begin
# 如果模板没有问题,则通过中间层检测实训仓库是否异常
# 监测版本库HEAD是否存在不存在则取最新的HEAD
gitUrl = repo_url @myshixun.repo_path
gitUrl = Base64.urlsafe_encode64(gitUrl)
shixun_tomcat = edu_setting('cloud_bridge')
rep_params = {:tpiID => "#{@myshixun.id}", :tpiGitURL => "#{gitUrl}"}
# 监测版本库HEAD是否存在不存在则取最新的HEAD
uri = "#{shixun_tomcat}/bridge/game/check"
res = uri_post uri, rep_params
uid_logger("repo_content to bridge: res is #{res}")
# res值0 表示正常;-1表示有错误-2表示代码版本库没了
#
if status == 0 && res
# 版本库报错,修复不了
if res['code'] == -1 || res['code'] == -2
begin
# GitService.delete_repository(repo_path: @myshixun.repo_path) if res['code'] == -1
project_fork(@myshixun, @shixun.repo_path, current_user.login)
rescue Exception => e
uid_logger_error("#{e.message}")
tip_exception("#{e.message}")
end
end
rescue Exception => e
uid_logger_error(e.message)
end
rescue Exception => e
uid_logger_error(e.message)
if @myshixun.shixun.try(:status) < 2
tip_exception("代码获取异常,请检查实训模板的评测设置是否正确")
else
# 报错继续retry
tip_exception(-3, "#{e.message}")
end
if @myshixun.shixun.try(:status) < 2
tip_exception("代码获取异常,请检查实训模板的评测设置是否正确")
else
# 报错继续retry
tip_exception(-3, "#{e.message}")
end
end
# 有异常版本库获取不到代码前端轮训15S后调用retry == 1
tip_exception(0, e.message)
end
end

@ -562,6 +562,17 @@ class ShixunsController < ApplicationController
commit_id = commit["id"]
end
# 如果该实训是金课中的实训,则将当前用户加入到当期开课的课堂
# if StageShixun.exists?(shixun_id: @shixun.id, subject_id: Subject.where(excellent: 1))
# subject = Subject.where(excellent: 1, id: StageShixun.where(shixun_id: @shixun.id).pluck(:subject_id)).take
# course = subject.courses.where("start_date is not null and start_date <= '#{Date.today}' and end_date is not null and end_date >= '#{Date.today}'").take
# if course.present? && !CourseMember.exists?(course_id: course.id, user_id: current_user.id)
# # 为了不影响后续操作用create而不是create!
# CourseMember.create(course_id: course.id, user_id: current_user.id, role: 4)
# CourseAddStudentCreateWorksJob.perform_later(course.id, [current_user.id])
# end
# end
ActiveRecord::Base.transaction do
begin
cloud_bridge = edu_setting('cloud_bridge')

@ -83,21 +83,37 @@ class SubjectsController < ApplicationController
@is_creator = current_user.creator_of_subject?(@subject)
@is_manager = @user.manager_of_subject?(@subject)
# 合作团队
@members = @subject.subject_members.includes(:user)
@shixuns = @subject.shixuns.published.pluck(:id)
challenge_ids = Challenge.where(shixun_id: @shixuns).pluck(:id)
@courses = @subject.courses if @subject.excellent
@members = @subject.subject_members.includes(:user)
shixuns = @subject.shixuns.published.pluck(:id)
challenge_ids = Challenge.where(shixun_id: shixuns).pluck(:id)
# 实训路径中的所有实训标签
@tags = ChallengeTag.where(challenge_id: challenge_ids).pluck(:name).uniq
# 用户获取的实训标签
# @user_tags = @subject.shixuns.map(&:user_tags_name).flatten.uniq
@user_tags = user_shixun_tags challenge_ids, @user.id
@my_subject_progress = @subject.my_subject_progress
@challenge_count = challenge_ids.size
# 访问数变更
@subject.increment!(:visits)
end
def right_banner
@user = current_user
# 合作团队
@members = @subject.subject_members.includes(:user)
shixuns = @subject.shixuns.published.pluck(:id)
challenge_ids = Challenge.where(shixun_id: shixuns).pluck(:id)
# 实训路径中的所有实训标签
@tags = ChallengeTag.where(challenge_id: challenge_ids).pluck(:name).uniq
# 用户获取的实训标签
# @user_tags = @subject.shixuns.map(&:user_tags_name).flatten.uniq
@user_tags = user_shixun_tags challenge_ids, @user.id
@my_subject_progress = @subject.my_subject_progress
end
def new
normal_status("")
end

@ -26,12 +26,18 @@ class Users::BaseController < ApplicationController
render_forbidden
end
def require_auth_teacher!
return if current_user.admin_or_business? || observed_user.certification_teacher?
render_forbidden
end
def page_value
params[:page].to_i <= 0 ? 1 : params[:page].to_i
end
def per_page_value
params[:per_page].to_i > 0 && params[:per_page].to_i < 50 ? params[:per_page].to_i : 20
params[:per_page].to_i > 0 && params[:per_page].to_i <= 100 ? params[:per_page].to_i : 20
end
alias_method :limit_value, :per_page_value

@ -1,5 +1,5 @@
class Users::VideoAuthsController < Users::BaseController
before_action :private_user_resources!
before_action :private_user_resources!, :check_account, :require_auth_teacher!
def create
result = Videos::CreateAuthService.call(observed_user, create_params)

@ -1,5 +1,6 @@
class Users::VideosController < Users::BaseController
before_action :private_user_resources!
before_action :private_user_resources!, :check_account
before_action :require_auth_teacher!, except: [:index, :review]
helper_method :current_video

@ -380,4 +380,8 @@ module TidingDecorator
I18n.t(locale_format(tiding_type)) % [container.try(:title) || extra]
end
end
def public_course_start_content
I18n.t(locale_format) % [belong_container&.name, belong_container&.start_date&.strftime("%Y-%m-%d")]
end
end

@ -52,7 +52,8 @@ module ApplicationHelper
shixun_id = shixun_id.blank? ? -1 : shixun_id.join(",")
Shixun.select([:id, :name, :user_id, :challenges_count, :myshixuns_count, :trainee, :identifier]).where("id
in(#{shixun_id}) or homepage_show =1").unhidden.order("myshixuns_count desc, homepage_show asc").limit(3)
in(#{shixun_id})").unhidden.order("homepage_show asc, myshixuns_count desc").limit(3)
end
# 相关推荐
@ -257,8 +258,8 @@ module ApplicationHelper
end
end
def download_url attachment
attachment_path(attachment)
def download_url attachment,options={}
attachment_path(attachment,options)
end
# 耗时:天、小时、分、秒

@ -163,7 +163,7 @@ module ExportHelper
end
w_15 = w.work_score.nil? ? "--" : w.work_score.round(1)
w_16 = w.update_time ? format_time(w.update_time) : "--" "更新时间"
w_17 = (game_spend_time w.cost_time)
w_17 = w.cost_time ? (game_spend_time w.cost_time) : "--"
teacher_comments = w.student_works_scores
if teacher_comments.present?
w_18 = ""

@ -16,4 +16,19 @@ module SubjectsHelper
ChallengeTag.joins("join games on challenge_tags.challenge_id = games.challenge_id").
where(challenge_id: challenge_ids, games: {status: 2, user_id: user_id}).pluck("challenge_tags.name").uniq
end
# 金课的课堂状态 0未开课1进行中2已结束
def subject_course_status course
if course.is_end
{status: 2, time: ""}
elsif course.start_date && course.start_date > Date.today
{status: 0, time: ""}
elsif course.start_date && course.start_date <= Date.today && course.end_date >= Date.today
sum_week = ((course.end_date - course.start_date).to_i / 7.0).ceil
curr_week = ((Date.today - course.start_date).to_i / 7.0).ceil
{status: 1, time: "进行至第#{curr_week}周,共#{sum_week}"}
else
{status: -1, time: ""}
end
end
end

@ -16,6 +16,15 @@ module AliyunVod::Service::VideoUpload
result = request(:post, params)
if result['Code'].present?
message =
case result['Code']
when 'InvalidFileName.Extension' then '不支持的文件格式'
when 'IllegalCharacters' then '文件名称包含非法字符'
end
raise AliyunVod::Error, message if message.present?
end
raise AliyunVod::Error, '获取上传凭证失败' if result['UploadAddress'].blank?
result

@ -115,4 +115,15 @@ class Attachment < ApplicationRecord
end
end
#判断是否为pdf文件
def is_pdf?
is_pdf = false
file_content_type = content_type
file_ext_type = File.extname(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
is_pdf
end
end

@ -20,4 +20,14 @@ class AttachmentHistory < ApplicationRecord
is_public == 1
end
def is_history_pdf?
is_pdf = false
file_content_type = content_type
file_ext_type = File.extname(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
is_pdf
end
end

@ -36,7 +36,7 @@ class HomeworkCommon < ApplicationRecord
validates :name, length: { maximum: 60 }
validates :description, length: { maximum: 15000 }
validates :reference_answer, length: { maximum: 5000 }
validates :reference_answer, length: { maximum: 15000 }
# after_update :update_activity
before_destroy :update_homework_bank_quotes

@ -25,7 +25,8 @@ module Searchable::Course
author_school_name: teacher&.school_name,
visits_count: visits,
members_count: members_count,
is_public: is_public == 1
is_public: is_public == 1,
first_category_url: ApplicationController.helpers.module_url(none_hidden_course_modules.first, self)
}
end

@ -268,7 +268,7 @@ class User < ApplicationRecord
# 实训路径管理员
def creator_of_subject?(subject)
subject.user_id == id
subject.user_id == id || admin?
end
# 实训路径合作者、admin

@ -36,9 +36,17 @@ class DuplicateCourseService < ApplicationService
end
def copy_course_modules!
@second_category_list = {}
origin_course.course_modules.each do |course_module|
attrs = course_module.as_json(only: %i[module_type position hidden module_name])
CourseModule.create!(attrs.merge(course_id: course.id))
new_course_module = CourseModule.create!(attrs.merge(course_id: course.id))
# 复制子目录
course_module.course_second_categories.each do |second_category|
category_attr = second_category.as_json(only: %i[category_type name position])
new_second_category =
CourseSecondCategory.create!(category_attr.merge(course_id: course.id, course_module_id: new_course_module.id))
@second_category_list[second_category.id] = new_second_category.id
end
end
end
@ -50,7 +58,10 @@ class DuplicateCourseService < ApplicationService
origin_course.homework_commons.where(homework_type: %i[normal group practice]).find_each do |origin_homework|
homework_attrs = origin_homework.as_json(only: %i[name description homework_type homework_bank_id reference_answer])
homework = HomeworkCommon.create!(homework_attrs.merge(user_id: user.id, course_id: course.id))
course_second_category_id = @second_category_list[origin_homework.course_second_category_id]
homework = HomeworkCommon.create!(homework_attrs.merge(user_id: user.id, course_id: course.id,
course_second_category_id:course_second_category_id))
origin_homework.attachments.find_each do |origin_attachment|
attachment = origin_attachment.copy
@ -71,6 +82,7 @@ class DuplicateCourseService < ApplicationService
HomeworksService.new.create_shixun_homework_cha_setting(homework, origin_homework.shixuns.first)
end
origin_homework.increment!(:quotes)
origin_homework.homework_bank.increment!(:quotes) if origin_homework.homework_bank
end
@ -138,9 +150,9 @@ class DuplicateCourseService < ApplicationService
attachment.copy_from = origin_attachment.copy_from || origin_attachment.id
attachment.is_publish = 0
attachment.attachtype ||= 4
attachment.course_second_category_id = @second_category_list[origin_attachment.course_second_category_id]
attachment.save!
origin_course.update_quotes(attachment)
end
end

@ -51,8 +51,10 @@ class Users::UpdateAccountService < ApplicationService
if first_full_reward
RewardGradeService.call(user, container_id: user.id, container_type: 'Account', score: 500)
sms_notify_admin(user.lastname) if user.user_extension.teacher?
if user.user_extension.teacher?
join_course(user.id,1309, 2)
sms_notify_admin(user.lastname)
end
end
user
@ -73,4 +75,11 @@ class Users::UpdateAccountService < ApplicationService
rescue => ex
Util.logger_error(ex)
end
def join_course(user_id, course_id, identity)
course = Course.find_by(id: course_id)
return unless course
attr = {course_id: course_id, role: identity, user_id: user_id}
CourseMember.create!(attr)
end
end

@ -35,7 +35,7 @@ class Videos::CreateAuthService < ApplicationService
def upload_video_result
AliyunVod::Service.create_upload_video(title, filename, params)
rescue AliyunVod::Error => _
raise Error, '获取视频上传凭证失败'
rescue AliyunVod::Error => ex
raise Error, ex.message || '获取视频上传凭证失败'
end
end

@ -6,4 +6,7 @@ json.publish_time attachment.publish_time
json.quotes attachment.quotes_count
json.downloads_count attachment.downloads_count
json.created_on attachment.created_on
json.url attachment_path(attachment, type: 'history')
# json.url attachment_path(attachment, type: 'history').gsub("/api","")
json.is_pdf attachment.is_history_pdf?
json.url attachment.is_history_pdf? ? attachment_path(attachment, type: 'history',disposition:"inline") : attachment_path(attachment, type: 'history')
json.attachment_id attachment.attachment_id

@ -1,7 +1,8 @@
json.id attachment.id
json.title attachment.title
json.is_public attachment.publiced?
json.is_lock attachment.locked?(@is_member)
# json.is_lock attachment.locked?(@is_member)
json.is_lock !attachment.publiced?
json.is_publish attachment.published?
json.publish_time attachment.publish_time
json.unified_setting attachment.unified_setting
@ -10,4 +11,5 @@ json.quotes attachment.quotes_count
json.description attachment.description
json.downloads_count attachment.downloads_count
json.created_on attachment.created_on
json.url download_url(attachment) unless attachment.locked?(@is_member)
json.is_pdf attachment.is_pdf?
json.url attachment.is_pdf? ? download_url(attachment,disposition:"inline") : download_url(attachment)

@ -2,5 +2,7 @@ json.id attachment.id
json.title attachment.title
json.filesize number_to_human_size attachment.filesize
json.description attachment.description
json.url download_url(attachment)
json.is_pdf attachment.is_pdf?
json.url attachment.is_pdf? ? download_url(attachment,disposition:"inline") : download_url(attachment)
# json.url download_url(attachment)
json.set! :delete, delete.nil? ? true : delete if defined? delete

@ -1,5 +1,6 @@
json.id attachment.id
json.title attachment.title
json.filesize number_to_human_size(attachment.filesize)
json.url download_url(attachment)
json.created_on attachment.created_on
json.is_pdf attachment.is_pdf?
json.url attachment.is_pdf? ? download_url(attachment,disposition:"inline") : download_url(attachment)
json.created_on attachment.created_on

@ -5,6 +5,7 @@ json.course_id @course.id
json.school @course.school&.name
json.class_period @course.class_period
json.credit @course.credit
json.start_date @course.start_date
json.end_date @course.end_date
json.is_public @course.is_public
json.course_module_types @course.course_modules.where(hidden: 0).pluck(:module_type)

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

@ -8,6 +8,7 @@ json.data do
json.course_is_public @course.is_public?
json.files do
json.array! @attachments do |attachment|
json.is_history_file attachment.attachment_histories.count > 0 #是否有历史文件
json.partial! "attachments/attachment", attachment: attachment
json.author do
json.partial! "users/user_simple", user: attachment.author

@ -21,7 +21,7 @@ if @type == "image"
elsif @type == "html"
json.iframe_src File.read("#{@user_path}/#{@user_picture[0]}")&.html_safe
elsif @type == "txt"
json.contents @contents.html_safe
json.contents @contents.to_s
elsif @type =="qrcode"
json.qrcode_str @qrcode_str
elsif @type == "mp3" || @type == "mp4"

@ -1,7 +1,6 @@
json.partial! "homework_commons/homework_public_navigation", locals: {homework: @homework, course: @course, user: @current_user}
json.work_id @work.id
json.description @work.description
json.
json.attachments @work.attachments do |atta|
json.partial! "attachments/attachment_simple", locals: {attachment: atta, delete: @work.delete_atta(atta)}

@ -0,0 +1,21 @@
json.members @members do |member|
json.partial! 'subject_member', locals: { user: member.user }
json.role member.role
end
# 技能标签
json.tags @tags do |tag|
unless tag.blank?
json.tag_name tag
json.status @user_tags.include?(tag)
end
end
# 我的进展
json.progress do
json.my_score @subject.my_subject_score
json.all_score @subject.all_score
json.learned @subject.my_subject_progress
json.time @subject.my_consume_time
end

@ -1,4 +1,4 @@
json.(@subject, :id, :name, :description, :learning_notes, :stages_count, :stage_shixuns_count, :shixuns_count)
json.(@subject, :id, :name, :description, :learning_notes, :stages_count, :stage_shixuns_count, :shixuns_count, :excellent)
json.challenge_choose_count @subject.subject_challenge_choose_count
json.challenges_count @subject.subject_challenge_count
@ -11,6 +11,20 @@ json.allow_statistics @is_manager
json.allow_send @user.logged?
json.allow_visit @subject.status > 1 || @is_manager
json.allow_add_member @is_manager
json.is_creator @is_creator
if @subject.excellent
json.courses @courses do |course|
json.course_id course.id
json.first_category_url module_url(course.none_hidden_course_modules.first, course)
json.start_date course.start_date
json.end_date course.end_date
json.student_count course.students.count
json.course_identity @user.course_identity(course)
json.course_status subject_course_status course
end
end
json.members @members do |member|
json.partial! 'subject_member', locals: { user: member.user }

@ -10,6 +10,7 @@ json.tidding_count 0
json.user_phone_binded @user.phone.present?
json.phone @user.phone
json.profile_completed @user.profile_completed?
json.professional_certification @user.professional_certification
if @course
json.course_identity @course_identity
json.course_name @course.name

@ -225,3 +225,4 @@
System:
1_end: "你提交的发布视频申请:%s审核已通过"
2_end: "你提交的发布视频申请:%s审核未通过<br/><span>原因:%{reason}</span>"
PublicCourseStart_end: "你报名参与的开放课程:%s将于%s正式开课"

@ -273,6 +273,7 @@ Rails.application.routes.draw do
delete :delete_member
post :up_member_position
post :down_member_position
get :right_banner
end
collection do

@ -0,0 +1,5 @@
class ModifyPathForChallenges < ActiveRecord::Migration[5.2]
def change
change_column :challenges, :path, :text
end
end

Binary file not shown.

@ -0,0 +1,188 @@
#coding=utf-8
# 执行示例 bundle exec rake excellent_course_exercise:student_answer args=2933,1042,823
# args 第一个是course_id, 第二个是参与人数, 第三个是通过人数
desc "同步精品课的学生试卷数据"
namespace :excellent_course_exercise do
if ENV['args']
course_id = ENV['args'].split(",")[0] # 对应课堂的id
participant_count = ENV['args'].split(",")[1].to_i # 表示参与人数
pass_count = ENV['args'].split(",")[2].to_i # 表示通过人数
end
task :student_answer => :environment do
course = Course.find_by(id: course_id)
course.exercises.each_with_index do |exercise, index|
# 第一个试卷的参与人数和通过人数都是传的数据,后续的随机
if index == 0
members = course.students.order("id asc").limit(participant_count)
update_exercise_user(exercise, members, pass_count)
else
new_participant_count = rand((participant_count - 423)..participant_count)
new_pass_count = rand((new_participant_count - 113)..new_participant_count)
members = course.students.order("id asc").limit(new_participant_count)
update_exercise_user(exercise, members, new_pass_count)
end
end
end
def update_exercise_user exercise, members, pass_count
exercise_question_ids = exercise.exercise_questions.where(question_type: 0).pluck(:id)
# index < pass_count 之前的学生都是通关的,之后的未通过
members.each_with_index do |member, index|
exercise_user = exercise.exercise_users.where(user_id: member.user_id).take
if exercise_question_ids.length == 20
rand_num = index < pass_count - 1 ? 20 : rand(1..16)
elsif exercise_question_ids.length == 17
rand_num = index < pass_count - 1 ? rand(13..17) : rand(1..11)
elsif exercise_question_ids.length == 39
rand_num = index < pass_count - 1 ? rand(30..39) : rand(1..18)
else
rand_num = exercise_question_ids.length
end
if exercise_user && exercise_user.commit_status == 0
question_ids = exercise_question_ids.sample(rand_num)
questions = exercise.exercise_questions.where(id: question_ids)
create_exercise_answer questions, member.user_id
total_score = calculate_student_score(exercise, member.user)
commit_option = {
:status => 1,
:commit_status => 1,
:start_at => exercise.publish_time,
:end_at => exercise.end_time,
:objective_score => total_score,
:score => total_score,
:subjective_score => 0
}
exercise_user.update_columns(commit_option)
end
end
end
def create_exercise_answer questions, user_id
questions.each do |question|
choice_position = question.exercise_standard_answers.take&.exercise_choice_id
choice = question.exercise_choices.where(choice_position: choice_position).take
answer_option = {
:user_id => user_id,
:exercise_question_id => question.id,
:exercise_choice_id => choice&.id,
:answer_text => ""
}
ex_a = ExerciseAnswer.new(answer_option)
ex_a.save!
end
end
#计算试卷的总分和试卷的答题状态
def calculate_student_score(exercise,user)
score1 = 0.0 #选择题/判断题
score2 = 0.0 #填空题
score5 = 0.0 #实训题
total_score = 0.0
ques_stand = [] #问题是否正确
exercise_questions = exercise.exercise_questions.includes(:exercise_answers,:exercise_shixun_answers,:exercise_standard_answers,:exercise_shixun_challenges)
exercise_questions&.each do |q|
begin
if q.question_type != 5
answers_content = q.exercise_answers.where(user_id: user.id) #学生的答案
else
answers_content = q.exercise_shixun_answers.where(user_id: user.id) #学生的答案
end
if q.question_type <= 2 #为选择题或判断题时
if answers_content.present? #学生有回答时
answer_choice_array = []
answers_content.each do |a|
answer_choice_array.push(a.exercise_choice.choice_position) #学生答案的位置
end
user_answer_content = answer_choice_array.sort
standard_answer = q.exercise_standard_answers.pluck(:exercise_choice_id).sort #该问题的标准答案,可能有多个
if user_answer_content == standard_answer #答案一致,多选或单选才给分,答案不对不给分
if standard_answer.size > 0
q_score_1 = q.question_score
# q_score_1 = (q.question_score.to_f / standard_answer.count) #当多选答案正确时每个answer的分数均摊。
else
q_score_1 = 0.0
end
answers_content.update_all(:score => q_score_1)
score1 = score1 + q.question_score
else
answers_content.update_all(:score => -1.0)
score1 += 0.0
end
else
score1 += 0.0
end
elsif q.question_type == 5 #实训题时,主观题这里不评分
q.exercise_shixun_challenges&.each do |exercise_cha|
game = Game.user_games(user.id,exercise_cha.challenge_id)&.first #当前用户的关卡
if game.present?
exercise_cha_score = 0.0
answer_status = 0
# if game.status == 2 && game.final_score >= 0
if game.final_score > 0
exercise_cha_score = game.real_score(exercise_cha.question_score)
# exercise_cha_score = exercise_cha.question_score #每一关卡的得分
answer_status = 1
end
ex_shixun_answer_content = answers_content&.where(exercise_shixun_challenge_id: exercise_cha.id)
code = nil
if exercise_cha.challenge&.path.present?
cha_path = challenge_path(exercise_cha.challenge&.path)
game_challenge = game.game_codes.search_challenge_path(cha_path)&.first
if game_challenge.present?
game_code = game_challenge
code = game_code.try(:new_code)
else
code = git_fle_content(game.myshixun.repo_path,cha_path)
end
end
if ex_shixun_answer_content.blank? #把关卡的答案存入试卷的实训里
### Todo 实训题的_shixun_details里的代码是不是直接从这里取出就可以了涉及到code的多个版本库的修改
sx_option = {
:exercise_question_id => q.id,
:exercise_shixun_challenge_id => exercise_cha.id,
:user_id => user.id,
:score => exercise_cha_score.round(1),
:answer_text => code,
:status => answer_status
}
ExerciseShixunAnswer.create(sx_option)
else
ex_shixun_answer_content.first.update_attributes(score:exercise_cha_score.round(1),answer_text:code)
end
score5 += exercise_cha_score
else
score5 += 0.0
end
end
end
user_scores = answers_content.blank? ? 0.0 : answers_content.score_reviewed.pluck(:score).sum
if user_scores > 0.0
stand_answer = 1
else
stand_answer = 0
end
ques_option = {
"q_id":q.id, #该问题的id
"q_type":q.question_type,
"q_position":q.question_number, #该问题的位置
"stand_status":stand_answer, #该问题是否正确,1为正确0为错误
"user_score":user_scores.round(1) #每个问题的总得分
}
ques_stand.push(ques_option)
rescue Exception => e
Rails.logger.info("calcuclate_score_have_error____________________________#{e}")
next
end
end
total_score = score1 + score2 + score5
total_score
end
end

@ -0,0 +1,142 @@
#coding=utf-8
# 执行示例 bundle exec rake public_course:student args=149,2903
# args 第一个参数是subject_id第二个参数是课程course_id
# 第一期时间2018-12-16 至2019-03-31
# 第二期时间2019-04-07 至2019-07-28
#
# 这次学习很有收获,感谢老师提供这么好的资源和细心的服务🎉🎉🎉
#
desc "同步精品课数据"
namespace :public_course do
if ENV['args']
subject_id = ENV['args'].split(",")[0] # 对应课程的id
course_id = ENV['args'].split(",")[1] # 对应课堂的id
status = ENV['args'].split(",")[2] # 表示相应的期数
type = ENV['args'].split(",")[3] # 表示课程模块
end
if status.to_i == 1
start_time = '2018-12-16'
end_time = '2019-04-01'
elsif status.to_i == 2
start_time = '2019-04-07'
end_time = '2019-07-28'
else
# 这种情况是取所有的
start_time = '2015-01-01'
end_time = '2022-07-28'
end
task :student => :environment do
puts "subject_id is #{subject_id}"
puts "course_id is #{course_id}"
user_ids = Myshixun.find_by_sql("select distinct(user_id) from myshixuns where shixun_id in (select shixun_id from stage_shixuns
where stage_id in (select id from stages where subject_id=#{subject_id}))").map(&:user_id)
puts user_ids
if user_ids.present?
user_ids.each do |user_id|
puts user_id
begin
CourseMember.create!(course_id: course_id, user_id: user_id, role: 4)
rescue Exception => e
Rails.logger()
end
end
end
end
#
task :message => :environment do
discusses = Discuss.find_by_sql("select content, user_id, created_on, updated_on from discusses where dis_id in (select shixun_id from stage_shixuns where
stage_id in (select id from stages where subject_id=#{subject_id})) and created_at > #{start_time} and
created_at<#{end_time}")
discusses.find_each do |discuss|
puts discuss.user_id
puts discuss.content
# 回复帖子
# 讨论区发布帖子
# Message.create!(board: @message.board, root_id: @message.root_id || @message.id,
# author: current_user, parent: @message,
# message_detail_attributes: {
# content: params[:content]
# })
end
end
# 更新某个课程的某类时间
# 执行示例 bundle exec rake public_course:student args=2903,1
task :time => :environment do
# course_id = ENV['args'].split(",")[0] # 对应课堂的id
# type = ENV['args'].split(",")[1]
course = Course.find(course_id)
case type.to_i
when 1
# 讨论区
when 2
# 作业
course.homework_commons.each do |homework|
created_at = random_time(start_time, end_time)
publish_time = random_larger_time created_at, start_time, end_time
end_time = random_larger_time publish_time, start_time, end_time
updated_at = end_time
homework.update_columns(publish_time: publish_time, end_time: end_time, created_at: created_at, updated_at: updated_at)
homework.homework_detail_manual.update_columns(comment_status: 6, created_at: created_at, updated_at: updated_at)
end
when 3
# 试卷
course.exercises.each do |exercise|
created_at = random_time start_time, end_time
publish_time = random_larger_time created_at, start_time, end_time
end_time = random_larger_time publish_time, start_time, end_time
updated_at = end_time
exercise.update_columns(publish_time: publish_time, end_time: end_time, created_at: created_at, updated_at: updated_at, exercise_status: 3)
end
when 4
# 资源
course.attachments.each do |atta|
created_on = random_time start_time, end_time
atta.update_columns(is_publish: 1, created_on: created_on, publish_time: created_on)
end
end
end
def min_swith(time)
puts time
return time < 9 ? "0#{time}" : time
end
def random_time(start_time, end_time)
hour = (6..23).to_a.sample(1).first
min = rand(60)
sec = rand(60)
start_time = Date.parse(start_time)
end_time = Date.parse(end_time)
date = (start_time..end_time).to_a.sample(1).first
time = "#{date} #{min_swith(hour)}:#{min_swith(min)}:#{min_swith(sec)}"
puts time
time
end
def random_larger_time(time, start_time, end_time)
large_time = random_time(start_time, end_time)
while large_time <= time
large_time = random_time(start_time, end_time)
end
large_time
end
end

@ -0,0 +1,19 @@
desc "开放课程开课前通知报名用户"
namespace :public_course_notice do
task :tiding => :environment do
Course.where(excellent: 1).where("start_date is not null and start_date = '#{Date.today}'").each do |course|
attrs = %i[user_id trigger_user_id status container_id container_type belong_container_id
belong_container_type tiding_type created_at updated_at]
same_attrs = {
trigger_user_id: 0, container_id: course.id, container_type: 'PublicCourseStart',
belong_container_id: course.id, belong_container_type: 'Course', tiding_type: 'System', status: 0
}
Tiding.bulk_insert(*attrs) do |worker|
course.students.each do |student|
worker.add same_attrs.merge(user_id: student.user_id)
end
end
end
end
end

@ -0,0 +1,37 @@
# bundle exec rake sync:public_message args=149,2903
namespace :sync do
task :public_message => :environment do
subject_id = ENV['args'].split(",")[0] # 对应课程的id
board_id = ENV['args'].split(",")[1]
message_id = ENV['args'].split(",")[2]
status = ENV['args'].split(",")[3] # 表示相应的期数
if status.to_i == 1
start_time = '2018-12-16'
end_time = '2019-04-01'
elsif status.to_i == 2
start_time = '2019-04-07'
end_time = '2019-07-28'
else
# 这种情况是取所有的
start_time = '2015-01-01'
end_time = '2022-07-28'
end
shixun_ids = Shixun.find_by_sql("select shixun_id from stage_shixuns where stage_id in (select id from stages where
subject_id=#{subject_id}) ").map(&:shixun_id)
discusses = Discuss.where(dis_id: shixun_ids).where("created_at >? and created_at <?", start_time, end_time)
if discusses.present?
discusses.find_each do |discuss|
puts discuss.user_id
puts board_id
puts message_id
new_message = Message.create!(board_id: board_id.to_i, author_id: discuss.user_id, parent_id: message_id, root_id: message_id)
MessageDetail.create!(message_id: new_message.id, content: discuss.try(:content))
end
end
end
end

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

@ -29,7 +29,7 @@ const env = getClientEnvironment(publicUrl);
module.exports = {
// You may want 'eval' instead if you prefer to see the compiled output in DevTools.
// See the discussion in https://github.com/facebookincubator/create-react-app/issues/343.s
devtool: "cheap-module-eval-source-map",
// devtool: "cheap-module-eval-source-map",
// 开启调试
// These are the "entry points" to our application.
// This means they will be the "root" imports that are included in JS bundle.

@ -70,4 +70,9 @@ export function appendFileSizeToUploadFileAll(fileList) {
return item
})
}
export const uploadNameSizeSeperator = '  '
export const uploadNameSizeSeperator = '  '
export const sortDirections = ["ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend",
"ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend",
"ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend",
"ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend", "ascend", "descend", ]

@ -17,7 +17,7 @@ export { updatePageParams as updatePageParams } from './RouterUti
export { bytesToSize as bytesToSize } from './UnitUtil';
export { markdownToHTML, uploadNameSizeSeperator, appendFileSizeToUploadFile, appendFileSizeToUploadFileAll, isImageExtension,
downloadFile } from './TextUtil'
downloadFile, sortDirections } from './TextUtil'
export { handleDateString, getNextHalfHourOfMoment,formatDuring } from './DateUtil'

@ -27,34 +27,42 @@ class Fileslistitem extends Component{
this.props.Settingtypes(discussMessage.id)
}
showfiles=(value)=>{
let {discussMessage,coursesId}=this.props
let file_id=discussMessage.id
let url="/files/"+file_id+"/histories.json"
axios.get(url,{
params:{
course_id:coursesId
},
}).then((result)=>{
if(result.data.attachment_histories.length===0){
let link = document.createElement('a');
document.body.appendChild(link);
link.href = result.data.url;
link.download = result.data.title;
//兼容火狐浏览器
let evt = document.createEvent("MouseEvents");
evt.initEvent("click", false, false);
link.dispatchEvent(evt);
document.body.removeChild(link);
}else{
this.setState({
Showoldfiles:true,
allfiles:result.data
})
}
}).catch((error)=>{
console.log(error)
})
showfiles=(list)=>{
if(list.is_history_file===false){
// this.props.DownloadFileA(list.title,list.url)
window.location.href=list.url;
}else{
let {discussMessage,coursesId}=this.props
let file_id=discussMessage.id
let url="/files/"+file_id+"/histories.json"
axios.get(url,{
params:{
course_id:coursesId
},
}).then((result)=>{
if(result.data.attachment_histories.length===0){
// if(result.data.is_pdf===true){
// this.props.ShowOnlinePdf(result.data.url)
// //预览pdf
// }else{
//
// }
// this.props.DownloadFileA(result.data.title,result.data.url)
window.location.href=list.url;
}else{
this.setState({
Showoldfiles:true,
allfiles:result.data
})
}
}).catch((error)=>{
console.log(error)
})
}
}
closaoldfilesprops=()=>{
@ -129,8 +137,6 @@ class Fileslistitem extends Component{
discussMessage,
} = this.props;
return(
<div className="graduateTopicList boardsList">
@ -144,6 +150,7 @@ class Fileslistitem extends Component{
loadtype={this.state.Loadtype}
/>:""}
<Showoldfiles
{...this.props}
visible={this.state.Showoldfiles}
allfiles={this.state.allfiles}
closaoldfilesprops={this.closaoldfilesprops}
@ -191,13 +198,13 @@ class Fileslistitem extends Component{
{
this.props.isAdmin ? <a
// href={"/courses/" + coursesId + "/graduation/graduation_tasks/" + categoryid + "/" + taskid + "/list"}
onClick={()=>this.showfiles(discussMessage.title)}
onClick={()=>this.showfiles(discussMessage)}
title={discussMessage.title}
className="fl mt3 font-16 font-bd color-dark maxwidth580">{discussMessage.title}</a> : ""
}
{
this.props.isStudent? <a
onClick={()=>this.showfiles(discussMessage.title)}
onClick={()=>this.showfiles(discussMessage)}
title={discussMessage.title}
className="fl mt3 font-16 font-bd color-dark maxwidth580">{discussMessage.title}</a> :""
}
@ -207,7 +214,7 @@ class Fileslistitem extends Component{
discussMessage.is_lock === true ?
<span className="fl mt3 font-16 font-bd color-dark maxwidth580">{discussMessage.title}</span>
:<a
onClick={()=>this.showfiles(discussMessage.title)}
onClick={()=>this.showfiles(discussMessage)}
title={discussMessage.title}
className="fl mt3 font-16 font-bd color-dark maxwidth580">{discussMessage.title}</a>:""
}

@ -757,6 +757,7 @@ class Fileslists extends Component{
setupdate={(id)=>this.seactall(id)}
Cancel={this.Cancelvisible}
has_course_groups={this.state.has_course_groups}
attachmentId={this.state.coursesecondcategoryid}
/>:""}
<Titlesearchsection

@ -69,7 +69,7 @@ class CommonWorkPost extends Component{
status: 'done'
}
})
const _memebers = response.data.members.slice(0);
const _memebers = response.data.members ? response.data.members.slice(0) : [];
this._edit_init_memebers = _memebers
delete response.data.members;
this.setState({

@ -496,6 +496,15 @@ class Coursesleftnav extends Component{
saveNavmoda=()=>{
let {Navmodaltypename,setnavid,NavmodalValue}=this.state;
let id =setnavid;
if(Navmodaltypename===5&&NavmodalValue==="未分班"||Navmodaltypename===2&&NavmodalValue==="未分班"){
this.setState({
NavmodalValuetype:true,
NavmodalValues:"名称不能和未分班一样"
})
return
}
if(NavmodalValue===""){
this.setState({
NavmodalValuetype:true,
@ -639,6 +648,7 @@ class Coursesleftnav extends Component{
}
onDragEnd=(result)=>{
debugger
// console.log(result)
// let {course_modules}=this.props;
// let newcourse_modules=course_modules;
@ -670,22 +680,26 @@ class Coursesleftnav extends Component{
// course_modules:newcourse_modules
// })
if(result.source.droppableId==="shixun_homework"||result.source.droppableId==="graduation"||result.source.droppableId==="attachment"){
let url ="/course_second_categories/"+result.draggableId+"/move_category.json"
this.droppablepost(url,result.destination.index+1)
}else if(result.source.droppableId==="board"){
let url ="/boards/"+result.draggableId+"/move_category.json"
this.droppablepost(url,result.destination.index+1)
}else if(result.source.droppableId==="course_group"){
let url ="/course_groups/"+result.draggableId+"/move_category.json"
this.droppablepost(url,result.destination.index+1)
}
if(result.source.droppableId==="shixun_homework"||result.source.droppableId==="graduation"||result.source.droppableId==="attachment"){
let url ="/course_second_categories/"+result.draggableId+"/move_category.json";
if(result.destination.index!=null){
this.droppablepost(url,result.destination.index+1)
}
}else if(result.source.droppableId==="board"){
let url ="/boards/"+result.draggableId+"/move_category.json";
if(result.destination.index!=null) {
this.droppablepost(url, result.destination.index + 1)
}
}else if(result.source.droppableId==="course_group"){
if(result.draggableId!=1){
let url ="/course_groups/"+result.draggableId+"/move_category.json";
if(result.destination.index!=null) {
this.droppablepost(url, result.destination.index + 1)
}
}
}
}
@ -708,15 +722,19 @@ class Coursesleftnav extends Component{
let {url}=this.state;
if (key === this.props.indexs) {
this.props.unlocationNavfun(undefined)
this.props.history.replace(urls);
} else {
this.props.unlocationNavfun(key)
this.props.history.replace(urls);
}
if(urls!=url){
this.props.history.replace(urls);
}
if(this.props.indexs===undefined){
this.props.history.replace(urls);
}
// if(this.props.indexs===undefined){
//
// }else{
//
// }
}
maincontent=(item,key)=>{
@ -820,8 +838,16 @@ class Coursesleftnav extends Component{
onInput={this.setNavmodalValue}
/>
</div>
{this.state.NavmodalValuetype===true?<span className={"color-red"}>
<style>
{
`
.ml70{
margin-left: 70px;
}
`
}
</style>
{this.state.NavmodalValuetype===true?<span className={"ml70 color-red"}>
{this.state.NavmodalValues}
</span>:""}
<div className={this.state.NavmodalValuetype===true?"clearfix mt20 edu-txt-center":"clearfix mt50 edu-txt-center"}>
@ -928,9 +954,9 @@ class Coursesleftnav extends Component{
<a className="fl pl46 pd0 Draggablelichild">
<span className={this.props.location.pathname===iem.second_category_url?"color-blue fl ml38 maxwidth155 task-hide Draggablelichild":"fl ml38 maxwidth155 task-hide Draggablelichild"}>{iem.category_name}</span>
<span className={twosandiantype===undefined?this.props.location.pathname===iem.second_category_url?"fr mr20 color-blue Draggablelichild font-14":"fr mr20 color999 Draggablelichild font-14":item.type===twosandiantypes&&twosandiantype===index&&iem.category_name!="未分班"?"none":this.props.location.pathname===iem.second_category_url?"fr mr20 color-blue Draggablelichild font-14":"fr mr20 color999 Draggablelichild font-14"} >{iem.category_count===0?"":iem.category_count}</span>
<span className={twosandiantype===undefined?this.props.location.pathname===iem.second_category_url?"fr mr20 color-blue Draggablelichild font-14":"fr mr20 color999 Draggablelichild font-14":item.type===twosandiantypes&&twosandiantype===index&&iem.category_id!=0?"none":this.props.location.pathname===iem.second_category_url?"fr mr20 color-blue Draggablelichild font-14":"fr mr20 color999 Draggablelichild font-14"} >{iem.category_count===0?"":iem.category_count}</span>
{item.type===twosandiantypes&&twosandiantype===index?
iem.category_name==="未分班"?"":
iem.category_id===0?"":
iem.category_type==="graduation_topics"||iem.category_type==="graduation_tasks"?
<span className={"fr mr20 color999 Draggablelichild font-14"} >{iem.category_count===0?"":iem.category_count}</span>
:<Popover placement="right" content={this.content(item,iem,index)} trigger="hover" key={index}>

@ -220,12 +220,13 @@ class Selectsetting extends Component{
let coursesId=this.props.match.params.coursesId;
let attachmentId=this.props.match.params.attachmentId;
let attachmentId=this.props.attachmentId;
let url="/files/"+this.props.discussMessageid+".json";
//
axios.put(url,{
course_id:coursesId,
new_attachment_id:newfileList.length===0?undefined:newfileList,
course_second_category_id:this.props.coursesidtype===undefined||this.props.coursesidtype==="node"?0:attachmentId,
is_public:is_public,
is_unified_setting:unified_setting,
publish_time:unified_setting===true?datatime===undefined?moment(new Date()).format('YYYY-MM-DD HH'):datatime:undefined,

@ -42,6 +42,9 @@ class Showoldfiles extends Component{
this.props.closaoldfilesprops()
}
showfiless=(url)=>{
this.props.ShowOnlinePdf(url)
}
render(){
let {visible,allfiles}=this.props;
@ -175,7 +178,11 @@ class Showoldfiles extends Component{
<div className="clearfix edu-txt-center lineh-40 bor-bottom-greyE" id={allfiles.id}>
<li className="fl fontlefts">
<a className={"isabox"} href={allfiles.url}>{allfiles.title}</a>
<a className={"isabox"} href={allfiles.url} >{allfiles.title}</a>
{/*{allfiles.is_pdf===false?*/}
{/*<a className={"isabox"} href={allfiles.url} >{allfiles.title}</a>:*/}
{/*<a className={"isabox"} onClick={()=>this.showfiless(allfiles.url)} >{allfiles.title}</a>*/}
{/*}*/}
<span className={"newcolor-orange fl"}>当前版本</span>
</li>
@ -192,6 +199,10 @@ class Showoldfiles extends Component{
<li className="fl fontlefts">
<a className={"isabox"} href={item.url}>{item.title}</a>
{/*{item.is_pdf===false?*/}
{/*<a className={"isabox"} href={item.url}>{item.title}</a>:*/}
{/*<a className={"isabox"} onClick={()=>this.showfiless(item.url)} >{item.title}</a>*/}
{/*}*/}
</li>
<li className="fl filesves ">

@ -760,6 +760,7 @@ class GraduationTasksSubmitedit extends Component{
height: '30px'
}}>
<Checkbox value={item.user_id}
key={item.user_id}
checked={
task_status.map((item,key)=>{
return parseInt(task_status[key])===item.user_id?true:false

@ -8,7 +8,7 @@ import Titlesearchsection from '../common/titleSearch/TitleSearchSection'
import ColorCountText from '../common/titleSearch/ColorCountText'
import update from 'immutability-helper'
import { WordsBtn, ConditionToolTip, on, off ,trigger} from 'educoder'
import { WordsBtn, ConditionToolTip, on, off ,trigger, sortDirections } from 'educoder'
import axios from 'axios'
@ -63,6 +63,7 @@ function buildColumns(that) {
width: 120,
key: 'name',
sorter: showSorter,
sortDirections: sortDirections,
sortOrder: sortedInfo.columnKey === 'name' && sortedInfo.order,
render: (name, record) => {
return <a href={`/users/${record.login}`} target="_blank" className="overflowHidden1" style={{ maxWidth: '110px'}}
@ -75,6 +76,7 @@ function buildColumns(that) {
sorter: showSorter,
// 'ascend' | 'descend'
defaultSortOrder: 'ascend',
sortDirections: sortDirections,
sortOrder: sortedInfo.columnKey === 'role' && sortedInfo.order,
}]
@ -116,6 +118,7 @@ function buildColumns(that) {
title: '答辩组',
// width: 90,
sorter: showSorter,
sortDirections: sortDirections,
key: 'graduation_group',
dataIndex: 'graduation_group',
sortOrder: sortedInfo.columnKey === 'graduation_group' && sortedInfo.order,

@ -242,7 +242,7 @@ class Index extends Component {
updateChallengePath={context.updateChallengePath}
time_limit={context.time_limit}
time_limit={context.time_limit + 5}
resetTestSetsExpandedArray={context.resetTestSetsExpandedArray}
onRunCodeTestFinish={context.onRunCodeTestFinish}

@ -226,10 +226,11 @@ class DetailCards extends Component{
startshixunCombattype:true,
})
} else {
window.location.href = "/tasks/" + response.data.game_identifier;
// window.location.href = "/tasks/" + response.data.game_identifier;
// window.location.href = path
// let path="/tasks/"+response.data.game_identifier;
// this.props.history.push(path);
window.open("/tasks/" + response.data.game_identifier);
}
}).catch((error) => {

@ -187,8 +187,8 @@ class addCollaborators extends Component{
{
partnerList && partnerList.map((item,key)=>{
return(
<li className="clearfix">
<Checkbox value={item.user_id} key={key} className="fl"></Checkbox>
<li className="clearfix" key={key}>
<Checkbox value={item.user_id} key={item.user_id} className="fl"></Checkbox>
<a target="_blank" className="task-hide color-grey3 fl span1 edu-txt-w80">{item.user_name}</a>
<span className="task-hide fl color-grey edu-txt-w80 span2">{item.nickname}</span>
<span className="task-hide fl color-grey edu-txt-w80 span2">{item.identity}</span>

@ -321,6 +321,30 @@ export function TPMIndexHOC(WrappedComponent) {
checkIfProfileCompleted = () => {
return this.state.current_user && this.state.current_user.profile_completed
}
ShowOnlinePdf = (url) => {
return axios({
method:'get',
url:url,
responseType: 'arraybuffer',
}).then((result)=>{
var binaryData = [];
binaryData.push(result.data);
this.url =window.URL.createObjectURL(new Blob(binaryData, {type:"application/pdf"}));
window.open(this.url);
})
}
DownloadFileA=(title,url)=>{
let link = document.createElement('a');
document.body.appendChild(link);
link.href =url;
link.download = title;
//兼容火狐浏览器
let evt = document.createEvent("MouseEvents");
evt.initEvent("click", false, false);
link.dispatchEvent(evt);
document.body.removeChild(link);
}
render() {
let{Headertop,Footerdown, isRender, AccountProfiletype}=this.state;
const common = {
@ -334,11 +358,12 @@ export function TPMIndexHOC(WrappedComponent) {
isNotMember: this.isNotMember,
isUserid:this.state.coursedata&&this.state.coursedata.userid,
fetchUser: this.fetchUser,
showLoginDialog: this.showLoginDialog,
checkIfLogin: this.checkIfLogin,
showProfileCompleteDialog: this.showProfileCompleteDialog,
checkIfProfileCompleted: this.checkIfProfileCompleted,
ShowOnlinePdf:(url)=>this.ShowOnlinePdf(url),
DownloadFileA:(title,url)=>this.DownloadFileA(title,url),
}
return (
<div>

@ -183,14 +183,14 @@ class SearchPage extends Component{
return (
<a key={key}
href={
item.type==="shixun"?`/shixuns/${item.identifier}/challenges`:item.type==="course"?`/courses/${item.id}/students`:item.type==="subject"?`/paths/${item.id}`:item.type==="memo"?`/forums/${item.id}`:""
item.type==="shixun"?`/shixuns/${item.identifier}/challenges`:item.type==="course"?`${item.first_category_url}`:item.type==="subject"?`/paths/${item.id}`:item.type==="memo"?`/forums/${item.id}`:""
}
target="_blank"
>
<div className="project-package-item">
<div className={"font-16 color-dark fl "} >
<div className={"font-16 color-dark fl "} style={{width:"100%"}} >
{/*标题*/}
<span className={"markdown-body fonttext"}
dangerouslySetInnerHTML={{__html:item.title}}/>

Loading…
Cancel
Save