diff --git a/app/controllers/challenges_controller.rb b/app/controllers/challenges_controller.rb
index 103c33aab..c69f5bbfb 100644
--- a/app/controllers/challenges_controller.rb
+++ b/app/controllers/challenges_controller.rb
@@ -155,8 +155,14 @@ class ChallengesController < ApplicationController
def index
uid_logger("identifier: #{params}")
-
- @challenges = @shixun.challenges.fields_for_list
+ base_columns = "challenges.id, challenges.subject, challenges.st, challenges.score, challenges.position,
+ 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
+
+ @challenges = @shixun.challenges.joins(join_sql).select(base_columns)
@editable = @shixun.status == 0 # before_action:有判断权限,如果没发布,则肯定是管理人员
@user = current_user
diff --git a/app/controllers/course_videos_controller.rb b/app/controllers/course_videos_controller.rb
new file mode 100644
index 000000000..0d5a3e460
--- /dev/null
+++ b/app/controllers/course_videos_controller.rb
@@ -0,0 +1,34 @@
+class CourseVideosController < ApplicationController
+ before_action :require_login
+ before_action :validate_params
+ before_action :find_course, only: [:create]
+ before_action :find_video, only: [:update]
+ before_action :teacher_allowed
+
+ def create
+ title = params[:name].strip
+ link = params[:link].strip
+ @course.course_videos.create!(title: title, link: link, is_link: 1, user_id: current_user.id)
+ render_ok
+ end
+
+ def update
+ title = params[:name].strip
+ link = params[:link].strip
+ @video.update!(title: title, link: link)
+ render_ok
+ end
+
+ private
+
+ def validate_params
+ tip_exception("视频名称不能为空") if params[:name].blank?
+ tip_exception("链接地址不能为空") if params[:link].blank?
+ end
+
+ def find_video
+ @video = CourseVideo.find params[:id]
+ @course = @video.course
+ end
+
+end
\ No newline at end of file
diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb
index fe9d20d8d..2e94e435d 100644
--- a/app/controllers/courses_controller.rb
+++ b/app/controllers/courses_controller.rb
@@ -102,22 +102,32 @@ class CoursesController < ApplicationController
end
def course_videos
- videos = @course.videos
+ videos = @course.course_videos
+ @video_module = @course.course_modules.find_by(module_type: "video")
if params[:category_id].present? && params[:category_id].to_i != 0
+ @category = @video_module&.course_second_categories.find_by(id: params[:category_id])
+ tip_exception("子目录id有误") if !@category.present?
videos = videos.where(course_second_category_id: params[:category_id].to_i)
end
videos = custom_sort(videos, params[:sort_by], params[:sort_direction])
@count = videos.count
- @videos = paginate videos.includes(user: :user_extension)
+ @videos = paginate videos.includes(video: [user: :user_extension], user: :user_extension)
end
def delete_course_video
- video = Video.find_by(id: params[:video_id])
- tip_exception(404, "找不到资源") if video.blank?
- tip_exception(403, "...") unless (video.user_id == current_user.id || current_user.admin_or_business?)
- video.destroy!
- AliyunVod::Service.delete_video([video.uuid]) rescue nil
+ if params[:is_link]
+ video = @course.course_videos.find_by!(id: params[:video_id])
+ tip_exception(403, "...") unless (video.user_id == current_user.id || current_user.admin_or_business?)
+ video.destroy!
+ else
+ video = Video.find_by(id: params[:video_id])
+ tip_exception(404, "找不到资源") if video.blank?
+ tip_exception(403, "...") unless (video.user_id == current_user.id || current_user.admin_or_business?)
+ video.destroy!
+ AliyunVod::Service.delete_video([video.uuid]) rescue nil
+ end
+
render_ok
end
@@ -127,7 +137,7 @@ class CoursesController < ApplicationController
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(id: params[:video_ids])
+ videos = @course.course_videos.where(video_id: params[:video_ids]).or(@course.course_videos.where(id: params[:video_ids]))
videos.update_all(course_second_category_id: params[:new_category_id])
normal_status(0, "操作成功")
diff --git a/app/controllers/files_controller.rb b/app/controllers/files_controller.rb
index 25e0de44a..c1fa48be8 100644
--- a/app/controllers/files_controller.rb
+++ b/app/controllers/files_controller.rb
@@ -7,7 +7,7 @@ class FilesController < ApplicationController
before_action :file_validate_sort_type, only: :index
before_action :validate_send_message_to_course_params, only: :bulk_send
before_action :set_pagination, only: %i[index public_with_course_and_project mine_with_course_and_project]
- before_action :validate_upload_params, only: %i[upload import]
+ before_action :validate_upload_params, only: %i[import]
before_action :find_file, only: %i[show setting update]
before_action :publish_params, only: %i[upload import update]
@@ -163,6 +163,7 @@ class FilesController < ApplicationController
# 上传资源
def upload
+ find_course_second_category_id
attachment_ids = params[:attachment_ids]
course_second_category_id = params[:course_second_category_id] || 0 # 0: 为主目录, 其他为次目录id
# is_unified_setting = params.has_key?(:is_unified_setting) ? params[:is_unified_setting] : true
@@ -170,25 +171,48 @@ class FilesController < ApplicationController
# course_group_publish_times = params[:course_group_publish_times] || []
begin
- attachment_ids.each do |attchment_id|
- attachment = Attachment.find_by_id attchment_id
- unless attachment.nil?
- attachment.container = @course
- attachment.course_second_category_id = course_second_category_id
- attachment.description = params[:description]
- attachment.is_public = params[:is_public] && @course.is_public == 1 ? 1 : 0
- attachment.is_publish = @atta_is_publish
- attachment.delay_publish = @atta_delay_publish
- attachment.publish_time = @atta_publish_time
- attachment.unified_setting = @unified_setting
- if @unified_setting == 0
- attachment_group_setting attachment, params[:group_settings]
+ if attachment_ids.present?
+ attachment_ids.each do |attchment_id|
+ attachment = Attachment.find_by_id attchment_id
+ unless attachment.nil?
+ attachment.container = @course
+ attachment.course_second_category_id = course_second_category_id
+ attachment.description = params[:description]
+ attachment.is_public = params[:is_public] && @course.is_public == 1 ? 1 : 0
+ attachment.is_publish = @atta_is_publish
+ attachment.delay_publish = @atta_delay_publish
+ attachment.publish_time = @atta_publish_time
+ attachment.unified_setting = @unified_setting
+ if @unified_setting == 0
+ attachment_group_setting attachment, params[:group_settings]
+ end
+ # attachment.set_publish_time(publish_time) if is_unified_setting
+ # attachment.set_course_group_publish_time(@course, course_group_publish_times) if @course.course_groups.size > 0 && !is_unified_setting && publish_time.blank?
+ attachment.save!
end
- # attachment.set_publish_time(publish_time) if is_unified_setting
- # attachment.set_course_group_publish_time(@course, course_group_publish_times) if @course.course_groups.size > 0 && !is_unified_setting && publish_time.blank?
- attachment.save!
end
+ else
+ tip_exception("资源名称不能为空") if params[:name].blank?
+ tip_exception("资源名称不能超过60个字符") if params[:name].strip.length > 60
+ tip_exception("链接地址不能为空") if params[:link].blank?
+ attachment = Attachment.new
+ attachment.container = @course
+ attachment.course_second_category_id = course_second_category_id
+ attachment.author_id = current_user.id
+ attachment.filename = params[:name].strip
+ attachment.link = params[:link].strip
+ attachment.description = params[:description]
+ attachment.is_public = params[:is_public] && @course.is_public == 1 ? 1 : 0
+ attachment.is_publish = @atta_is_publish
+ attachment.delay_publish = @atta_delay_publish
+ attachment.publish_time = @atta_publish_time
+ attachment.unified_setting = @unified_setting
+ if @unified_setting == 0
+ attachment_group_setting attachment, params[:group_settings]
+ end
+ attachment.save!
end
+
rescue Exception => e
uid_logger_error(e.message)
tip_exception(e.message)
diff --git a/app/controllers/users/videos_controller.rb b/app/controllers/users/videos_controller.rb
index 0ae240dd7..645c25362 100644
--- a/app/controllers/users/videos_controller.rb
+++ b/app/controllers/users/videos_controller.rb
@@ -1,6 +1,6 @@
class Users::VideosController < Users::BaseController
before_action :private_user_resources!, :check_account
- before_action :require_teacher!
+ before_action :require_teacher!, except: [:destroy]
before_action :require_auth_teacher!, except: [:index, :review]
helper_method :current_video
@@ -53,6 +53,19 @@ class Users::VideosController < Users::BaseController
render_error(ex.message)
end
+ def destroy
+ video = observed_user.videos.find_by(id: params[:video_id])
+ render_forbidden unless video.user_id != observed_user.id || !current_user.admin_or_business?
+ return render_not_found if video.blank?
+ return render_error('该状态下不能删除视频') unless video.pending?
+
+ video.destroy!
+
+ AliyunVod::Service.delete_video([video.uuid]) rescue nil
+
+ render_ok
+ end
+
private
def current_video
diff --git a/app/controllers/weapps/attendances_controller.rb b/app/controllers/weapps/attendances_controller.rb
index 3f0eec248..57e1e10df 100644
--- a/app/controllers/weapps/attendances_controller.rb
+++ b/app/controllers/weapps/attendances_controller.rb
@@ -58,12 +58,18 @@ class Weapps::AttendancesController < ApplicationController
@history_attendances = @course.course_attendances.where(id: history_attendance_ids.uniq).
where("attendance_date < '#{current_date}' or (attendance_date = '#{current_date}' and end_time < '#{current_end_time}')").order("id desc")
- @current_attendance = @course.course_attendances.where(id: all_attendance_ids.uniq).
+ @current_attendances = @course.course_attendances.where(id: all_attendance_ids.uniq).
where("attendance_date = '#{current_date}' and start_time <= '#{current_end_time}' and end_time > '#{current_end_time}'")
@history_count = @history_attendances.size
+ # 当前签到如果存在快捷签到,则直接签到
+ quick_attendances = @current_attendances.where(mode: "QUICK")
+ if quick_attendances.present?
+ student_direct_attendance quick_attendances, member
+ end
+
student_attendance_ids = @history_attendances.pluck(:id)
- student_attendance_ids += @current_attendance.present? ? @current_attendance.pluck(:id) : []
+ student_attendance_ids += @current_attendances.present? ? @current_attendances.pluck(:id) : []
if student_attendance_ids.uniq.blank?
@normal_count = 0
@@ -141,4 +147,16 @@ class Weapps::AttendancesController < ApplicationController
def edit_auth
tip_exception(403, "") unless @user_course_identity < Course::PROFESSOR || @attendance.user_id == current_user.id
end
+
+ def student_direct_attendance quick_attendances, member
+ quick_attendances.each do |attendance|
+ current_attendance = attendance.course_member_attendances.find_by(user_id: member.user_id)
+ if current_attendance.present?
+ current_attendance.update!(attendance_status: "NORMAL", attendance_mode: "QUICK")
+ else
+ attendance.course_member_attendances.create!(course_member_id: member.id, user_id: member.user_id, course_id: attendance.course_id,
+ course_group_id: member.course_group_id, attendance_status: "NORMAL", attendance_mode: "QUICK")
+ end
+ end
+ end
end
\ No newline at end of file
diff --git a/app/helpers/courses_helper.rb b/app/helpers/courses_helper.rb
index e9d6e4b06..ed76a4b0c 100644
--- a/app/helpers/courses_helper.rb
+++ b/app/helpers/courses_helper.rb
@@ -98,7 +98,7 @@ module CoursesHelper
when "attachment"
"/courses/#{course.id}/file/#{category.id}"
when "video"
- "/courses/#{course.id}/course_videos/#{category.id}"
+ "/courses/#{course.id}/course_video/#{category.id}"
end
end
diff --git a/app/models/challenge.rb b/app/models/challenge.rb
index 70fac990b..5646da363 100644
--- a/app/models/challenge.rb
+++ b/app/models/challenge.rb
@@ -69,12 +69,13 @@ class Challenge < ApplicationRecord
end
# 开启挑战
- def open_game user_id, shixun
- game = self.games.where(user_id: user_id).first
- if game.present?
- shixun.task_pass || game.status != 3 ? "/tasks/#{game.identifier}" : ""
+ def open_game shixun
+ # 这里的identifier,status是关联了games取了games的identifier,status
+ identifier = self.identifier
+ if identifier.present?
+ shixun.task_pass || self.status != 3 ? "/tasks/#{identifier}" : ""
else
- "/api/shixuns/#{shixun.identifier}/shixun_exec"
+ self.position == 1 ? "/api/shixuns/#{shixun.identifier}/shixun_exec" : ""
end
end
@@ -92,16 +93,16 @@ class Challenge < ApplicationRecord
# end
## 用户关卡状态 0: 不能开启实训; 1:直接开启; 2表示已完成
- def user_tpi_status user_id
+ def user_tpi_status shixun
# todo: 以前没加索引导致相同关卡,同一用户有多个games
# 允许跳关则直接开启
- game = games.where(user_id: user_id).take
- if game.blank?
- position == 1 ? 1 : 0
+ identifier = self.identifier
+ if identifier.blank?
+ self.position == 1 ? 1 : 0
else
- if game.status == 3
+ if status == 3
shixun.task_pass ? 1 : 0
- elsif game.status == 2
+ elsif status == 2
2
else
1
diff --git a/app/models/course_attendance.rb b/app/models/course_attendance.rb
index 28059efc1..3b7e07fdf 100644
--- a/app/models/course_attendance.rb
+++ b/app/models/course_attendance.rb
@@ -1,6 +1,6 @@
class CourseAttendance < ApplicationRecord
# status: 0: 未开启,1:已开启,2:已截止
- # mode: 0 两种签到,1 二维码签到,2 数字签到
+ # mode: 0 两种签到,1 二维码签到,2 数字签到,3 快捷签到
enum mode: { ALL: 0, QRCODE: 1, NUMBER: 2, QUICK: 3 }
belongs_to :course
diff --git a/app/models/course_member_attendance.rb b/app/models/course_member_attendance.rb
index 152bb48b6..b854acfe7 100644
--- a/app/models/course_member_attendance.rb
+++ b/app/models/course_member_attendance.rb
@@ -1,6 +1,6 @@
class CourseMemberAttendance < ApplicationRecord
# attendance_mode :0 初始数据,1 二维码签到,2 数字签到,3 老师签到
- enum attendance_mode: { DEFAULT: 0, QRCODE: 1, NUMBER: 2, TEACHER: 3}
+ enum attendance_mode: { DEFAULT: 0, QRCODE: 1, NUMBER: 2, QUICK: 3, TEACHER: 4}
# attendance_status :1 正常签到,2 请假,0 旷课
enum attendance_status: { NORMAL: 1, LEAVE: 2, ABSENCE: 0 }
belongs_to :course_member
diff --git a/app/models/course_video.rb b/app/models/course_video.rb
index e61a439dc..246be34fd 100644
--- a/app/models/course_video.rb
+++ b/app/models/course_video.rb
@@ -1,4 +1,7 @@
class CourseVideo < ApplicationRecord
belongs_to :course
- belongs_to :video
+ belongs_to :video, optional: true
+ belongs_to :user, optional: true
+
+ validates :title, length: { maximum: 60, too_long: "不能超过60个字符" }
end
diff --git a/app/views/challenges/index.json.jbuilder b/app/views/challenges/index.json.jbuilder
index c53ab9c58..d4f2a7f59 100644
--- a/app/views/challenges/index.json.jbuilder
+++ b/app/views/challenges/index.json.jbuilder
@@ -16,10 +16,12 @@ if @challenges.present?
json.st challenge.st
json.name challenge.subject
json.score challenge.score
- json.passed_count challenge.user_passed_count
- json.playing_count challenge.playing_count
+ 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.name_url shixun_challenge_path(challenge, shixun_identifier: @shixun.identifier)
- #json.open_game challenge.open_game(@user.id, @shixun)
+ json.open_game challenge.open_game(@shixun)
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)
@@ -27,6 +29,6 @@ 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 @user.id
+ json.status challenge.user_tpi_status(@shixun)
end
end
diff --git a/app/views/courses/course_videos.json.jbuilder b/app/views/courses/course_videos.json.jbuilder
index 807ff92bb..bee5e89cb 100644
--- a/app/views/courses/course_videos.json.jbuilder
+++ b/app/views/courses/course_videos.json.jbuilder
@@ -1,3 +1,22 @@
json.count @count
-json.videos @videos, partial: 'users/videos/video', as: :video
-json.course_id @course.id
\ No newline at end of file
+
+json.videos @videos do |video|
+ if video.is_link
+ json.(video, :id, :title, :link, :user_id)
+
+ user = video.user
+ json.user_name user&.real_name
+ json.user_img url_to_avatar(user)
+ json.user_login user&.login
+ else
+ json.partial! 'users/videos/video', locals: { video: video.video }
+ end
+end
+
+json.course_id @course.id
+if @category.present?
+ json.category_id @category.id
+ json.category_name @category.name
+end
+json.course_module_id @video_module&.id
+json.has_category @video_module.course_second_categories.size > 0
\ No newline at end of file
diff --git a/app/views/weapps/attendances/student_attendances.json.jbuilder b/app/views/weapps/attendances/student_attendances.json.jbuilder
index c2b9fca12..f0ee4c8f8 100644
--- a/app/views/weapps/attendances/student_attendances.json.jbuilder
+++ b/app/views/weapps/attendances/student_attendances.json.jbuilder
@@ -1,4 +1,4 @@
-json.current_attendance @current_attendance do |attendance|
+json.current_attendance @current_attendances do |attendance|
json.partial! 'student_attendance', locals: {attendance: attendance}
end
diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml
index f9671eec1..4c5c808ac 100644
--- a/config/locales/zh-CN.yml
+++ b/config/locales/zh-CN.yml
@@ -183,6 +183,9 @@ zh-CN:
attendance_date: '签到日期'
start_time: '开始时间'
end_time: '结束时间'
+ course_video:
+ title: '视频名称'
+ link: '链接地址'
diff --git a/config/routes.rb b/config/routes.rb
index 1f9d4cfc4..7bf1b6c1b 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -538,6 +538,8 @@ Rails.application.routes.draw do
get 'search_slim'
end
+ resources :course_videos, only:[:create, :update], shallow: true
+
resources :course_stages, shallow: true do
member do
post :up_position
diff --git a/db/migrate/20200309071103_migrate_member_attendance_mode.rb b/db/migrate/20200309071103_migrate_member_attendance_mode.rb
new file mode 100644
index 000000000..41f81444a
--- /dev/null
+++ b/db/migrate/20200309071103_migrate_member_attendance_mode.rb
@@ -0,0 +1,5 @@
+class MigrateMemberAttendanceMode < ActiveRecord::Migration[5.2]
+ def change
+ CourseMemberAttendance.where(attendance_mode: 3).update_all(attendance_mode: 4)
+ end
+end
diff --git a/db/migrate/20200309101753_add_link_to_course_videos.rb b/db/migrate/20200309101753_add_link_to_course_videos.rb
new file mode 100644
index 000000000..d5580d92e
--- /dev/null
+++ b/db/migrate/20200309101753_add_link_to_course_videos.rb
@@ -0,0 +1,8 @@
+class AddLinkToCourseVideos < ActiveRecord::Migration[5.2]
+ def change
+ add_column :course_videos, :is_link, :boolean, default: 0
+ add_column :course_videos, :title, :string
+ add_column :course_videos, :link, :string
+ add_column :course_videos, :user_id, :integer, index: true
+ end
+end
diff --git a/db/migrate/20200309123121_add_link_to_attachments.rb b/db/migrate/20200309123121_add_link_to_attachments.rb
new file mode 100644
index 000000000..23510be26
--- /dev/null
+++ b/db/migrate/20200309123121_add_link_to_attachments.rb
@@ -0,0 +1,5 @@
+class AddLinkToAttachments < ActiveRecord::Migration[5.2]
+ def change
+ add_column :attachments, :link, :string
+ end
+end
diff --git a/public/images/educoder/xcx/fenxiangs.png b/public/images/educoder/xcx/fenxiangs.png
new file mode 100755
index 000000000..f5b170bed
Binary files /dev/null and b/public/images/educoder/xcx/fenxiangs.png differ
diff --git a/public/images/educoder/xcx/xuesqiandao.png b/public/images/educoder/xcx/xuesqiandao.png
new file mode 100755
index 000000000..7124615fd
Binary files /dev/null and b/public/images/educoder/xcx/xuesqiandao.png differ
diff --git a/public/react/src/common/components/comment/CommentForm.js b/public/react/src/common/components/comment/CommentForm.js
index 11eea72e2..058cceda7 100644
--- a/public/react/src/common/components/comment/CommentForm.js
+++ b/public/react/src/common/components/comment/CommentForm.js
@@ -10,11 +10,9 @@ import './index.scss';
import React, { useState } from 'react';
import { Form, Button, Input } from 'antd';
import QuillForEditor from '../../quillForEditor';
-// import { QuillDeltaToHtmlConverter } from 'quill-delta-to-html'
-// import {formatDelta} from './util';
const FormItem = Form.Item;
-function CommentForm (props) {
+function CommentForm(props) {
const {
onCancel,
@@ -28,9 +26,6 @@ function CommentForm (props) {
const [focus, setFocus] = useState(false);
const options = [
- // ['bold', 'italic', 'underline'],
- // [{header: [1,2,3,false]}],
- 'code-block',
'link',
'image',
'formula'
@@ -52,12 +47,10 @@ function CommentForm (props) {
// 编辑器内容变化时
const handleContentChange = (content) => {
- console.log('编辑器内容', content);
setCtx(content);
try {
// const _html = new QuillDeltaToHtmlConverter(content.ops, {}).convert();
- // props.form.setFieldsValue({'comment': _html.replace(/<\/?[^>]*>/g, '')});
- props.form.setFieldsValue({'comment': content});
+ props.form.setFieldsValue({ 'comment': content });
} catch (error) {
console.log(error);
}
@@ -69,7 +62,7 @@ function CommentForm (props) {
if (!err) {
setShowQuill(false);
const content = ctx;
- props.form.setFieldsValue({'comment': ''});
+ props.form.setFieldsValue({ 'comment': '' });
setCtx('');
// const _html = formatDelta(content.ops);
// console.log('保存的内容=====》》》》', content);
@@ -95,7 +88,7 @@ function CommentForm (props) {
{
getFieldDecorator('comment', {
rules: [
- { required: true, message: '评论内容不能为空'}
+ { required: true, message: '评论内容不能为空' }
],
})(