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

newyslclassrooms
caicai8 5 years ago
commit 07124d2124

@ -159,11 +159,12 @@ class ChallengesController < ApplicationController
challenges.shixun_id, games.identifier, games.status"
join_sql = "LEFT JOIN games ON games.challenge_id = challenges.id AND games.user_id = #{current_user.id}"
# 下面2个参数是为了解决列表获取通关人数与正在游玩人数的问题
@pass_games_map = @shixun.challenges.joins(:games).where(games: {status:2}).group(:challenge_id).reorder(nil).count
@play_games_map = @shixun.challenges.joins(:games).where(games: {status:[0,1]}).group(:challenge_id).reorder(nil).count
#@pass_games_map = @shixun.challenges.joins(:games).where(games: {status:2}).group(:challenge_id).reorder(nil).count
#@play_games_map = @shixun.challenges.joins(:games).where(games: {status:[0,1]}).group(:challenge_id).reorder(nil).count
@challenges = @shixun.challenges.joins(join_sql).select(base_columns)
#@challenges = @shixun.challenges.fields_for_list
@editable = @shixun.status == 0 # before_action有判断权限如果没发布则肯定是管理人员
@user = current_user
@shixun.increment!(:visits)

@ -112,6 +112,8 @@ class CoursesController < ApplicationController
videos = custom_sort(videos, params[:sort_by], params[:sort_direction])
@count = videos.count
sql = "left join videos on videos.id=course_videos.video_id AND (videos.transcoded=1 OR videos.user_id = #{current_user.id})"
videos = videos.joins(sql).reload
@videos = paginate videos.includes(video: [user: :user_extension], user: :user_extension)
end
@ -133,13 +135,17 @@ class CoursesController < ApplicationController
# 视频移动到目录
def move_to_category
tip_exception("请选择要移动的目录") if params[:new_category_id].blank?
category = @course.course_second_categories.find_by(id: params[:new_category_id])
if params[:new_category_id].to_i == 0 || category.present?
videos = @course.course_videos.where(video_id: params[:video_ids]).or(@course.course_videos.where(id: params[:video_ids]))
video = @course.course_videos.where(video_id: params[:video_ids]).or(@course.course_videos.where(id: params[:video_ids])).first
user_id = video.user_id || video.video.user_id
tip_exception("您不是课堂管理员或者视频发布者,暂不能移动视频。") unless @user_course_identity < Course::PROFESSOR || user_id == current_user.id
videos.update_all(course_second_category_id: params[:new_category_id])
video.update!(course_second_category_id: params[:new_category_id])
normal_status(0, "操作成功")
else
normal_status(-1, "目录不存在")

@ -70,6 +70,8 @@ module ApplicationHelper
# shixun开启挑战对应的行为名及url
def task_operation_url current_myshixun, shixun
return ["开启挑战", "/shixuns/#{shixun.identifier}/shixun_exec"] unless current_user.logged?
if current_myshixun.blank?
name = shixun.status == 0 ? "模拟实战" : "开启挑战"
url = "/shixuns/#{shixun.identifier}/shixun_exec"

