dev_forum
杨树林 5 years ago
commit 4d752d99d5

@ -187,15 +187,32 @@ class ApplicationController < ActionController::Base
# 系统全局认证 # 系统全局认证
def check_auth def check_auth
if current_user.certification != 1 && current_user.apply_actions.exists?(container_type: 'TrialAuthorization', status: 0)
tip_exception(408, "您的试用申请正在审核中,请耐心等待")
elsif current_user.certification != 1
day_cer = UserDayCertification.find_by(user_id: current_user.id) day_cer = UserDayCertification.find_by(user_id: current_user.id)
tip_exception(407, "系统未授权") unless (Time.now.to_i - day_cer.try(:created_at).to_i) < 86400 # 如果注册超过24小时则需要完善资料及授权
elsif !current_user.profile_completed? if (Time.now.to_i - day_cer.try(:created_at).to_i) > 86400
if !current_user.profile_completed?
info_url = '/account/profile' info_url = '/account/profile'
tip_exception(402, info_url) tip_exception(402, info_url)
elsif current_user.certification != 1
if current_user.apply_actions.exists?(container_type: 'TrialAuthorization', status: 0)
tip_exception(408, "您的试用申请正在审核中,请耐心等待")
end end
tip_exception(407, "系统未授权")
end
end
# if current_user.certification != 1 && current_user.apply_actions.exists?(container_type: 'TrialAuthorization', status: 0)
# tip_exception(408, "您的试用申请正在审核中,请耐心等待")
# elsif (Time.now.to_i - day_cer.try(:created_at).to_i) < 86400
# if !current_user.profile_completed?
# info_url = '/account/profile'
# tip_exception(402, info_url)
# elsif current_user.certification != 1
# day_cer = UserDayCertification.find_by(user_id: current_user.id)
# tip_exception(407, "系统未授权") unless (Time.now.to_i - day_cer.try(:created_at).to_i) < 86400
# end
# end
end end
def start_user_session(user) def start_user_session(user)