@ -26,6 +26,20 @@ module AliyunVod::Service::VideoManage
result
end
# 读取视频编码格式
def get_meta_code_info(video_id)
params = {
Action: 'GetMezzanineInfo',
VideoId: video_id,
AdditionType: 'video'
}.merge(base_params)
result = request(:post, params)
result['Mezzanine']['VideoStreamList'][0]['CodecName']
rescue => e
Rails.logger.info "读取视频编码信息失败: #{video_id}, #{e.message}"
end
# 删除视频信息
def delete_video(video_ids)
params = {

@ -14,4 +14,20 @@ module AliyunVod::Service::VideoProcess
result
end
# 提交视频转码任务
def submit_transcode_job(video_id, group_id, **opts)
params = {
Action: 'SubmitTranscodeJobs',
VideoId: video_id,
TemplateGroupId: group_id
}.merge(base_params)
params = opts.merge(params)
result = request(:post, params)
raise AliyunVod::Error, '提交视频转码作业失败' if result['TranscodeJobs'].blank?
result
end
end

@ -79,20 +79,34 @@ class Challenge < ApplicationRecord
end
end
# # 开启挑战
# def open_game(user_id, shixun)
#
#
# game = self.games.select([:status, :identifier]).where(user_id: user_id).first
# game = self.games.select{|game| game.user_id == user_id}
# def open_game shixun, user_id
# game = self.games.map{|g| g.user_id == user_id}.first
# if game.present?
# shixun.task_pass || game.status != 3 ? "/tasks/#{game.identifier}" : ""
# else
# "/api/shixuns/#{shixun.identifier}/shixun_exec"
# self.position == 1 ? "/api/shixuns/#{shixun.identifier}/shixun_exec" : ""
# end
# end
## 用户关卡状态 0: 不能开启实训; 1:直接开启; 2表示已完成
# def user_tpi_status shixun, user_id
# # todo: 以前没加索引导致相同关卡,同一用户有多个games
# # 允许跳关则直接开启
# game = games.where(user_id: user_id).take
# if game.blank?
# position == 1 ? 1 : 0
# else
# if game.status == 3
# shixun.task_pass ? 1 : 0
# elsif game.status == 2
# 2
# else
# 1
# end
# end
# end
# ## 用户关卡状态 0: 不能开启实训; 1:直接开启; 2表示已完成
def user_tpi_status shixun
# todo: 以前没加索引导致相同关卡,同一用户有多个games
# 允许跳关则直接开启
@ -128,12 +142,14 @@ class Challenge < ApplicationRecord
# 关卡用户通关数
def user_passed_count
games.where(status: 2).count
#games.map{|g| g.status == 2}.count
self.games.where(status: 1).count
end
# 关卡用户正在挑战的人数
def playing_count
games.where(status: [0, 1]).count
#games.map{|g| g.status == 0 || g.status == 1}.count
self.games.where(status: [0,1]).count
end
def last_challenge

@ -3,6 +3,6 @@ class CourseVideo < ApplicationRecord
belongs_to :video, optional: true
belongs_to :user, optional: true
validates :title, length: { maximum: 60, too_long: "不能超过60个字符" }
validates :link, format: { with: CustomRegexp::URL, message: "必须为网址超链接" }
validates :title, length: { maximum: 60, too_long: "不能超过60个字符" }, allow_blank: true
validates :link, format: { with: CustomRegexp::URL, message: "必须为网址超链接" }, allow_blank: true
end

@ -210,8 +210,9 @@ class Shixun < ApplicationRecord
end
# 当前用户开启的实训
def current_myshixun(user_id)
myshixuns.find_by(user_id: user_id)
def current_myshixun(user)
return nil unless user.logged?
myshixuns.find_by(user_id: user.id)
end
# 实训技术平台
@ -264,7 +265,7 @@ class Shixun < ApplicationRecord
# 实训关卡的总分(由于大部分是实践题,因此没关联查choose表)
# 提前加载问题由于选择题比较少所以几乎不会触发选择题的查询所以没必要提前载入choose_score
def all_score
self.challenges.pluck(:score).sum
self.challenges.sum(:score)
end
### fork 数量

@ -339,7 +339,7 @@ class User < ApplicationRecord
# 实训管理员实训合作者、admin
def manager_of_shixun?(shixun)
logger.info("############id: #{id}")
shixun.shixun_members.exists?(role: [1,2], user_id: id) || admin? || business?
shixun.shixun_members.exists?(user_id: id, role: [1,2]) || admin? || business?
end
# 实训管理员

@ -1,6 +1,9 @@
class Video < ApplicationRecord
include AASM
# 标准视频转码组
NORMAL_TRANSCODE_GROUP_ID = 'a0277c5c0c7458458e171b0cee6ebf5e'
belongs_to :user
has_many :video_applies, dependent: :destroy

@ -28,6 +28,16 @@ class Videos::BatchPublishService < ApplicationService
if param[:course_id].present?
video.status = "published"
end
# 标清转码为h264
if AliyunVod::Service.get_meta_code_info(video.uuid).start_with?('h264', 'h265')
video.transcoded = true
result = AliyunVod::Service.get_play_info(video.uuid)
video.play_url = result['PlayInfoList']['PlayInfo'][0]['PlayURL']
else
AliyunVod::Service.submit_transcode_job(video.uuid, Video::NORMAL_TRANSCODE_GROUP_ID)
end
video.save!
if param[:course_id].present?
@ -41,7 +51,7 @@ class Videos::BatchPublishService < ApplicationService
# 如果是课堂上传则创建课堂记录
Rails.logger.info("#####param: #{ param[:course_id]}")
if param[:course_id].present?
course_second_category_id = params[:category_id] || 0
course_second_category_id = param[:category_id] || 0
video.course_videos.create!(course_id: param[:course_id], course_second_category_id: course_second_category_id)
end
end

@ -20,9 +20,9 @@ class Videos::DispatchCallbackService < ApplicationService
return if video.cover_url.present?
video.update!(cover_url: params['CoverUrl'])
when 'TranscodeComplete' then # 转码完成
when 'StreamTranscodeComplete' then # 转码完成
return if video.play_url.present?
video.update!(play_url: params['FileUrl'])
video.update!(play_url: params['FileUrl'], transcoded: true)
end
rescue => ex

@ -16,12 +16,14 @@ if @challenges.present?
json.st challenge.st
json.name challenge.subject
json.score challenge.score
json.passed_count @pass_games_map.fetch(challenge.id, 0)
#json.passed_count challenge.user_passed_count
json.playing_count @play_games_map.fetch(challenge.id, 0)
#json.playing_count challenge.playing_count
#json.passed_count @pass_games_map.fetch(challenge.id, 0)
user_passed_count = challenge.user_passed_count
json.passed_count user_passed_count
#json.playing_count @play_games_map.fetch(challenge.id, 0)
json.playing_count (challenge.games.count - user_passed_count)
json.name_url shixun_challenge_path(challenge, shixun_identifier: @shixun.identifier)
json.open_game challenge.open_game(@shixun)
#json.open_game challenge.open_game(@shixun, @user.id)
if @editable
json.edit_url edit_shixun_challenge_path(challenge, shixun_identifier: @shixun.identifier)
json.delete_url shixun_challenge_path(challenge, shixun_identifier: @shixun.identifier)
@ -29,6 +31,7 @@ if @challenges.present?
json.down_url index_down_shixun_challenge_path(challenge, :shixun_identifier => @shixun.identifier) if @shixun.challenges_count != challenge.position
end
#json.passed challenge.has_passed?(@user.id)
#json.status challenge.user_tpi_status(@shixun, @user.id)
json.status challenge.user_tpi_status(@shixun)
end
end

@ -14,7 +14,7 @@ json.name shixun.name
json.stu_num shixun.myshixuns_count
json.experience shixun.all_score
json.diffcult level_to_s(shixun.trainee)
json.score_info shixun.shixun_preference_info # todo: 这块可以改成只显示实训的平均分,不用每次都去取每种星的分数了。
json.score_info shixun.averge_star # todo: 这块可以改成只显示实训的平均分,不用每次都去取每种星的分数了。
json.is_jupyter shixun.is_jupyter
# 用于是否显示导航栏中的'背景知识'
json.propaedeutics shixun.propaedeutics.present?

@ -1,5 +1,4 @@
json.extract! video, :id, :title, :cover_url, :file_url, :play_url, :vv, :user_id
json.extract! video, :id, :title, :cover_url, :file_url, :play_url, :vv, :user_id, :transcoded
json.play_duration video.video_play_duration
json.published_at video.display_published_at
json.created_at video.display_created_at

@ -0,0 +1,5 @@
class AddTranscodedToVideo < ActiveRecord::Migration[5.2]
def change
add_column :videos, :transcoded, :boolean, default: false
end
end

@ -0,0 +1,12 @@
#coding=utf-8
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")
p "--- Start submit video trans code #{v.uuid}"
AliyunVod::Service.submit_transcode_job(v.uuid, 'a0277c5c0c7458458e171b0cee6ebf5e')
end
end
end
end

@ -112,7 +112,7 @@ const NewOrEditTask = (props) => {
content: (<p>发布后即可应用到自己管理的课堂<br /> 是否确认发布?</p>),
onOk() {
changePublishLoadingStatus(true);
handlePublish(props, 'publish');
props.handlePublish(props, 'publish');
}
});
}