@ -14,7 +14,7 @@ class CoursesController < ApplicationController
before_action :require_login, except: [:index, :show, :students, :teachers, :board_list, :mine, :all_course_groups, before_action :require_login, except: [:index, :show, :students, :teachers, :board_list, :mine, :all_course_groups,
:left_banner, :top_banner] :left_banner, :top_banner]
before_action :check_auth, except: [:index, :show, :students, :teachers, :board_list, :mine, :all_course_groups, before_action :check_auth, except: [:index, :show, :students, :teachers, :board_list, :mine, :all_course_groups,
:left_banner, :top_banner, :apply_to_join_course] :left_banner, :top_banner, :apply_to_join_course, :exit_course]
before_action :set_course, :user_course_identity, only: [:show, :update, :destroy, :settings, :set_invite_code_halt, before_action :set_course, :user_course_identity, only: [:show, :update, :destroy, :settings, :set_invite_code_halt,
:set_public_or_private, :search_teacher_candidate, :teachers, :apply_teachers, :set_public_or_private, :search_teacher_candidate, :teachers, :apply_teachers,
:top_banner, :left_banner, :add_teacher_popup, :add_teacher, :top_banner, :left_banner, :add_teacher_popup, :add_teacher,
@ -891,7 +891,7 @@ class CoursesController < ApplicationController
# end # end
# 创建学生身份 # 创建学生身份
if params[:student].present? if params[:student].present? && params[:student].to_i == 1
existing_student = CourseMember.find_by(course_id: course.id, role: %i[STUDENT], user_id: current_user.id) existing_student = CourseMember.find_by(course_id: course.id, role: %i[STUDENT], user_id: current_user.id)
if existing_student.present? if existing_student.present?
# 如果在该课堂已经存在学生身份,且邀请码为分班邀请码,则将其直接加入分班 # 如果在该课堂已经存在学生身份,且邀请码为分班邀请码,则将其直接加入分班
@ -911,7 +911,7 @@ class CoursesController < ApplicationController
end end
# 创建教师身份 # 创建教师身份
if params[:professor].present? || params[:assistant_professor].present? if (params[:professor].present? && params[:professor].to_i == 1) || (params[:assistant_professor].present? && params[:assistant_professor].to_i == 1)
teacher_already_exist = current_user.teacher_of_course_non_active? course teacher_already_exist = current_user.teacher_of_course_non_active? course
unless teacher_already_exist unless teacher_already_exist
existing_course_message = CourseMessage.find_by(course_id: course.id, course_message_id: current_user.id, existing_course_message = CourseMessage.find_by(course_id: course.id, course_message_id: current_user.id,
@ -920,8 +920,8 @@ class CoursesController < ApplicationController
course_message = CourseMessage.new(course_id: course.id, user_id: course.tea_id, status: 0, course_message = CourseMessage.new(course_id: course.id, user_id: course.tea_id, status: 0,
course_message_id: current_user.id, course_message_type: "JoinCourseRequest", course_message_id: current_user.id, course_message_type: "JoinCourseRequest",
viewed: false) viewed: false)
course_message.content = 2 if params[:professor].present? course_message.content = 2 if params[:professor].present? && params[:professor].to_i == 1
course_message.content = 3 if params[:assistant_professor].present? course_message.content = 3 if params[:assistant_professor].present? && params[:assistant_professor].to_i == 1
course_message.save! course_message.save!

@ -556,10 +556,19 @@ class GamesController < ApplicationController
msg = @game.run_code_message msg = @game.run_code_message
msg.update_attributes(:status => 0, :message => nil) if msg.present? msg.update_attributes(:status => 0, :message => nil) if msg.present?
# 更新时间是为了TPM端显示的更新退出实训及访问实训的时候会更新 # 更新时间是为了TPM端显示的更新退出实训及访问实训的时候会更新如果版本库地址不存在重新去版本库中找
@myshixun.update_column(:updated_at, Time.now) myshixuns_update =
if @myshixun.repo_name.nil?
g = Gitlab.client
repo_name = g.project(@myshixun.gpid).path_with_namespace
{repo_name: repo_name}
else
{updated_at: Time.now}
end
logger.info("#############myshixuns_update: ##{myshixuns_update}")
@myshixun.update_attributes!(myshixuns_update)
gitUrl = repo_ip_url @myshixun.repo_path gitUrl = repo_ip_url @myshixun.repo_path
logger.info("#############giturl: ##{gitUrl}") logger.info("#############giturl: ##{gitUrl}")
gitUrl = Base64.urlsafe_encode64(gitUrl) gitUrl = Base64.urlsafe_encode64(gitUrl)

@ -0,0 +1,87 @@
class LibrariesController < ApplicationController
include PaginateHelper
before_action :require_login, :check_auth, except: %i[index show]
helper_method :current_library, :library_manageable?
def index
libraries = Library.all
libraries =
if User.current&.logged? && params[:type] == 'mine'
libraries.where(user_id: current_user.id).order(created_at: :desc)
else
libraries.where(status: :published).order(visited_count: :desc)
end
keyword = params[:keyword].to_s.strip
if keyword.present?
libraries = libraries.where('title LIKE :keyword OR author_name LIKE :keyword OR author_school_name LIKE :keyword',
keyword: "%#{keyword}%")
end
@count = libraries.count
@libraries = paginate libraries.includes(:library_tags, :praise_tread_cache, user: :user_extension)
ids = @libraries.map(&:id)
@download_count_map = Attachment.where(container_type: 'Library', container_id: ids)
.group(:container_id).sum(:downloads)
end
def show
unless current_library.published? || library_manageable?(current_library)
return render_forbidden
end
end
def create
library = current_user.libraries.new
Libraries::SaveService.call(library, current_user, save_params)
render_ok
rescue Libraries::SaveService::Error => ex
render_error(ex.message)
end
def update
return render_forbidden unless library_manageable?(current_library)
Libraries::SaveService.call(current_library, current_user, save_params)
render_ok
rescue Libraries::SaveService::Error => ex
render_error(ex.message)
end
def destroy
if admin_or_business?
current_library.destroy!
elsif current_library.user_id == current_user&.id
unless current_library.pending?
render_error('只有草稿才能删除')
return
end
current_library.destroy!
else
render_forbidden
return
end
render_ok
end
private
def current_library
@_current_library ||= Library.find(params[:id])
end
def library_manageable?(library)
current_user&.id == library.user_id || admin_or_business?
end
def save_params
params.permit(:title, :content, :author_name, :author_school_name,
:cover_id, :publish, attachment_ids: [], tag_ids: [])
end
end

@ -1,7 +1,7 @@
class SubjectsController < ApplicationController class SubjectsController < ApplicationController
before_action :require_login, :check_auth, except: [:index] before_action :require_login, :check_auth, except: [:index]
# before_action :check_auth, except: [:index] # before_action :check_auth, except: [:index]
before_action :find_subject, except: [:index, :create, :append_to_stage] before_action :find_subject, except: [:index, :create, :new, :append_to_stage]
before_action :allowed, only: [:update, :edit, :destroy, :publish, :cancel_publish, :cancel_has_publish, before_action :allowed, only: [:update, :edit, :destroy, :publish, :cancel_publish, :cancel_has_publish,
:search_members, :add_subject_members, :statistics, :shixun_report, :school_report, :search_members, :add_subject_members, :statistics, :shixun_report, :school_report,
:up_member_position, :down_member_position] :up_member_position, :down_member_position]
@ -89,11 +89,17 @@ class SubjectsController < ApplicationController
# 用户获取的实训标签 # 用户获取的实训标签
# @user_tags = @subject.shixuns.map(&:user_tags_name).flatten.uniq # @user_tags = @subject.shixuns.map(&:user_tags_name).flatten.uniq
@user_tags = user_shixun_tags challenge_ids, @user.id @user_tags = user_shixun_tags challenge_ids, @user.id
@my_subject_progress = @subject.my_subject_progress
@challenge_count = challenge_ids.size
# 访问数变更 # 访问数变更
@subject.increment!(:visits) @subject.increment!(:visits)
end end
def new
normal_status("")
end
def create def create
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
begin begin
@ -140,11 +146,10 @@ class SubjectsController < ApplicationController
@type = params[:type] @type = params[:type]
# 超级管理员用户显示所有未隐藏的实训、非管理员显示合作团队用户的实训(对本单位公开且未隐藏) # 超级管理员用户显示所有未隐藏的实训、非管理员显示合作团队用户的实训(对本单位公开且未隐藏)
if current_user.admin? if current_user.admin?
@shixuns = Shixun.select([:id, :name, :status, :myshixuns_count, :identifier]).where(hidden: 0) @shixuns = Shixun.select([:id, :name, :status, :myshixuns_count, :identifier, :averge_star]).where(hidden: 0)
else else
none_shixun_ids = ShixunSchool.where("school_id != #{current_user.user_extension.try(:school_id).to_i}").pluck(:shixun_id) none_shixun_ids = ShixunSchool.where("school_id != #{current_user.user_extension.try(:school_id).to_i}").pluck(:shixun_id)
@shixuns = Shixun.select([:id, :name, :status, :myshixuns_count, :identifier, :averge_star]).where.not(id: none_shixun_ids).where(hidden: 0)
@shixuns = Shixun.select([:id, :name, :status, :myshixuns_count, :identifier]).where.not(id: none_shixun_ids).where(hidden: 0)
end end
# 实训课程的所有标签 # 实训课程的所有标签

@ -0,0 +1,5 @@
module LibraryDecorator
extend ApplicationDecorator
display_time_method :published_at, :created_at, :updated_at
end

@ -0,0 +1,12 @@
class Libraries::SaveForm
include ActiveModel::Model
attr_accessor :title, :content, :author_name, :author_school_name, :cover_id,
:publish, :attachment_ids, :tag_ids
validates :title, presence: true, length: { maximum: 255 }
validates :content, presence: true
validates :author_name, presence: true, length: { maximum: 10 }
validates :author_school_name, presence: true, length: { maximum: 50 }
validates :attachment_ids, presence: true
end

@ -168,7 +168,8 @@ module ApplicationHelper
# 选用实训的学校情况 # 选用实训的学校情况
def school_user_detail shixun def school_user_detail shixun
school_ids = shixun.myshixuns.joins("join user_extensions ue on myshixuns.user_id=ue.user_id").pluck(:school_id).uniq user_ids = shixun.myshixuns.map(&:user_id).uniq # 走缓存取数据
school_ids = UserExtension.where(user_id:user_ids).pluck(:school_id).uniq
school_names = School.where(id: school_ids[0..1]).pluck(:name) school_names = School.where(id: school_ids[0..1]).pluck(:name)
school_size = school_ids.size school_size = school_ids.size
str = school_size > 0 ? "#{school_names.join("")}#{school_size}" : "0所" str = school_size > 0 ? "#{school_names.join("")}#{school_size}" : "0所"

@ -13,6 +13,7 @@ module SubjectsHelper
# 实训路径的所有用户获得的标签 # 实训路径的所有用户获得的标签
def user_shixun_tags challenge_ids, user_id def user_shixun_tags challenge_ids, user_id
ChallengeTag.joins(challenge: [:games]).where(games: {status: 2, user_id: user_id}, challenges: {id:challenge_ids}).pluck("challenge_tags.name").uniq 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 end
end end

@ -0,0 +1,9 @@
module Util
module UUID
module_function
def time_uuid(format: '%Y%m%d%H%M%S', suffix: 8)
"#{Time.zone.now.strftime(format)}#{Random.rand(10**suffix).to_i}"
end
end
end

@ -0,0 +1,43 @@
class Library < ApplicationRecord
include AASM
belongs_to :user
belongs_to :cover, class_name: 'Attachment', foreign_key: :cover_id, optional: true
has_many :library_applies, dependent: :delete_all
has_many :library_library_tags, dependent: :delete_all
has_many :library_tags, through: :library_library_tags
has_many :attachments, as: :container
has_one :praise_tread_cache, foreign_key: :object_id
validates :uuid, presence: true, uniqueness: true
aasm(:status) do
state :pending, initiali: true
state :processing
state :refused
state :published
event :submit do
transitions from: [:pending, :refused], to: :processing
end
event :refuse do
transitions from: :processing, to: :refused
end
event :publish do
transitions from: :processing, to: :published
end
end
def generate_uuid
uuid = Util::UUID.time_uuid
while Library.exists?(uuid: uuid)
uuid = Util::UUID.time_uuid
end
self.uuid = uuid
end
end

@ -0,0 +1,19 @@
class LibraryApply < ApplicationRecord
include AASM
belongs_to :library
aasm(:status) do
state :pending, initiali: true
state :refused
state :agreed
event :refuse do
transitions from: :pending, to: :refused
end
event :agree do
transitions from: :pending, to: :agreed
end
end
end

@ -0,0 +1,4 @@
class LibraryLibraryTag < ApplicationRecord
belongs_to :library
belongs_to :library_tag
end

@ -0,0 +1,6 @@
class LibraryTag < ApplicationRecord
has_many :library_library_tags, dependent: :delete_all
has_many :libraries, through: :library_library_tags
validates :name, presence: true, uniqueness: true
end

@ -0,0 +1,32 @@
class Libraries::AgreeApplyService < ApplicationService
Error = Class.new(StandardError)
attr_reader :library_apply, :library, :user
def initialize(library_apply, user)
@library_apply = library_apply
@library = library_apply.library
@user = user
end
def call
raise Error, '该状态下不能进行此操作' unless library_apply.may_agree?
ActiveRecord::Base.transaction do
library_apply.agree!
library_apply.library.publish!
# 将消息改为已处理
Tiding.where(container_id: library.id, container_type: 'Library', tiding_type: 'Apply', status: 0).update_all(status: 1)
notify_library_author!
end
end
private
def notify_library_author!
Tiding.create!(user_id: library.user_id, trigger_user_id: 1,
container_id: library.id, container_type: 'Library',
tiding_type: 'System', status: 1)
end
end

@ -0,0 +1,39 @@
class Libraries::RefuseApplyService < ApplicationService
Error = Class.new(StandardError)
attr_reader :library_apply, :library, :user, :params
def initialize(library_apply, user, params)
@library_apply = library_apply
@library = library_apply.library
@user = user
@params = params
end
def call
reason = params[:reason].to_s.strip
raise Error, '原因不能为空' if reason.blank?
raise Error, '该状态下不能进行此操作' unless library_apply.may_refuse?
ActiveRecord::Base.transaction do
library_apply.reason = reason
library_apply.refused_at = Time.current
library_apply.refuse
library_apply.save!
library.refuse!
# 将消息改为已处理
Tiding.where(container_id: library.id, container_type: 'Library', tiding_type: 'Apply', status: 0).update_all(status: 1)
notify_library_author!
end
end
private
def notify_library_author!
Tiding.create!(user_id: library.user_id, trigger_user_id: 1,
container_id: library.id, container_type: 'Library',
tiding_type: 'System', status: 2, extra: library_apply.reason)
end
end

@ -0,0 +1,69 @@
class Libraries::SaveService < ApplicationService
Error = Class.new(StandardError)
attr_reader :library, :user, :params
def initialize(library, user, params)
@library = library
@user = user
@params = params
end
def call
Libraries::SaveForm.new(params).validate!
if library.new_record?
library.user_id = user.id
library.generate_uuid
end
ActiveRecord::Base.transaction do
library.assign_attributes(library_params)
library.save!
deal_library_tag!
deal_attachments!
Libraries::SubmitService.call(library) if with_publish?
end
library
rescue Libraries::SubmitService::Error => ex
raise Error, ex.message
end
private
def deal_library_tag!
new_tag_ids = LibraryTag.where(id: Array.wrap(params[:tag_ids]).compact).pluck(:id)
old_tag_ids = library.library_library_tags.pluck(:library_tag_id)
# 删除标签
destroy_ids = old_tag_ids - new_tag_ids
library.library_library_tags.where(library_tag_id: destroy_ids).delete_all
# 创建标签
created_ids = new_tag_ids - old_tag_ids
created_ids.each do |id|
library.library_library_tags.create!(library_tag_id: id)
end
end
def deal_attachments!
attachment_ids = Array.wrap(params[:attachment_ids]).compact.map(&:to_i)
old_attachment_id = library.attachments.pluck(:id)
destroy_ids = old_attachment_id - attachment_ids
library.attachments.where(id: destroy_ids).delete_all
Attachment.where(id: attachment_ids, author_id: user.id).update_all(container: library)
end
def library_params
params.slice(*%i[title content author_name author_school_name cover_id])
end
def with_publish?
params[:publish].to_s == 'true'
end
end

@ -0,0 +1,32 @@
class Libraries::SubmitService < ApplicationService
Error = Class.new(StandardError)
attr_reader :library
def initialize(library)
@library = library
end
def call
return if library.processing? || library.published?
raise Error, '该状态下不能提交审核' unless library.may_submit?
ActiveRecord::Base.transaction do
library.published_at = Time.current
library.submit
library.save!
library.library_applies.create!
send_library_apply_notify!
end
end
private
def send_library_apply_notify!
Tiding.create!(user_id: 1, trigger_user_id: library.user_id,
container_id: library.id, container_type: 'Library',
tiding_type: 'Apply', status: 0)
end
end

@ -13,7 +13,7 @@ class Users::BindEmailService < ApplicationService
raise Error, '该邮箱已被绑定' if User.where.not(id: user.id).exists?(mail: params[:email]) raise Error, '该邮箱已被绑定' if User.where.not(id: user.id).exists?(mail: params[:email])
code = VerificationCode.where(email: params[:email], code: params[:code], code_type: 4).last code = VerificationCode.where(email: params[:email], code: params[:code], code_type: 5).last
raise Error, '验证码无效' unless code&.effective? raise Error, '验证码无效' unless code&.effective?
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do

@ -21,7 +21,7 @@ if question.question_type <= 2 #当为选择题或判断题时,只显示选
user_answer_b = user_answer.include?(a.id) user_answer_b = user_answer.include?(a.id)
json.c_position (index+1) if ex_choice_random_boolean #当选项随机时,选项位置以此为准,否则不出现 json.c_position (index+1) if ex_choice_random_boolean #当选项随机时,选项位置以此为准,否则不出现
json.choice_id a.id json.choice_id a.id
json.choice_text "#{(index+65).chr}.#{a.choice_text}" json.choice_text (edit_type.present? || question.question_type == 2) ? a.choice_text : "#{(index+65).chr}.#{a.choice_text}"
json.choice_position a.choice_position json.choice_position a.choice_position
if exercise_type == 1 || exercise_type == 4 #1为教师编辑/预览 试卷或问题2为空白试卷即标准答案和用户答案都不显示3为用户开始答题的显示4为老师评阅试卷或学生在截止后查看试卷 if exercise_type == 1 || exercise_type == 4 #1为教师编辑/预览 试卷或问题2为空白试卷即标准答案和用户答案都不显示3为用户开始答题的显示4为老师评阅试卷或学生在截止后查看试卷
json.standard_boolean standard_answer_b json.standard_boolean standard_answer_b

@ -6,4 +6,5 @@ json.partial! "exercise_questions/exercise_questions",
shixun_challenges: @exercise_question_shixun, shixun_challenges: @exercise_question_shixun,
exercise_type:1, exercise_type:1,
user_answer:[], user_answer:[],
ques_position:nil ques_position:nil,
edit_type:true

@ -6,4 +6,5 @@ json.partial! "exercise_questions/exercise_questions",
shixun_challenges: @exercise_question_shixun, shixun_challenges: @exercise_question_shixun,
exercise_type:1, exercise_type:1,
user_answer:[], user_answer:[],
ques_position:nil ques_position:nil,
edit_type:nil

@ -62,7 +62,8 @@ json.exercise_questions do
exercise_type: ex_type, exercise_type: ex_type,
user_answer: user_ques_answers[:answered_content], user_answer: user_ques_answers[:answered_content],
shixun_type: user_ques_answers[:shixun_type], shixun_type: user_ques_answers[:shixun_type],
ques_position: nil ques_position: nil,
edit_type:nil
if user_ques_comments.count > 0 if user_ques_comments.count > 0
json.question_comments do json.question_comments do
json.partial! "exercises/exercise_comments", question_comment:user_ques_answers[:question_comment].first json.partial! "exercises/exercise_comments", question_comment:user_ques_answers[:question_comment].first

@ -12,7 +12,8 @@ json.exercise_questions do
shixun_challenges: q.exercise_shixun_challenges, shixun_challenges: q.exercise_shixun_challenges,
exercise_type:2, exercise_type:2,
user_answer:[], user_answer:[],
ques_position:nil ques_position:nil,
edit_type:nil
end end
end end

@ -16,7 +16,8 @@ json.exercise_questions do
exercise_type:1, exercise_type:1,
user_answer:[], user_answer:[],
shixun_type:0, shixun_type:0,
ques_position:nil ques_position:nil,
edit_type:true
end end
end end

@ -19,7 +19,8 @@ json.exercise_questions do
exercise_type:1, exercise_type:1,
user_answer:[], user_answer:[],
shixun_type:0, shixun_type:0,
ques_position:nil ques_position:nil,
edit_type:nil
end end
end end

@ -59,6 +59,7 @@ json.exercise_questions do
choices:question.exercise_choices, choices:question.exercise_choices,
exercise_type:3, exercise_type:3,
shixun_type:question_info[:shixun_type], shixun_type:question_info[:shixun_type],
ques_position: q[:ques_number] ques_position: q[:ques_number],
edit_type:nil
end end
end end

@ -0,0 +1,16 @@
json.count @count
json.libraries do
json.array! @libraries.each do |library|
json.extract! library, :id, :title, :content, :author_name, :author_school_name, :status, :visited_count
json.cover_url library.cover_id.present? ? download_url(library.cover) : nil
json.praise_count library.praise_tread_cache&.praise_num || 0
json.download_count @download_count_map.fetch(library.id, 0)
json.published_at library.display_published_at
json.created_at library.display_created_at
json.tags library.library_tags.map(&:name)
end
end

@ -0,0 +1,46 @@
library = current_library
json.extract! library, :id, :uuid, :title, :content, :author_name, :author_school_name, :status, :visited_count
json.praise_count library.praise_tread_cache&.praise_num || 0
json.published_at library.display_published_at
json.created_at library.display_created_at
# 创建者
json.creator do
json.partial! 'users/user_simple', user: library.user
end
# 封面
if library.cover_id.present?
json.cover do
json.partial! 'attachments/attachment_simple', attachment: library.cover
end
else
json.cover nil
end
json.attachments library.attachments, partial: 'attachments/attachment_small', as: :attachment
# 标签
json.tags do
json.array! library.library_tags.each do |tag|
json.extract! tag, :id, :name
end
end
# 操作权限
json.operation do
if current_user&.logged?
manageable = library_manageable?(library)
json.can_deletable manageable
json.can_editable manageable
json.user_praised PraiseTread.exists?(user_id: current_user&.id)
else
json.can_deletable false
json.can_editable false
json.user_praised false
end
end

@ -10,5 +10,5 @@ json.array! shixuns do |shixun|
json.shixun_name shixun.name json.shixun_name shixun.name
json.myshixuns_count shixun.myshixuns_count json.myshixuns_count shixun.myshixuns_count
json.school_users school_user_detail(shixun) json.school_users school_user_detail(shixun)
json.preference format("%.1f", shixun.shixun_preference) json.preference format("%.1f", shixun.averge_star)
end end

@ -0,0 +1,12 @@
'zh-CN':
activemodel:
attributes:
libraries/save_form:
title: 标题
content: 描述
author_name: 作者名称
author_school_name: 作者单位
cover_id: 封面
publish: ''
attachment_ids: 附件
tag_ids: 标签

@ -690,6 +690,8 @@ Rails.application.routes.draw do
post :win, on: :collection post :win, on: :collection
end end
end end
resources :libraries, only: [:index, :show, :create, :update, :destroy]
end end
#git 认证回调 #git 认证回调

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -2,7 +2,8 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <!-- width=device-width, initial-scale=1 , shrink-to-fit=no -->
<!-- <meta name="viewport" content=""> -->
<meta name="theme-color" content="#000000"> <meta name="theme-color" content="#000000">
<!-- <!--
manifest.json provides metadata used when your web app is added to the manifest.json provides metadata used when your web app is added to the

@ -18,10 +18,10 @@ function locationurl(list){
} }
// TODO 开发期多个身份切换 // TODO 开发期多个身份切换
// const debugType =""; const debugType =""
const debugType =window.location.search.indexOf('debug=t') != -1 ? 'teacher' : // window.location.search.indexOf('debug=t') != -1 ? 'teacher' :
window.location.search.indexOf('debug=s') != -1 ? 'student' : 'admin' // window.location.search.indexOf('debug=s') != -1 ? 'student' : 'admin'
window._debugType = debugType; // window._debugType = debugType;
export function initAxiosInterceptors(props) { export function initAxiosInterceptors(props) {
// TODO 避免重复的请求 https://github.com/axios/axios#cancellation // TODO 避免重复的请求 https://github.com/axios/axios#cancellation

@ -101,6 +101,7 @@ class Addcourses extends Component{
}) })
}else{ }else{
this.setState({ this.setState({
professor:null,
assistant_professor:null, assistant_professor:null,
Checkboxteacherchecked:e.target.checked, Checkboxteacherchecked:e.target.checked,
Checkboxteachingtype:false Checkboxteachingtype:false
@ -128,7 +129,7 @@ class Addcourses extends Component{
hidetojoinclass=()=>{ hidetojoinclass=()=>{
let {Addcoursestype}=this.props;
// console.log(this.props) // console.log(this.props)
this.setState({ this.setState({
invite_code:undefined, invite_code:undefined,
@ -143,11 +144,16 @@ class Addcourses extends Component{
student:null, student:null,
Addcoursestypes:false Addcoursestypes:false
}) })
if(Addcoursestype===true){
this.props.hideAddcoursestype(); this.props.hideAddcoursestype();
} }
}
submitasyn=(course_id)=>{ submitasyn=(course_id)=>{
let{professor}=this.state; let{professor,Addcoursestype}=this.state;
if(professor===1){ if(professor===1){
this.setState({ this.setState({
loadtype:true, loadtype:true,
@ -156,13 +162,17 @@ class Addcourses extends Component{
modalSave:(course_id)=>this.submitasyns(course_id), modalSave:(course_id)=>this.submitasyns(course_id),
Addcoursestype:false Addcoursestype:false
}) })
if(Addcoursestype===true){
this.props.hideAddcoursestype(); this.props.hideAddcoursestype();
}
}else{ }else{
// let{course_id}=this.state; // let{course_id}=this.state;
this.setState({ this.setState({
Addcoursestype:false Addcoursestype:false
}) })
if(Addcoursestype===true){
this.props.hideAddcoursestype(); this.props.hideAddcoursestype();
}
window.location.href ="/courses/"+course_id+"/students"; window.location.href ="/courses/"+course_id+"/students";
} }
@ -172,6 +182,7 @@ class Addcourses extends Component{
} }
submittojoinclass=()=>{ submittojoinclass=()=>{
let{Addcoursestype}=this.state;
this.setState({ this.setState({
isSpin:true isSpin:true
}) })
@ -213,6 +224,12 @@ class Addcourses extends Component{
// // modalSave:this.submitasyn, // // modalSave:this.submitasyn,
// course_id:response.data.course_id // course_id:response.data.course_id
// }) // })
// https://www.trustie.net/issues/22365
if (response.data.course_id == 2704) {
this.props.history.push('/courses/2704/boards/8367/messages/42072')
return;
}
if(response.data.course_id!=undefined){ if(response.data.course_id!=undefined){
this.submitasyn(response.data.course_id) this.submitasyn(response.data.course_id)
} }
@ -220,7 +237,9 @@ class Addcourses extends Component{
message:"提示", message:"提示",
description:response.data.message description:response.data.message
}); });
if(Addcoursestype===true){
this.props.hideAddcoursestype(); this.props.hideAddcoursestype();
}
// this.props.showNotification(response.data.message); // this.props.showNotification(response.data.message);
@ -233,7 +252,9 @@ class Addcourses extends Component{
this.setState({ this.setState({
Addcoursestype:false Addcoursestype:false
}) })
if(Addcoursestype===true){
this.props.hideAddcoursestype(); this.props.hideAddcoursestype();
}
// this.setState({ // this.setState({
@ -331,7 +352,7 @@ class Addcourses extends Component{
keyboard={false} keyboard={false}
className={"HomeworkModal"} className={"HomeworkModal"}
title="加入课堂" title="加入课堂"
visible={Addcoursestype===undefined?Addcoursestypes:Addcoursestype} visible={Addcoursestype===undefined||Addcoursestype===false?Addcoursestypes:Addcoursestype}
closable={false} closable={false}
footer={null} footer={null}
destroyOnClose={true} destroyOnClose={true}

@ -54,7 +54,7 @@ class SingleDisplay extends Component{
} }
render() { render() {
let { question_title, question_score, question_type, question_choices, standard_answer, let { question_title, question_score, question_type, question_choices, standard_answer,
question_id, question_number, index, displayCount question_id, question_number, index, displayCount, showActionButton
} = this.props; } = this.props;
// const { getFieldDecorator } = this.props.form; // const { getFieldDecorator } = this.props.form;
@ -70,6 +70,9 @@ class SingleDisplay extends Component{
// const answerTagArray = standard_answer.map((item, index) => { return item == true ? tagArray[index] : -1 }).filter(item => item != -1); // const answerTagArray = standard_answer.map((item, index) => { return item == true ? tagArray[index] : -1 }).filter(item => item != -1);
let length = 5; let length = 5;
const qName = qNameArray[question_type] const qName = qNameArray[question_type]
const isPreviewPage = showActionButton == false
return( return(
<div className="bor-bottom-greyE padding20-30 singleDisplay" id={qNumber} _id={question_id}> <div className="bor-bottom-greyE padding20-30 singleDisplay" id={qNumber} _id={question_id}>
<style>{` <style>{`
@ -89,10 +92,14 @@ class SingleDisplay extends Component{
{/* 单选 or 多选 */} {/* 单选 or 多选 */}
<div className="options"> <div className="options">
{ question_choices.map((item, optionIndex) => { { question_choices.map((item, optionIndex) => {
let prefix = undefined
if (!isPreviewPage) {
prefix = `${tagArray[optionIndex]}.`
}
if (question_type == 0) { // 单选 if (question_type == 0) { // 单选
return ( return (
<div className="mb10 clearfix" key={optionIndex}> <div className="mb10 clearfix" key={optionIndex}>
<Radio disabled className="fl lineh-20" checked={item.standard_boolean}></Radio> <Radio disabled className="fl lineh-20" checked={item.standard_boolean}>{prefix}</Radio>
<span style={{ display: 'inline-block'}} className="markdown-body fl" <span style={{ display: 'inline-block'}} className="markdown-body fl"
dangerouslySetInnerHTML={{__html: markdownToHTML(item.choice_text)}}></span> dangerouslySetInnerHTML={{__html: markdownToHTML(item.choice_text)}}></span>
</div>) </div>)
@ -100,7 +107,7 @@ class SingleDisplay extends Component{
return ( return (
<div className="mb10 clearfix" key={optionIndex}> <div className="mb10 clearfix" key={optionIndex}>
<Checkbox disabled className="fl lineh-20" checked={item.standard_boolean}></Checkbox> <Checkbox disabled className="fl lineh-20" checked={item.standard_boolean}>{prefix}</Checkbox>
<span style={{ display: 'inline-block'}} className="markdown-body fl" <span style={{ display: 'inline-block'}} className="markdown-body fl"
dangerouslySetInnerHTML={{__html: markdownToHTML(item.choice_text)}}></span> dangerouslySetInnerHTML={{__html: markdownToHTML(item.choice_text)}}></span>
</div>) </div>)

@ -1137,7 +1137,7 @@ class ShixunHomework extends Component{
`}</style> `}</style>
{/*onChange={this.onCheckBoxChange} value={checkBoxValues}*/} {/*onChange={this.onCheckBoxChange} value={checkBoxValues}*/}
{datas===undefined?"": <Checkbox.Group style={{ width: '100%' }} onChange={this.onCheckBoxChange} value={this.state.checkBoxValues}> {datas===undefined?"": <Checkbox.Group style={{ width: '100%' }} onChange={this.onCheckBoxChange} value={this.state.checkBoxValues}>
{ datas.homeworks.map((item, index) => { { datas.homeworks && datas.homeworks.map((item, index) => {
// console.log("ShixunhomeWorkItem") // console.log("ShixunhomeWorkItem")
// console.log("++++++++++++++++++++++++++++++++++++++++++") // console.log("++++++++++++++++++++++++++++++++++++++++++")
// console.log(JSON.stringify(this.props)) // console.log(JSON.stringify(this.props))

@ -139,7 +139,9 @@ class PathDetailIndex extends Component{
let pathid=this.props.match.params.pathId; let pathid=this.props.match.params.pathId;
let url="/paths/"+pathid+".json"; let url="/paths/"+pathid+".json";
axios.get(url).then((result)=>{ axios.get(url).then((result)=>{
if (result.data.status == 407) {
return;
}
if(result.data.allow_visit===true){ if(result.data.allow_visit===true){
this.setState({ this.setState({
detailInfoList:result.data, detailInfoList:result.data,
@ -162,6 +164,9 @@ class PathDetailIndex extends Component{
let pathid=this.props.match.params.pathId; let pathid=this.props.match.params.pathId;
let url="/paths/"+pathid+".json"; let url="/paths/"+pathid+".json";
axios.get(url).then((result)=>{ axios.get(url).then((result)=>{
if (result.data.status == 407) {
return;
}
if(result.data.allow_visit===true){ if(result.data.allow_visit===true){
this.setState({ this.setState({
detailInfoList:result.data, detailInfoList:result.data,

Loading…
Cancel
Save