@ -222,6 +222,7 @@ export const validateOjForm = (props, type, cb) => {
}
let boolflad=false;
try {
if(ojForm.sub_discipline_id.length===0){
hasSuccess = false;
@ -229,34 +230,58 @@ export const validateOjForm = (props, type, cb) => {
message: '提示',
description: '课程必须选择!'
});
boolflad=true;
}else if(ojForm.timeLimit===null){
hasSuccess = false;
notification['error']({
message: '提示',
description: '时间限制必须输入!'
});
boolflad=true;
} else if(ojForm.name.length===0){
hasSuccess = false;
notification['error']({
message: '提示',
description: '任务名称必须输入!'
});
boolflad=true;
}else if(ojForm.description.length===0){
hasSuccess = false;
notification['error']({
message: '提示',
description: '描述必须输入!'
});
boolflad=true;
}
}catch (e) {
}
try {
if( hasSuccess === false){
if(boolflad===true){
props.changeSubmitLoadingStatus(false);
}
}
}catch (e) {
}
try {
if( hasSuccess === false){
if(boolflad===true){
props.changePublishLoadingStatus(false);
}
}
}catch (e) {
}
/** 表单验证结束 */
/** 表单验证通过后,调用保存 or 更新 or 发布 */
if (hasSuccess) {

Loading…
Cancel
Save