diff --git a/app/controllers/admins/examination_authentications_controller.rb b/app/controllers/admins/examination_authentications_controller.rb index 8045644e1..c68c062b6 100644 --- a/app/controllers/admins/examination_authentications_controller.rb +++ b/app/controllers/admins/examination_authentications_controller.rb @@ -12,7 +12,7 @@ class Admins::ExaminationAuthenticationsController < Admins::BaseController ActiveRecord::Base.transaction do exam = ExaminationBank.find current_apply.container_id current_apply.update!(status: 1) - exam.update!(public: 0) + exam.update!(public: 1) end render_success_js end diff --git a/app/controllers/admins/item_authentications_controller.rb b/app/controllers/admins/item_authentications_controller.rb index 88d833ee9..8da9b232f 100644 --- a/app/controllers/admins/item_authentications_controller.rb +++ b/app/controllers/admins/item_authentications_controller.rb @@ -16,7 +16,7 @@ class Admins::ItemAuthenticationsController < Admins::BaseController ActiveRecord::Base.transaction do item = ItemBank.find current_apply.container_id current_apply.update!(status: 1) - item.update!(public: 0) + item.update!(public: 1) end render_success_js end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index b418d528a..f68784db8 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -85,8 +85,8 @@ class ApplicationController < ActionController::Base # 题库的访问权限 def bank_visit_auth - tip_exception(-2,"未通过职业认证") if current_user.is_teacher? && !current_user.certification_teacher? && !current_user.admin? && @bank.user_id != current_user.id && @bank.is_public - tip_exception(403, "无权限") unless @bank.user_id == current_user.id || current_user.admin? || + tip_exception(-2,"未通过职业认证") if current_user.is_teacher? && !current_user.certification_teacher? && !current_user.admin_or_business? && @bank.user_id != current_user.id && @bank.is_public + tip_exception(403, "无权限") unless @bank.user_id == current_user.id || current_user.admin_or_business? || (current_user.certification_teacher? && @bank.is_public) end @@ -165,7 +165,7 @@ class ApplicationController < ActionController::Base def find_course return normal_status(2, '缺少course_id参数!') if params[:course_id].blank? @course = Course.find(params[:course_id]) - tip_exception(404, "") if @course.is_delete == 1 && !current_user.admin? + tip_exception(404, "") if @course.is_delete == 1 && !current_user.admin_or_business? rescue Exception => e tip_exception(e.message) end diff --git a/app/controllers/commons_controller.rb b/app/controllers/commons_controller.rb index bcb0fa45a..16e9dc2be 100644 --- a/app/controllers/commons_controller.rb +++ b/app/controllers/commons_controller.rb @@ -58,7 +58,7 @@ class CommonsController < ApplicationController 200 end else - current_user.admin? ? 200 : 403 + current_user.admin_or_business? ? 200 : 403 end return normal_status(code, "你没有权限操作!") if code == 403 end diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb index 599a4440c..da9f8240a 100644 --- a/app/controllers/courses_controller.rb +++ b/app/controllers/courses_controller.rb @@ -396,7 +396,7 @@ class CoursesController < ApplicationController def teachers @search_str = params[:search].present? ? params[:search].strip : "" - if @course.try(:id) != 1309 || current_user.admin? || current_user.try(:id) == 15582 + if @course.try(:id) != 1309 || current_user.admin_or_business? || current_user.try(:id) == 15582 @teacher_list = @course.course_members.joins(:user).where("course_members.role in (1, 2, 3) and LOWER(concat(users.lastname, users.firstname)) LIKE ?", "%#{@search_str}%") else @@ -441,7 +441,7 @@ class CoursesController < ApplicationController @applications = CourseMessage.unhandled_join_course_requests_by_course(@course). joins("join users on course_messages.course_message_id=users.id"). where("LOWER(concat(users.lastname, users.firstname)) LIKE ?", "%#{search_str}%") - if @course.try(:id) != 1309 || current_user.admin? || current_user.try(:id) == 15582 + if @course.try(:id) != 1309 || current_user.admin_or_business? || current_user.try(:id) == 15582 teacher_list = @course.course_members.where("course_members.role in (1, 2, 3)") else teacher_list = @course.course_members.where("(course_members.role in (1, 3) or (course_members.user_id = #{current_user.id} @@ -838,7 +838,7 @@ class CoursesController < ApplicationController # 已通过职业认证的教师复制课堂 def duplicate_course - return tip_exception("没有复制权限") unless current_user.admin? || current_user.is_teacher? || current_user.teacher_of_course?(@course) + return tip_exception("没有复制权限") unless current_user.admin_or_business? || current_user.is_teacher? || current_user.teacher_of_course?(@course) return tip_exception("教师职业认证未通过") unless current_user.pro_certification? new_course = @course.self_duplicate @@ -1280,7 +1280,7 @@ class CoursesController < ApplicationController end if @all_members.size == 0 - normal_status(-1,"课堂暂时没有学生") + normal_status(-1,"暂无学生数据") elsif params[:export].present? && params[:export] normal_status(0,"正在下载中") else @@ -1308,7 +1308,7 @@ class CoursesController < ApplicationController end if @all_members.length == 0 - normal_status(-1,"课堂暂时没有学生") + normal_status(-1,"暂无学生数据") elsif params[:export].present? && params[:export] normal_status(0,"正在下载中") else @@ -1404,7 +1404,7 @@ class CoursesController < ApplicationController # Use callbacks to share common setup or constraints between actions. def set_course @course = Course.find_by!(id: params[:id]) - tip_exception(404, "") if @course.is_delete == 1 && !current_user.admin? + tip_exception(404, "") if @course.is_delete == 1 && !current_user.admin_or_business? end # Never trust parameters from the scary internet, only allow the white list through. diff --git a/app/controllers/examination_banks_controller.rb b/app/controllers/examination_banks_controller.rb index ef545e06e..7c1f950f3 100644 --- a/app/controllers/examination_banks_controller.rb +++ b/app/controllers/examination_banks_controller.rb @@ -50,8 +50,11 @@ class ExaminationBanksController < ApplicationController end def destroy - @exam.destroy! - render_ok + ActiveRecord::Base.transaction do + ApplyAction.where(container_type: "ExaminationBank", container_id: @exam.id).destroy_all + @exam.destroy! + render_ok + end end def set_public diff --git a/app/controllers/exercise_bank_questions_controller.rb b/app/controllers/exercise_bank_questions_controller.rb index 1fd8ad874..46547ecb0 100644 --- a/app/controllers/exercise_bank_questions_controller.rb +++ b/app/controllers/exercise_bank_questions_controller.rb @@ -372,7 +372,7 @@ class ExerciseBankQuestionsController < ApplicationController private def bank_admin - tip_exception(403, "无权限") unless @exercise.user_id == current_user.id || current_user.admin? + tip_exception(403, "无权限") unless @exercise.user_id == current_user.id || current_user.admin_or_business? end def get_exercise diff --git a/app/controllers/exercise_banks_controller.rb b/app/controllers/exercise_banks_controller.rb index 9a35bfcdb..556b445ba 100644 --- a/app/controllers/exercise_banks_controller.rb +++ b/app/controllers/exercise_banks_controller.rb @@ -26,7 +26,7 @@ class ExerciseBanksController < ApplicationController search = params[:search] type = params[:type] # 超级管理员用户显示所有未隐藏的实训、非管理员显示所有已发布的实训(对本单位公开且未隐藏未关闭) - if current_user.admin? + if current_user.admin_or_business? @shixuns = Shixun.unhidden else none_shixun_ids = ShixunSchool.where("school_id != #{current_user.school_id}").pluck(:shixun_id) @@ -67,7 +67,7 @@ class ExerciseBanksController < ApplicationController end def bank_admin - tip_exception(403, "无权限") unless @bank.user_id == current_user.id || current_user.admin? + tip_exception(403, "无权限") unless @bank.user_id == current_user.id || current_user.admin_or_business? end #判断实训是否已选择 diff --git a/app/controllers/graduation_works_controller.rb b/app/controllers/graduation_works_controller.rb index 67f21e85c..fd47df172 100644 --- a/app/controllers/graduation_works_controller.rb +++ b/app/controllers/graduation_works_controller.rb @@ -382,6 +382,7 @@ class GraduationWorksController < ApplicationController tip_exception("成绩不能为空") if params[:score].blank? tip_exception("成绩不能小于零") if params[:score].to_f < 0 tip_exception("成绩不能大于100") if params[:score].to_f.round(1) > 100 + tip_exception("调分原因不能超过100个字符") if params[:comment].present? && params[:comment].length > 100 ActiveRecord::Base.transaction do begin # 分数不为空的历史评阅都置为失效 @@ -410,7 +411,7 @@ class GraduationWorksController < ApplicationController # 删除教师/教辅的评分记录 def delete_score score = @work.graduation_work_scores.where(id: params[:comment_id]).first - if score.present? && (score.is_invalid || score.score.nil?) && (score.user == current_user || current_user.admin?) + if score.present? && (score.is_invalid || score.score.nil?) && (score.user == current_user || current_user.admin_or_business?) begin score.destroy normal_status("删除成功") diff --git a/app/controllers/gtopic_banks_controller.rb b/app/controllers/gtopic_banks_controller.rb index f09a8554c..504868a6e 100644 --- a/app/controllers/gtopic_banks_controller.rb +++ b/app/controllers/gtopic_banks_controller.rb @@ -26,7 +26,7 @@ class GtopicBanksController < ApplicationController end def bank_admin - tip_exception(403, "无权限") unless @bank.user_id == current_user.id || current_user.admin? + tip_exception(403, "无权限") unless @bank.user_id == current_user.id || current_user.admin_or_business? end def gtopic_bank_params diff --git a/app/controllers/homework_banks_controller.rb b/app/controllers/homework_banks_controller.rb index 61bded033..00efbbd5f 100644 --- a/app/controllers/homework_banks_controller.rb +++ b/app/controllers/homework_banks_controller.rb @@ -47,7 +47,7 @@ class HomeworkBanksController < ApplicationController end def bank_admin - tip_exception(403, "无权限") unless @bank.user_id == current_user.id || current_user.admin? + tip_exception(403, "无权限") unless @bank.user_id == current_user.id || current_user.admin_or_business? end def bank_params diff --git a/app/controllers/homework_commons_controller.rb b/app/controllers/homework_commons_controller.rb index f9931c370..1d47fa293 100644 --- a/app/controllers/homework_commons_controller.rb +++ b/app/controllers/homework_commons_controller.rb @@ -145,7 +145,7 @@ class HomeworkCommonsController < ApplicationController @student_works = @homework.teacher_works(@member) @all_member_count = @student_works.size @score_open = true - elsif @user_course_identity > Course::STUDENT && @homework.work_public + elsif @user_course_identity > Course::STUDENT @student_works = student_works @score_open = false else @@ -757,7 +757,7 @@ class HomeworkCommonsController < ApplicationController search = params[:search] type = params[:type] # 超级管理员用户显示所有未隐藏的实训、非管理员显示所有已发布的实训(对本单位公开且未隐藏未关闭) - if current_user.admin? + if current_user.admin_or_business? @shixuns = Shixun.unhidden else none_shixun_ids = ShixunSchool.where("school_id != #{current_user.school_id}").pluck(:shixun_id) diff --git a/app/controllers/item_banks_controller.rb b/app/controllers/item_banks_controller.rb index 8b77e3e9a..221e754a4 100644 --- a/app/controllers/item_banks_controller.rb +++ b/app/controllers/item_banks_controller.rb @@ -31,8 +31,11 @@ class ItemBanksController < ApplicationController end def destroy - @item.destroy! - render_ok + ActiveRecord::Base.transaction do + ApplyAction.where(container_type: "ItemBank", container_id: @item.id).destroy_all + @item.destroy! + render_ok + end end def set_public diff --git a/app/controllers/memos_controller.rb b/app/controllers/memos_controller.rb index d2c386681..3c76972b8 100644 --- a/app/controllers/memos_controller.rb +++ b/app/controllers/memos_controller.rb @@ -144,6 +144,7 @@ class MemosController < ApplicationController def reply tip_exception("parent_id不能为空") if params[:parent_id].blank? tip_exception("content不能为空") if params[:content].blank? + tip_exception("content不能超过1000字符") if params[:content].length > 1000 ActiveRecord::Base.transaction do begin diff --git a/app/controllers/messages_controller.rb b/app/controllers/messages_controller.rb index 153598990..7b096f1ec 100644 --- a/app/controllers/messages_controller.rb +++ b/app/controllers/messages_controller.rb @@ -63,6 +63,7 @@ class MessagesController < ApplicationController def reply return normal_status(2, "回复内容不能为空") if params[:content].blank? + return normal_status(2, "回复内容不能超过1000字符") if params[:content].length > 1000 @reply = Message.create!(board: @message.board, root_id: @message.root_id || @message.id, author: current_user, parent: @message, message_detail_attributes: { @@ -126,7 +127,7 @@ class MessagesController < ApplicationController end def create - return normal_status(403, "您没有权限进行该操作") unless current_user.admin? || current_user.member_of_course?(@board.course) + return normal_status(403, "您没有权限进行该操作") unless current_user.admin_or_business? || current_user.member_of_course?(@board.course) begin @message = Message.new(message_params) diff --git a/app/controllers/poll_bank_questions_controller.rb b/app/controllers/poll_bank_questions_controller.rb index 71f302115..9e3e890b0 100644 --- a/app/controllers/poll_bank_questions_controller.rb +++ b/app/controllers/poll_bank_questions_controller.rb @@ -114,7 +114,7 @@ class PollBankQuestionsController < ApplicationController private def bank_admin - tip_exception(403, "无权限") unless @poll.user_id == current_user.id || current_user.admin? + tip_exception(403, "无权限") unless @poll.user_id == current_user.id || current_user.admin_or_business? end def get_poll diff --git a/app/controllers/question_banks_controller.rb b/app/controllers/question_banks_controller.rb index ddb0f3ce1..5183c7a96 100644 --- a/app/controllers/question_banks_controller.rb +++ b/app/controllers/question_banks_controller.rb @@ -10,7 +10,7 @@ class QuestionBanksController < ApplicationController def bank_list page = params[:page] || 1 limit = params[:limit] || 15 - @certification_teacher = current_user.is_certification_teacher || current_user.admin? + @certification_teacher = current_user.is_certification_teacher || current_user.admin_or_business? @objects = @object_type.classify.constantize.where(@object_filter) @objects = if params[:search] @@ -134,7 +134,7 @@ class QuestionBanksController < ApplicationController def destroy bank = current_bank - unless current_user.admin? || bank.user_id == current_user.id + unless current_user.admin_or_business? || bank.user_id == current_user.id render_forbidden return end @@ -165,7 +165,7 @@ class QuestionBanksController < ApplicationController def object_banks banks ||= @object_type.classify.constantize.where(@object_filter).where(id: params[:object_id]) - unless current_user.admin? + unless current_user.admin_or_business? banks = banks.where(user_id: current_user.id) end banks @@ -202,7 +202,7 @@ class QuestionBanksController < ApplicationController end def teacher_or_admin - tip_exception(403, "无权限操作") unless current_user.is_certification_teacher || current_user.admin? + tip_exception(403, "无权限操作") unless current_user.is_certification_teacher || current_user.admin_or_business? end def quote_homework_bank homework, course diff --git a/app/controllers/student_works_controller.rb b/app/controllers/student_works_controller.rb index 0b7874299..734229501 100644 --- a/app/controllers/student_works_controller.rb +++ b/app/controllers/student_works_controller.rb @@ -546,6 +546,7 @@ class StudentWorksController < ApplicationController tip_exception("成绩不能为空") if params[:score].blank? tip_exception("成绩不能小于零") if params[:score].to_f < 0 tip_exception("成绩不能大于100") if params[:score].to_f.round(1) > 100 + tip_exception("调分原因不能超过100个字符") if params[:comment].present? && params[:comment].length > 100 ActiveRecord::Base.transaction do begin # 分数不为空的历史评阅都置为失效 diff --git a/app/controllers/subjects_controller.rb b/app/controllers/subjects_controller.rb index f8a96af6b..8e23590ef 100644 --- a/app/controllers/subjects_controller.rb +++ b/app/controllers/subjects_controller.rb @@ -456,6 +456,25 @@ class SubjectsController < ApplicationController end end + def statistics_new + # data = Subjects::DataStatisticService.new(@subject) + # Rails.logger.info("study_count: #{data.study_count}") + # Rails.logger.info("course_study_count: #{ data.course_study_count}") + # Rails.logger.info("passed_count: #{data.passed_count}") + # Rails.logger.info("course_used_count: #{data.course_used_count}") + # Rails.logger.info("school_used_count: #{data.school_used_count}") + + # data_1 = Subjects::CourseUsedInfoService.call(@subject) + # Rails.logger.info("study_count: #{data_1}") + + # data_2 = Subjects::ShixunUsedInfoService.call(@subject) + # Rails.logger.info("study_count: #{data_2}") + + data_3 = Subjects::UserUsedInfoService.call(@subject) + Rails.logger.info("study_count: #{data_3}") + render_ok() + end + def shixun_report end diff --git a/app/controllers/task_banks_controller.rb b/app/controllers/task_banks_controller.rb index 2b1a400ef..768c4cb2a 100644 --- a/app/controllers/task_banks_controller.rb +++ b/app/controllers/task_banks_controller.rb @@ -29,7 +29,7 @@ class TaskBanksController < ApplicationController end def bank_admin - tip_exception(403, "无权限") unless @bank.user_id == current_user.id || current_user.admin? + tip_exception(403, "无权限") unless @bank.user_id == current_user.id || current_user.admin_or_business? end def gtask_bank_params diff --git a/app/controllers/users/question_banks_controller.rb b/app/controllers/users/question_banks_controller.rb index c5b837d0b..73d1d4dec 100644 --- a/app/controllers/users/question_banks_controller.rb +++ b/app/controllers/users/question_banks_controller.rb @@ -66,9 +66,9 @@ class Users::QuestionBanksController < Users::BaseController def check_user_permission! if params[:type] == 'publicly' - normal_status(-2,"未通过职业认证") unless User.current.admin? || User.current.certification_teacher? + normal_status(-2,"未通过职业认证") unless User.current.admin_or_business? || User.current.certification_teacher? else - render_forbidden unless User.current.admin? || User.current.is_teacher? + render_forbidden unless User.current.admin_or_business? || User.current.is_teacher? end end end \ No newline at end of file diff --git a/app/controllers/weapps/courses_controller.rb b/app/controllers/weapps/courses_controller.rb index cb3c195d6..d732416ba 100644 --- a/app/controllers/weapps/courses_controller.rb +++ b/app/controllers/weapps/courses_controller.rb @@ -39,7 +39,7 @@ class Weapps::CoursesController < Weapps::BaseController @page = (params[:page] || 1).to_i @limit = (params[:limit] || 20).to_i search = params[:search].present? ? params[:search].strip : "" - if @course.try(:id) != 1309 || current_user.admin? || current_user.try(:id) == 15582 + if @course.try(:id) != 1309 || current_user.admin_or_business? || current_user.try(:id) == 15582 @teacher_list = @course.course_members.joins(:user).where("course_members.role in (1, 2, 3)") else @teacher_list = @course.course_members.joins(:user).where("(course_members.role in (1, 3) or (course_members.user_id = #{current_user.id} @@ -203,6 +203,6 @@ class Weapps::CoursesController < Weapps::BaseController def set_course @course = Course.find_by!(id: params[:id]) - tip_exception(404, "") if @course.is_delete == 1 && !current_user.admin? + tip_exception(404, "") if @course.is_delete == 1 && !current_user.admin_or_business? end end \ No newline at end of file diff --git a/app/helpers/export_helper.rb b/app/helpers/export_helper.rb index 22adf3005..8b61ca2b6 100644 --- a/app/helpers/export_helper.rb +++ b/app/helpers/export_helper.rb @@ -47,9 +47,10 @@ module ExportHelper user_name = user.real_name user_mail = user.mail user_stu_id = user.student_id.present? ? (user.student_id.to_s + "\t") : "--" + user_grade = user.grade user_school = user.school_name user_course_group = u.course_group_name - user_info_array = [user_name,user_login,user_mail,user_stu_id,user_school,user_course_group] #用户的信息集合 + user_info_array = [user_name,user_login,user_mail,user_stu_id,user_grade,user_school,user_course_group] #用户的信息集合 user_work_scores = [] #学生总成绩 @@ -150,7 +151,7 @@ module ExportHelper course_user_score_title = "学生总成绩" score_title_cells = shixun_titles + common_titles + group_titles + task_titles + exercise_titles score_title_counts = [shixun_titles.count,common_titles.count,group_titles.count,task_titles.count,exercise_titles.count] - score_cell_head = %w(序号 真实姓名 登录名 邮箱 学号 学校 分班 个人总成绩) + score_title_cells + score_cell_head = %w(序号 真实姓名 登录名 邮箱 学号 金币 学校 分班 个人总成绩) + score_title_cells @course_user_scores = [course_user_score_title,score_cell_head,score_title_counts,total_user_score_array] #作业的全部集合 diff --git a/app/models/challenge.rb b/app/models/challenge.rb index 73079d82b..e9bef0c9d 100644 --- a/app/models/challenge.rb +++ b/app/models/challenge.rb @@ -28,6 +28,9 @@ class Challenge < ApplicationRecord scope :fields_for_list, -> { select([:id, :subject, :st, :score, :position, :shixun_id]) } + validates :task_pass, length: { maximum: 10000 } + + after_commit :create_diff_record def next_challenge diff --git a/app/models/challenge_answer.rb b/app/models/challenge_answer.rb index 0ce757d71..d3fd69cd0 100644 --- a/app/models/challenge_answer.rb +++ b/app/models/challenge_answer.rb @@ -3,6 +3,8 @@ class ChallengeAnswer < ApplicationRecord belongs_to :challenge has_many :game_answers, :dependent => :destroy + validates :contents, length: { maximum: 5000 } + def view_answer_time(user_id) game_answers.where(user_id: user_id).last&.view_time end diff --git a/app/models/challenge_choose.rb b/app/models/challenge_choose.rb index 2463d3317..2b8858f21 100644 --- a/app/models/challenge_choose.rb +++ b/app/models/challenge_choose.rb @@ -3,4 +3,7 @@ class ChallengeChoose < ApplicationRecord belongs_to :challenge, optional: true has_many :challenge_tags, :dependent => :destroy has_many :challenge_questions, dependent: :destroy + + validates :subject, length: { maximum: 1000 } + end diff --git a/app/models/challenge_question.rb b/app/models/challenge_question.rb index b0927aec0..959b033f9 100644 --- a/app/models/challenge_question.rb +++ b/app/models/challenge_question.rb @@ -1,3 +1,6 @@ class ChallengeQuestion < ApplicationRecord belongs_to :challenge_choose + + validates :option_name, length: { maximum: 500 } + end diff --git a/app/models/competition.rb b/app/models/competition.rb index 96fd14c1c..1d10e2032 100644 --- a/app/models/competition.rb +++ b/app/models/competition.rb @@ -33,6 +33,8 @@ class Competition < ApplicationRecord has_many :competition_prizes, dependent: :destroy has_many :competition_prize_users, dependent: :destroy + validates :introduction, length: { maximum: 500 } + before_save :set_laboratory after_create :create_competition_modules diff --git a/app/models/competition_module_md_content.rb b/app/models/competition_module_md_content.rb index 4a8dacf9e..936ded8ef 100644 --- a/app/models/competition_module_md_content.rb +++ b/app/models/competition_module_md_content.rb @@ -5,4 +5,6 @@ class CompetitionModuleMdContent < ApplicationRecord # validates :name, presence: true validates :content, presence: true + validates :content, length: { maximum: 10000 } + end \ No newline at end of file diff --git a/app/models/course.rb b/app/models/course.rb index 9100f8470..83d2bb56e 100644 --- a/app/models/course.rb +++ b/app/models/course.rb @@ -251,7 +251,7 @@ class Course < ApplicationRecord member = course_member(user.id) group_ids = if member.present? member.teacher_course_groups.size > 0 ? member.teacher_course_groups.pluck(:course_group_id) : course_groups.pluck(:id) - elsif user.admin? + elsif user.admin_or_business? course_groups.pluck(:id) else [] diff --git a/app/models/discuss.rb b/app/models/discuss.rb index a236a2bbc..f35ca4751 100644 --- a/app/models/discuss.rb +++ b/app/models/discuss.rb @@ -13,6 +13,8 @@ class Discuss < ApplicationRecord belongs_to :challenge, optional: true validate :validate_sensitive_string + validates :content, length: { maximum: 1000 } + after_create :send_tiding scope :children, -> (discuss_id){ where(parent_id: discuss_id).includes(:user).reorder(created_at: :asc) } diff --git a/app/models/exercise.rb b/app/models/exercise.rb index 9bc9bd1fb..1fd84d1f7 100644 --- a/app/models/exercise.rb +++ b/app/models/exercise.rb @@ -20,6 +20,7 @@ class Exercise < ApplicationRecord where("exercise_name LIKE ?", "%#{keywords}%") unless keywords.blank?} validates :exercise_name, length: { maximum: 60, too_long: "60 characters is the maximum allowed" } + validates :exercise_description, length: { maximum: 100 } after_create :create_exercise_list diff --git a/app/models/exercise_answer.rb b/app/models/exercise_answer.rb index 11558f937..00c08dd77 100644 --- a/app/models/exercise_answer.rb +++ b/app/models/exercise_answer.rb @@ -11,4 +11,6 @@ class ExerciseAnswer < ApplicationRecord scope :exercise_answer_is_right, -> {where("score > ?",0.0)} #判断答案是否正确,根据分数总和大于0 scope :score_reviewed, lambda {where("score >= ?",0.0)} #是否评分,用于判断主观题的 + validates :answer_text, length: { maximum: 5000 } + end \ No newline at end of file diff --git a/app/models/exercise_answer_comment.rb b/app/models/exercise_answer_comment.rb index 4279ba445..110efc737 100644 --- a/app/models/exercise_answer_comment.rb +++ b/app/models/exercise_answer_comment.rb @@ -6,4 +6,6 @@ class ExerciseAnswerComment < ApplicationRecord belongs_to :exercise_answer, optional: true scope :search_answer_comments, lambda {|name,ids| where("#{name}":ids)} + + validates :comment, length: { maximum: 100 } end diff --git a/app/models/exercise_bank_choice.rb b/app/models/exercise_bank_choice.rb index be29ca786..8f1dc9028 100644 --- a/app/models/exercise_bank_choice.rb +++ b/app/models/exercise_bank_choice.rb @@ -4,4 +4,7 @@ class ExerciseBankChoice < ApplicationRecord scope :find_choice_custom, lambda {|k,v| where("#{k} = ?",v)} #根据传入的参数查找问题 scope :left_choice_choose, lambda {|k,v| where("#{k} > ?",v)} #根据传入的参数查找问题 + + validates :choice_text, length: { maximum: 500 } + end \ No newline at end of file diff --git a/app/models/exercise_bank_question.rb b/app/models/exercise_bank_question.rb index fdd343f5a..fbb6da88f 100644 --- a/app/models/exercise_bank_question.rb +++ b/app/models/exercise_bank_question.rb @@ -11,6 +11,8 @@ class ExerciseBankQuestion < ApplicationRecord scope :left_question_choose, lambda {|k,v| where("#{k} > ?",v)} #根据传入的参数查找问题 scope :find_objective_questions, -> {where("question_type != ?",4)} #查找全部客观题 + validates :question_title, length: { maximum: 1000 } + def question_type_name case self.question_type when 0 diff --git a/app/models/exercise_bank_standard_answer.rb b/app/models/exercise_bank_standard_answer.rb index 2535473b0..9bfbd67aa 100644 --- a/app/models/exercise_bank_standard_answer.rb +++ b/app/models/exercise_bank_standard_answer.rb @@ -3,4 +3,7 @@ class ExerciseBankStandardAnswer < ApplicationRecord belongs_to :exercise_bank_choice #attr_accessible :answer_text scope :standard_by_ids, lambda { |s| where(exercise_bank_choice_id: s) } + + validates :answer_text, length: { maximum: 5000 } + end \ No newline at end of file diff --git a/app/models/exercise_choice.rb b/app/models/exercise_choice.rb index 72dc30c9d..54b844ad9 100644 --- a/app/models/exercise_choice.rb +++ b/app/models/exercise_choice.rb @@ -7,4 +7,6 @@ class ExerciseChoice < ApplicationRecord scope :find_choice_custom, lambda {|k,v| where("#{k} = ?",v)} #根据传入的参数查找问题 scope :left_choice_choose, lambda {|k,v| where("#{k} > ?",v)} #根据传入的参数查找问题 + validates :choice_text, length: { maximum: 500 } + end \ No newline at end of file diff --git a/app/models/exercise_question.rb b/app/models/exercise_question.rb index 2c9b281c3..3f1a49625 100644 --- a/app/models/exercise_question.rb +++ b/app/models/exercise_question.rb @@ -16,6 +16,8 @@ class ExerciseQuestion < ApplicationRecord scope :left_question_choose, lambda {|k,v| where("#{k} > ?",v)} #根据传入的参数查找问题 scope :find_objective_questions, -> {where("question_type != ?",4)} #查找全部客观题 + validates :question_title, length: { maximum: 1000 } + def question_type_name case self.question_type diff --git a/app/models/exercise_standard_answer.rb b/app/models/exercise_standard_answer.rb index b4c71bd76..ccf5c1203 100644 --- a/app/models/exercise_standard_answer.rb +++ b/app/models/exercise_standard_answer.rb @@ -6,5 +6,5 @@ class ExerciseStandardAnswer < ApplicationRecord scope :find_standard_answer_custom, lambda {|k,v| where("#{k} = ?",v)} #根据传入的参数查找问题 scope :standard_by_ids, lambda { |s| where(exercise_choice_id: s) } - + validates :answer_text, length: { maximum: 5000 } end diff --git a/app/models/graduation_work.rb b/app/models/graduation_work.rb index 96dce0c49..7fb0ecc24 100644 --- a/app/models/graduation_work.rb +++ b/app/models/graduation_work.rb @@ -55,7 +55,7 @@ class GraduationWork < ApplicationRecord end def delete_atta atta - last_score = graduation_work_scores.where.not(score: nil).last + last_score = graduation_work_scores.last (atta.author_id == User.current.id) && (last_score.blank? || last_score.try(:created_at) < atta.created_on) end diff --git a/app/models/graduation_work_score.rb b/app/models/graduation_work_score.rb index eaf59ffbd..853b996a1 100644 --- a/app/models/graduation_work_score.rb +++ b/app/models/graduation_work_score.rb @@ -5,5 +5,5 @@ class GraduationWorkScore < ApplicationRecord belongs_to :graduation_task has_many :attachments, as: :container, dependent: :destroy - validates :comment, length: { maximum: 2000 } + validates :comment, length: { maximum: 1000 } end diff --git a/app/models/gtask_bank.rb b/app/models/gtask_bank.rb index 55f83ef10..f9d38d33f 100644 --- a/app/models/gtask_bank.rb +++ b/app/models/gtask_bank.rb @@ -9,4 +9,6 @@ class GtaskBank < ApplicationRecord scope :myself, ->(user_id) { where(user_id: user_id)} scope :is_public, -> { where(:is_public => true) } + validates :name, length: { maximum: 60 } + validates :description, length: { maximum: 5000 } end diff --git a/app/models/gtopic_bank.rb b/app/models/gtopic_bank.rb index 609219711..fe9f184eb 100644 --- a/app/models/gtopic_bank.rb +++ b/app/models/gtopic_bank.rb @@ -7,4 +7,11 @@ class GtopicBank < ApplicationRecord has_many :graduation_topics, dependent: :nullify scope :myself, ->(user_id) { where(user_id: user_id)} + + + # 课题名称和描述字段长度限制 + validates :name, length: { maximum: 60, + too_long: "60 characters is the maximum allowed" } + validates :description, length: { maximum: 5000, + too_long: "5000 characters is the maximum allowed" } end diff --git a/app/models/hack.rb b/app/models/hack.rb index 79c7a0f82..e89212cc3 100644 --- a/app/models/hack.rb +++ b/app/models/hack.rb @@ -3,6 +3,7 @@ class Hack < ApplicationRecord # diffcult: 难度 1:简单;2:中等; 3:困难 # 编程题 validates_length_of :name, maximum: 60 + validates_length_of :description, maximum: 5000 validates :description, presence: { message: "描述不能为空" } validates :name, presence: { message: "名称不能为空" } # 测试集 diff --git a/app/models/hack_set.rb b/app/models/hack_set.rb index 9e2186fb5..4dafd94a7 100644 --- a/app/models/hack_set.rb +++ b/app/models/hack_set.rb @@ -1,4 +1,6 @@ class HackSet < ApplicationRecord + validates_length_of :input, maximum: 500 + validates_length_of :output, maximum: 500 validates :input, presence: { message: "测试集输入不能为空" } validates :output, presence: { message: "测试集输出不能为空" } validates_uniqueness_of :input, scope: [:hack_id, :input], message: "多个测试集的输入不能相同" diff --git a/app/models/homework_bank.rb b/app/models/homework_bank.rb index 7c9de0cda..d6db7bfab 100644 --- a/app/models/homework_bank.rb +++ b/app/models/homework_bank.rb @@ -10,4 +10,7 @@ class HomeworkBank < ApplicationRecord scope :is_public, -> { where(is_public: true)} scope :myself, ->(user_id) { where(user_id: user_id)} + validates :name, length: { maximum: 60 } + validates :description, length: { maximum: 15000 } + validates :reference_answer, length: { maximum: 15000 } end diff --git a/app/models/journals_for_message.rb b/app/models/journals_for_message.rb index 4300ae9cc..66ab98c9b 100644 --- a/app/models/journals_for_message.rb +++ b/app/models/journals_for_message.rb @@ -24,7 +24,9 @@ class JournalsForMessage < ApplicationRecord # "m_reply_count", # 留言的回复数量 # "m_reply_id" , # 回复某留言的留言id(a留言回复了b留言,这是b留言的id) # "is_comprehensive_evaluation", # 1 教师评论、2 匿评、3 留言 - # "hidden", 隐藏 + # "hidden", 隐藏、 + + validates :notes, length: { maximum: 1000 } after_create :send_tiding diff --git a/app/models/library.rb b/app/models/library.rb index 743959d30..982db732b 100644 --- a/app/models/library.rb +++ b/app/models/library.rb @@ -13,6 +13,7 @@ class Library < ApplicationRecord has_one :praise_tread_cache, foreign_key: :object_id has_many :praise_treads, as: :praise_tread_object, dependent: :destroy + validates :content, length: { maximum: 5000 } validates :uuid, presence: true, uniqueness: true diff --git a/app/models/memo.rb b/app/models/memo.rb index d79081350..9140fb5db 100644 --- a/app/models/memo.rb +++ b/app/models/memo.rb @@ -27,6 +27,8 @@ class Memo < ApplicationRecord scope :hot, -> { order("all_replies_count desc, updated_at desc") } scope :posts, -> { where(root_id: nil, forum_id: [3, 5]) } + validates :content, length: { maximum: 10000 } + after_create :send_tiding # 帖子的回复 @@ -39,6 +41,13 @@ class Memo < ApplicationRecord Memo.where(parent_id: id).includes(:author).reorder("created_at asc") end + # 主贴的名称 + def main_subject + memo = Memo.find_by(root_id: id) + Rails.logger.info("###############memo: #{memo&.subject}") + memo ? memo.subject : subject + end + private def send_tiding diff --git a/app/models/message.rb b/app/models/message.rb index 7588ddc2a..7620ef11d 100644 --- a/app/models/message.rb +++ b/app/models/message.rb @@ -39,6 +39,12 @@ class Message < ApplicationRecord message_detail.update_attributes(content: content) end + # 主贴的名称 + def main_subject + Rails.logger.info("##########parent: #{parent&.subject}") + parent.present? ? parent.subject : subject + end + def copy_attachments_to_new_message(new_message, user) attachments.each do |attach| new_message.attachments << Attachment.new(attach.attributes.except("id").merge( diff --git a/app/models/message_detail.rb b/app/models/message_detail.rb index 945d875f5..0d7aaa1c1 100644 --- a/app/models/message_detail.rb +++ b/app/models/message_detail.rb @@ -1,4 +1,5 @@ class MessageDetail < ApplicationRecord belongs_to :message, :touch => true + validates :content, length: { maximum: 5000 } end diff --git a/app/models/myshixun.rb b/app/models/myshixun.rb index 1a89c755e..8d2012381 100644 --- a/app/models/myshixun.rb +++ b/app/models/myshixun.rb @@ -5,6 +5,7 @@ class Myshixun < ApplicationRecord has_one :shixun_modify, :dependent => :destroy belongs_to :user + belongs_to :user_extension, foreign_key: :user_id belongs_to :shixun, counter_cache: true has_one :last_executable_task, -> { where(status: [0, 1]).reorder(created_at: :asc) }, class_name: 'Game' @@ -21,7 +22,7 @@ class Myshixun < ApplicationRecord end def output_times - games.pluck(:evaluate_count).sum.to_i + games.map(&:evaluate_count).sum.to_i end def repo_path diff --git a/app/models/poll.rb b/app/models/poll.rb index 365e46008..1c38d2426 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -25,6 +25,7 @@ class Poll < ApplicationRecord where("polls_name LIKE ?", "%#{keywords}%") unless keywords.blank?} validates :polls_name, length: { maximum: 60, too_long: "60 characters is the maximum allowed" } + validates :polls_description, length: { maximum: 100 } after_create :create_polls_list diff --git a/app/models/poll_answer.rb b/app/models/poll_answer.rb index 8e2421328..c7fa7e75c 100644 --- a/app/models/poll_answer.rb +++ b/app/models/poll_answer.rb @@ -8,4 +8,6 @@ class PollAnswer < ApplicationRecord scope :find_answer_by_custom, lambda {|k,v| where("#{k}":v)} #根据传入的参数查找问题 scope :left_answer_choose, lambda {|k,v| where("#{k} > ?",v)} #根据传入的参数查找问题 + validates :answer_text, length: { maximum: 500 } + end \ No newline at end of file diff --git a/app/models/poll_question.rb b/app/models/poll_question.rb index a0854aa48..dd7f3f95f 100644 --- a/app/models/poll_question.rb +++ b/app/models/poll_question.rb @@ -9,6 +9,8 @@ class PollQuestion < ApplicationRecord scope :ques_necessary, -> {where("is_necessary = ?",1)} scope :insert_question, lambda {|k| where("question_number > ?",k)} + validates :question_title, length: { maximum: 1000 } + def question_type_name case self.question_type when 1 diff --git a/app/models/poll_vote.rb b/app/models/poll_vote.rb index 67b832890..2e70f1342 100644 --- a/app/models/poll_vote.rb +++ b/app/models/poll_vote.rb @@ -8,4 +8,7 @@ class PollVote < ApplicationRecord scope :find_current_vote,lambda {|k,v| where("#{k}": v)} scope :find_vote_text,-> {where("vote_text IS NOT NULL")} + + validates :vote_text, length: { maximum: 5000 } + end \ No newline at end of file diff --git a/app/models/shixun.rb b/app/models/shixun.rb index d8a41ba6a..c16c4df4e 100644 --- a/app/models/shixun.rb +++ b/app/models/shixun.rb @@ -30,6 +30,8 @@ class Shixun < ApplicationRecord has_one :first_tag_repertoire, through: :first_shixun_tag_repertoire, source: :tag_repertoire has_many :homework_commons_shixuns, class_name: 'HomeworkCommonsShixun' + has_many :homework_commons, through: :homework_commons_shixuns + has_many :fork_shixuns, foreign_key: "fork_from", class_name: 'Shixun' #实训的关卡 @@ -59,6 +61,9 @@ class Shixun < ApplicationRecord # Jupyter数据集,附件 has_many :data_sets, ->{where(attachtype: 2)}, class_name: 'Attachment', as: :container, dependent: :destroy + # 试卷的实训题 + has_many :exercise_questions + scope :search_by_name, ->(keyword) { where("name like ? or description like ? ", "%#{keyword}%", "%#{keyword}%") } diff --git a/app/models/shixun_info.rb b/app/models/shixun_info.rb index 7f7aa364e..e3a8d334b 100644 --- a/app/models/shixun_info.rb +++ b/app/models/shixun_info.rb @@ -4,6 +4,8 @@ class ShixunInfo < ApplicationRecord validates_length_of :fork_reason, maximum: 60 after_commit :create_diff_record + validates :description, length: { maximum: 5000 } + private def create_diff_record diff --git a/app/models/shixun_work_comment.rb b/app/models/shixun_work_comment.rb index 7a67238ab..1d23718d3 100644 --- a/app/models/shixun_work_comment.rb +++ b/app/models/shixun_work_comment.rb @@ -2,4 +2,6 @@ class ShixunWorkComment < ApplicationRecord belongs_to :student_work belongs_to :user belongs_to :challenge, optional: true + validates :comment, length: { maximum: 500 } + validates :hidden_comment, length: { maximum: 500 } end diff --git a/app/models/stage.rb b/app/models/stage.rb index db7b5c0b3..84873b01f 100644 --- a/app/models/stage.rb +++ b/app/models/stage.rb @@ -7,5 +7,5 @@ class Stage < ApplicationRecord has_many :shixuns, :through => :stage_shixuns validates :name, length: { maximum: 60 } - validates :description, length: { maximum: 300 } + validates :description, length: { maximum: 1000 } end diff --git a/app/models/student_work.rb b/app/models/student_work.rb index 4da23a30f..473efa756 100644 --- a/app/models/student_work.rb +++ b/app/models/student_work.rb @@ -105,7 +105,7 @@ class StudentWork < ApplicationRecord end def delete_atta atta - last_score = student_works_scores.where.not(score: nil).last + last_score = student_works_scores.last (atta.author_id == User.current.id) && (last_score.blank? || last_score.try(:created_at) < atta.created_on) end diff --git a/app/models/student_works_score.rb b/app/models/student_works_score.rb index 299b61596..f9f4f4220 100644 --- a/app/models/student_works_score.rb +++ b/app/models/student_works_score.rb @@ -7,7 +7,7 @@ class StudentWorksScore < ApplicationRecord has_many :tidings, as: :container, dependent: :destroy has_many :attachments, as: :container, dependent: :destroy - validates :comment, length: { maximum: 2000 } + validates :comment, length: { maximum: 1000 } scope :shixun_comment, lambda { where(is_ultimate: 0) } @@ -17,7 +17,7 @@ class StudentWorksScore < ApplicationRecord end def allow_delete current_user - (self.is_invalid || self.score.nil?) && (current_user == self.user || current_user.admin?) + (self.is_invalid || self.score.nil?) && (current_user == self.user || current_user.admin_or_business?) end # 匿评分 diff --git a/app/models/subject.rb b/app/models/subject.rb index 28c45e4ba..df9271e5f 100644 --- a/app/models/subject.rb +++ b/app/models/subject.rb @@ -25,6 +25,11 @@ class Subject < ApplicationRecord has_many :courses, -> { where("is_delete = 0").order("courses.created_at ASC") } has_many :laboratory_subjects, dependent: :destroy + # 学习统计 + has_one :subject_record, dependent: :destroy + has_many :subject_course_records, dependent: :destroy + has_many :subject_shixun_infos, dependent: :destroy + has_many :subject_user_infos, dependent: :destroy validates :name, length: { maximum: 60 } validates :description, length: { maximum: 8000 } diff --git a/app/models/subject_course_record.rb b/app/models/subject_course_record.rb new file mode 100644 index 000000000..2240c0eb3 --- /dev/null +++ b/app/models/subject_course_record.rb @@ -0,0 +1,3 @@ +class SubjectCourseRecord < ApplicationRecord + belongs_to :subject +end diff --git a/app/models/subject_record.rb b/app/models/subject_record.rb new file mode 100644 index 000000000..cdd5b15e4 --- /dev/null +++ b/app/models/subject_record.rb @@ -0,0 +1,3 @@ +class SubjectRecord < ApplicationRecord + belongs_to :subject +end diff --git a/app/models/subject_shixun_info.rb b/app/models/subject_shixun_info.rb new file mode 100644 index 000000000..6ce4ccb50 --- /dev/null +++ b/app/models/subject_shixun_info.rb @@ -0,0 +1,3 @@ +class SubjectShixunInfo < ApplicationRecord + belongs_to :subject +end diff --git a/app/models/subject_user_info.rb b/app/models/subject_user_info.rb new file mode 100644 index 000000000..4435a1aea --- /dev/null +++ b/app/models/subject_user_info.rb @@ -0,0 +1,3 @@ +class SubjectUserInfo < ApplicationRecord + belongs_to :subject +end diff --git a/app/models/test_set.rb b/app/models/test_set.rb index 7772a3a00..1fae89afa 100644 --- a/app/models/test_set.rb +++ b/app/models/test_set.rb @@ -1,3 +1,7 @@ class TestSet < ApplicationRecord # match_rule: 匹配规则: full: 完全匹配, last: 末尾匹配 + # + validates :input, length: { maximum: 5000 } + validates :input, length: { maximum: 5000 } + end diff --git a/app/models/user.rb b/app/models/user.rb index f1b8c3d23..6022cc8eb 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -43,6 +43,7 @@ class User < ApplicationRecord has_many :shixun_members, :dependent => :destroy has_many :shixuns, :through => :shixun_members has_many :myshixuns, :dependent => :destroy + has_many :games, :dependent => :destroy has_many :study_shixuns, through: :myshixuns, source: :shixun # 已学习的实训 has_many :course_messages has_many :courses, foreign_key: 'tea_id', dependent: :destroy diff --git a/app/services/discusses_service.rb b/app/services/discusses_service.rb index 81ac1eb33..ae6a538ca 100644 --- a/app/services/discusses_service.rb +++ b/app/services/discusses_service.rb @@ -58,7 +58,7 @@ class DiscussesService praise_count: 0, position: params[:position], challenge_id: params[:challenge_id], hidden: !current_user.admin? ) # 发送手机通知 - Educoder::Sms.send(mobile:'18173242757', send_type:'discuss', name:'管理员') + # Educoder::Sms.send(mobile:'18173242757', send_type:'discuss', name:'管理员') rescue Exception => e raise(e.message) end diff --git a/app/services/subjects/course_used_info_service.rb b/app/services/subjects/course_used_info_service.rb new file mode 100644 index 000000000..2561f3aa4 --- /dev/null +++ b/app/services/subjects/course_used_info_service.rb @@ -0,0 +1,40 @@ +class Subjects::CourseUsedInfoService < ApplicationService + attr_reader :subject + def initialize(subject) + @subject = subject + @shixun_ids = subject.shixuns.pluck(:id) + end + + def call + return if subject.blank? + homework_commons = + HomeworkCommon.joins(:homework_commons_shixun) + .where(homework_type: %i[practice]) + .where(homework_commons_shixuns: {shixun_id: @shixun_ids}) + course_ids = homework_commons.pluck(:course_id) + homework_common_ids = homework_commons.pluck("homework_commons.id") + schools = School.joins(:courses).where(courses: {id: course_ids}).group("schools.id").select("schools.*, count(courses.id) course_count") + + # name:将该课程使用到课堂的单位 + # course_count: 将该课程使用到课堂的数量 + # student_count: 课堂的学生总数(去掉重复) + # choice_shixun_num: 选用该课程实训的个数(去重) + # choice_shixun_frequency: 选用该课程实训的次数 + course_info = [] + schools.map do |school| + name = school.name + course_count = school.course_count + student_count = school.courses.joins(:course_members).where(course_members: {role: 4, course_id: course_ids}).size + shixun_ids = school.courses.joins(homework_commons: :homework_commons_shixun) + .where(homework_commons: {id: homework_common_ids}) + .pluck("homework_commons_shixuns.shixun_id") + choice_shixun_frequency = shixun_ids.size + choice_shixun_num = shixun_ids.uniq.size + course_info << {school_id: school.id, school_name: name, course_count: course_count, student_count: student_count, + choice_shixun_num: choice_shixun_num, choice_shixun_frequency: choice_shixun_frequency} + end + course_info + end + +end + diff --git a/app/services/subjects/data_statistic_service.rb b/app/services/subjects/data_statistic_service.rb new file mode 100644 index 000000000..32b636400 --- /dev/null +++ b/app/services/subjects/data_statistic_service.rb @@ -0,0 +1,72 @@ +class Subjects::DataStatisticService < ApplicationService + attr_reader :subject + def initialize(subject) + @subject = subject + @shixuns = subject.shixuns + @shixun_ids = @shixuns.pluck(:id) + end + + # 学习总人数: + # 文案解释:学习该课程的全部人数(学习总人数=课堂学习人数+自主学习人数) + # 开发备注:只要点击该课程的任何一个实训(生成了tpi),都算一个学习人数;(去重,一个人数计算1次) + def study_count + @shixuns.joins(:myshixuns).pluck("myshixuns.user_id").uniq.size + end + + # 课堂学习人数: + # 文案解释:通过课堂学习该课程的人数 + # 开发备注:只要通过课堂进入,并点击了实训(生成了tpi),则算一个可以学习人数;(去重,一个人数计算1次) + def course_study_count + # 实训作业 + sw_user_ids = StudentWork.where.not(myshixun_id: 0).joins(homework_common: :homework_commons_shixun) + .where(homework_commons_shixuns: {shixun_id: @shixun_ids}).pluck("student_works.user_id") + # 试卷的实训题 + esa_user_ids = ExerciseShixunAnswer.joins(exercise_shixun_challenge: :shixun) + .where(shixuns: {id: @shixun_ids}).pluck("exercise_shixun_answers.user_id") + (sw_user_ids + esa_user_ids).uniq.size + end + + # 自主学习人数: + # 文案解释:通过自主学习该课程的人数 + # 开发备注:非课程进入,生成了实训的tpi(去重。一个人数计算1次 + def initiative_study + study_count - course_study_count + end + + # 通关总人数: + # 文案解释: + # 通关该课程所有实训的人数(去重。一个人数计算1次) + def passed_count + @shixuns.includes(:myshixuns).where(myshixuns: {status: 1}).pluck("myshixuns.user_id").uniq.size + end + + # 使用课堂数: + # 文案解释:使用该课程的课堂数量 + # 开发备注:课堂加入该课程的实训到自己课堂,则算一个使用课堂数。(去重,一个课堂计算1次) + def course_used_count + hc_course_ids = + HomeworkCommon.joins(:homework_commons_shixun) + .where(homework_type: %i[practice]) + .where(homework_commons_shixuns: {shixun_id: @shixun_ids}).pluck("homework_commons.course_id").uniq + ex_course_ids = + Exercise.joins(:exercise_questions) + .where(exercise_questions: {question_type: 5, shixun_id: @shixun_ids}).pluck("exercises.course_id").uniq + + (hc_course_ids + ex_course_ids).uniq.size + end + + # 使用单位数: + # 文案解释:使用该课程的单位数量(包括自主学习者所在单位) + # 开发备注:凡事该单位有使用该课程的实训(自主学习+课堂使用)都算;(去重,一个单位计算一次) + def school_used_count + school_ids.size + end + + + private + def school_ids + @shixuns.joins(myshixuns: :user_extension).pluck("user_extensions.school_id").uniq + end + + +end diff --git a/app/services/subjects/shixun_used_info_service.rb b/app/services/subjects/shixun_used_info_service.rb new file mode 100644 index 000000000..32309fd59 --- /dev/null +++ b/app/services/subjects/shixun_used_info_service.rb @@ -0,0 +1,30 @@ +class Subjects::ShixunUsedInfoService < ApplicationService + attr_reader :subject, :stages + def initialize(subject) + @subject = subject + @stages = subject.stages.includes(shixuns: [myshixuns: :games, homework_commons_shixuns: [homework_common: :course]]) + end + + def call + shixun_infos = [] + stages.each do |stage| + position = stage.position + stage.shixuns.each_with_index do |shixun, index| + stage = "#{position}-#{index+1}" + name = shixun.name + challenge_count = shixun.challenges_count + course_count = shixun.homework_commons.map{|hc| hc.course_id}.uniq.size + school_count = shixun.homework_commons.map{|hc| hc.course&.school_id}.uniq.size + used_count = shixun.myshixuns_count + passed_count = shixun.myshixuns.select{|m| m.status == 1}.size + evaluate_count = shixun.myshixuns.map{|m| m.output_times }.sum + passed_ave_time = passed_count > 0 ? shixun.myshixuns.map{|m| m.total_cost_time}.sum : 0 + shixun_infos << {stage: stage, name: name, challenge_count: challenge_count, course_count: course_count, + school_count: school_count, used_count: used_count, passed_count: passed_count, + evaluate_count: evaluate_count, passed_ave_time: passed_ave_time, shixun_id: shixun.id} + end + end + shixun_infos + end + +end diff --git a/app/services/subjects/user_used_info_service.rb b/app/services/subjects/user_used_info_service.rb new file mode 100644 index 000000000..3b1b969f0 --- /dev/null +++ b/app/services/subjects/user_used_info_service.rb @@ -0,0 +1,28 @@ +class Subjects::UserUsedInfoService < ApplicationService + attr_reader :subject, :shixun_ids + + def initialize(subject) + @subject = subject + @shixun_ids = subject.shixuns.pluck(:id) + + end + + def call + users_info = [] + users = User.includes(myshixuns: :games).where(myshixuns: {shixun_id: shixun_ids}, games: {status: 2}) + users.each do |user| + myshixuns = user.myshixuns.select{|m| shixun_ids.include?(m.shixun_id)} + name = "#{user.lastname}#{user.firstname}" + passed_myshixun_count = myshixuns.select{|m| m.status == 1}.size + passed_games_count = myshixuns.map{|m| m.games.select{|g| g.status == 2}.size }.size + code_line_count = 0 + evaluate_count = myshixuns.map{|m| m.output_times }.sum + cost_time = myshixuns.map{|m|m.total_cost_time }.sum + users_info << {user_id: user.id, name: name, passed_myshixun_count: passed_myshixun_count, + passed_games_count: passed_games_count, code_line_count: code_line_count, + evaluate_count: evaluate_count, cost_time: cost_time} + end + users_info + end + +end diff --git a/app/views/admins/shixuns/index.html.erb b/app/views/admins/shixuns/index.html.erb index 4348f0f45..7c6264928 100644 --- a/app/views/admins/shixuns/index.html.erb +++ b/app/views/admins/shixuns/index.html.erb @@ -23,20 +23,21 @@ <%= select_tag(:search_type, options_for_select(auto_trial_options), class: 'form-control') %> <%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: '输入关键字搜索') %> -
- 导出 -
-
+
<% fork_status_options = [['全部', ''], ["全部fork实训", "Fork"], ["实训内容升级", 'Shixun'], ["课堂教学使用", 'Course'],["实践课程使用",'Subject'],["其他原因",'Other']] %> <%= select_tag(:fork_status, options_for_select(fork_status_options), class: 'form-control') %>
- <%= submit_tag('搜索', class: 'btn btn-primary ml-3','data-disable-with': '搜索中...') %> - <%= link_to "清除", admins_shixuns_path,class: "btn btn-default",id:"shixuns-clear-search",'data-disable-with': '清除中...' %> +
+ <%= submit_tag('搜索', class: 'btn btn-primary ml-3','data-disable-with': '搜索中...') %> + <%= link_to "清除", admins_shixuns_path,class: "btn btn-default",id:"shixuns-clear-search",'data-disable-with': '清除中...' %> +
+ + 导出
<% end %> diff --git a/app/views/exercise_banks/show.json.jbuilder b/app/views/exercise_banks/show.json.jbuilder index 802e863cb..4c01f1fd1 100644 --- a/app/views/exercise_banks/show.json.jbuilder +++ b/app/views/exercise_banks/show.json.jbuilder @@ -2,7 +2,7 @@ if @bank.container_type == "Exercise" json.exercise do json.extract! @bank, :id, :name, :description, :is_public end - json.authorize @bank.user_id == current_user.id || current_user.admin? + json.authorize @bank.user_id == current_user.id || current_user.admin_or_business? json.partial! "exercises/exercise_scores" @@ -21,7 +21,7 @@ else json.poll do json.extract! @bank, :id, :name, :description, :is_public end - json.authorize @bank.user_id == current_user.id || current_user.admin? + json.authorize @bank.user_id == current_user.id || current_user.admin_or_business? json.question_types do json.q_counts @poll_questions_count diff --git a/app/views/graduation_tasks/show.json.jbuilder b/app/views/graduation_tasks/show.json.jbuilder index 814cc62ce..8b2a553b1 100644 --- a/app/views/graduation_tasks/show.json.jbuilder +++ b/app/views/graduation_tasks/show.json.jbuilder @@ -1,7 +1,7 @@ json.partial! "public_navigation", locals: {graduation: @task, course: @course} json.description @task.description json.user_id @task.user_id -json.authorize @task.user_id == current_user.id || current_user.admin? +json.authorize @task.user_id == current_user.id || current_user.admin_or_business? # 附件 json.attachments @attachments do |attachment| json.partial! "attachments/attachment_simple", locals: {attachment: attachment} diff --git a/app/views/graduation_works/comment_list.json.jbuilder b/app/views/graduation_works/comment_list.json.jbuilder index 77898c91d..5f59a8bcf 100644 --- a/app/views/graduation_works/comment_list.json.jbuilder +++ b/app/views/graduation_works/comment_list.json.jbuilder @@ -15,7 +15,7 @@ json.comment_scores @comment_scores do |score| json.score score.score json.content score.comment json.is_invalid score.is_invalid - json.delete (@current_user == score.user || @current_user.admin?) && (score.is_invalid || score.score.nil?) + json.delete (@current_user == score.user || @current_user.admin_or_business?) && (score.is_invalid || score.score.nil?) json.attachments score.attachments do |atta| json.partial! "attachments/attachment_simple", locals: {attachment: atta, delete: false} end diff --git a/app/views/gtopic_banks/show.json.jbuilder b/app/views/gtopic_banks/show.json.jbuilder index 7ab86674d..0d32b17a3 100644 --- a/app/views/gtopic_banks/show.json.jbuilder +++ b/app/views/gtopic_banks/show.json.jbuilder @@ -1,6 +1,6 @@ json.(@bank, :id, :name, :description, :is_public, :topic_type, :topic_source, :topic_property_first, :topic_property_second, :source_unit, :topic_repeat, :province, :city) -json.authorize @bank.user_id == current_user.id || current_user.admin? +json.authorize @bank.user_id == current_user.id || current_user.admin_or_business? json.attachment_list @bank_attachments do |attachment| json.partial! "attachments/attachment_simple", locals: {attachment: attachment} diff --git a/app/views/homework_banks/show.json.jbuilder b/app/views/homework_banks/show.json.jbuilder index f3785173a..82be072cf 100644 --- a/app/views/homework_banks/show.json.jbuilder +++ b/app/views/homework_banks/show.json.jbuilder @@ -1,5 +1,5 @@ json.(@bank, :id, :name, :description, :homework_type, :is_public, :min_num, :max_num, :base_on_project, :reference_answer) -json.authorize @bank.user_id == current_user.id || current_user.admin? +json.authorize @bank.user_id == current_user.id || current_user.admin_or_business? json.attachments @bank_attachments do |attachment| json.partial! "attachments/attachment_simple", locals: {attachment: attachment} diff --git a/app/views/shixun_lists/index.json.jbuilder b/app/views/shixun_lists/index.json.jbuilder index e926ee927..9526b0173 100644 --- a/app/views/shixun_lists/index.json.jbuilder +++ b/app/views/shixun_lists/index.json.jbuilder @@ -21,7 +21,7 @@ json.shixun_list do json.pic url_to_avatar(obj) json.content highlights json.level level_to_s(obj.trainee) - json.subjects obj.subjects.uniq do |subject| + json.subjects obj.subjects.visible.unhidden.uniq do |subject| json.(subject, :id, :name) end end diff --git a/app/views/student_works/show.json.jbuilder b/app/views/student_works/show.json.jbuilder index 7b3a91b5e..8cb3ee7ca 100644 --- a/app/views/student_works/show.json.jbuilder +++ b/app/views/student_works/show.json.jbuilder @@ -11,7 +11,7 @@ json.update_user_name @is_evaluation ? "匿名" : @work.update_user.try(:real_na json.update_atta @homework.late_duration && @is_author json.attachments @attachments do |atta| - json.partial! "attachments/attachment_simple", locals: {attachment: atta, delete: false, } + json.partial! "attachments/attachment_simple", locals: {attachment: atta, delete: false } end unless @is_evaluation diff --git a/app/views/task_banks/show.json.jbuilder b/app/views/task_banks/show.json.jbuilder index ab53399e1..bc9e6d70e 100644 --- a/app/views/task_banks/show.json.jbuilder +++ b/app/views/task_banks/show.json.jbuilder @@ -1,6 +1,6 @@ json.(@bank, :id, :name, :description, :task_type, :is_public) # 附件 -json.authorize @bank.user_id == current_user.id || current_user.admin? +json.authorize @bank.user_id == current_user.id || current_user.admin_or_business? json.attachments @bank_attachments do |attachment| json.partial! "attachments/attachment_simple", locals: {attachment: attachment} end diff --git a/app/views/users/question_banks/index.json.jbuilder b/app/views/users/question_banks/index.json.jbuilder index 018e78254..d39341e08 100644 --- a/app/views/users/question_banks/index.json.jbuilder +++ b/app/views/users/question_banks/index.json.jbuilder @@ -14,5 +14,5 @@ json.question_banks @question_banks do |question_bank| json.course_list_name question_bank.course_list&.name json.updated_at question_bank.updated_at json.solve_count @solve_count_map.fetch(question_bank.id, 0) - json.authorize question_bank.user_id == current_user.id || current_user.admin? + json.authorize question_bank.user_id == current_user.id || current_user.admin_or_business? end diff --git a/config/routes.rb b/config/routes.rb index 58f4f76a5..5a7b641f6 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -394,6 +394,7 @@ Rails.application.routes.draw do get 'cancel_publish' get 'cancel_has_publish' get 'statistics' + get 'statistics_new' get 'shixun_report' get 'school_report' post 'update_attr' diff --git a/db/migrate/20200109062658_create_subject_records.rb b/db/migrate/20200109062658_create_subject_records.rb new file mode 100644 index 000000000..97741fd8c --- /dev/null +++ b/db/migrate/20200109062658_create_subject_records.rb @@ -0,0 +1,14 @@ +class CreateSubjectRecords < ActiveRecord::Migration[5.2] + def change + create_table :subject_records do |t| + t.references :subject, unique: true + t.integer :study_count, default: 0 + t.integer :course_study_count, default: 0 + t.integer :initiative_study, default: 0 + t.integer :passed_count, default: 0 + t.integer :course_used_count, default: 0 + t.integer :school_used_count, default: 0 + t.timestamps + end + end +end diff --git a/db/migrate/20200109070211_create_subject_course_records.rb b/db/migrate/20200109070211_create_subject_course_records.rb new file mode 100644 index 000000000..cd88e7e40 --- /dev/null +++ b/db/migrate/20200109070211_create_subject_course_records.rb @@ -0,0 +1,16 @@ +class CreateSubjectCourseRecords < ActiveRecord::Migration[5.2] + def change + create_table :subject_course_records do |t| + t.references :subject + t.references :school + t.string :school_name + t.integer :course_count, default: 0 + t.integer :student_count, default: 0 + t.integer :choice_shixun_num, default: 0 + t.integer :choice_shixun_frequency, default: 0 + t.timestamps + end + + add_index :subject_course_records, [:school_id, :subject_id], unique: true, name: "couse_and_school_index" + end +end diff --git a/db/migrate/20200109084427_create_subject_shixun_infos.rb b/db/migrate/20200109084427_create_subject_shixun_infos.rb new file mode 100644 index 000000000..8916b2129 --- /dev/null +++ b/db/migrate/20200109084427_create_subject_shixun_infos.rb @@ -0,0 +1,21 @@ +class CreateSubjectShixunInfos < ActiveRecord::Migration[5.2] + def change + create_table :subject_shixun_infos do |t| + t.references :subject + t.references :shixun + t.string :stage + t.string :shixun_name + t.integer :challenge_count, default: 0 + t.integer :course_count, default: 0 + t.integer :school_count, default: 0 + t.integer :used_count, default: 0 + t.integer :passed_count, default: 0 + t.integer :evaluate_count, default: 0 + t.integer :passed_ave_time, default: 0 + + t.timestamps + end + + add_index :subject_shixun_infos, [:shixun_id, :subject_id], unique: true + end +end diff --git a/db/migrate/20200109091016_create_subject_user_infos.rb b/db/migrate/20200109091016_create_subject_user_infos.rb new file mode 100644 index 000000000..7f2671a71 --- /dev/null +++ b/db/migrate/20200109091016_create_subject_user_infos.rb @@ -0,0 +1,18 @@ +class CreateSubjectUserInfos < ActiveRecord::Migration[5.2] + def change + create_table :subject_user_infos do |t| + t.references :user + t.references :subject + t.string :username + t.integer :passed_myshixun_count, default: 0 + t.integer :passed_games_count, default: 0 + t.integer :code_line_count, default: 0 + t.integer :evaluate_count, default: 0 + t.integer :cost_time, default: 0 + t.timestamps + end + + add_index :subject_user_infos, [:user_id, :subject_id], unique: true + + end +end diff --git a/db/migrate/20200109095357_add_uniq_index_to_evaluation_distribution.rb b/db/migrate/20200109095357_add_uniq_index_to_evaluation_distribution.rb new file mode 100644 index 000000000..6bf860ef6 --- /dev/null +++ b/db/migrate/20200109095357_add_uniq_index_to_evaluation_distribution.rb @@ -0,0 +1,11 @@ +class AddUniqIndexToEvaluationDistribution < ActiveRecord::Migration[5.2] + def change + sql = %Q(delete from student_works_evaluation_distributions where (user_id, student_work_id) in + (select * from (select user_id, student_work_id from student_works_evaluation_distributions group by user_id, student_work_id having count(*) > 1) a) + and id not in (select * from (select min(id) from student_works_evaluation_distributions group by user_id, student_work_id having count(*) > 1 order by id) b)) + ActiveRecord::Base.connection.execute sql + + add_index :student_works_evaluation_distributions, [:student_work_id, :user_id], name: "index_on_student_work_id_and_user_id", unique: true + remove_index :student_works_evaluation_distributions, :user_id + end +end diff --git a/db/migrate/20200109105024_modify_myshixun_id_for_student_works.rb b/db/migrate/20200109105024_modify_myshixun_id_for_student_works.rb new file mode 100644 index 000000000..afecb4df5 --- /dev/null +++ b/db/migrate/20200109105024_modify_myshixun_id_for_student_works.rb @@ -0,0 +1,5 @@ +class ModifyMyshixunIdForStudentWorks < ActiveRecord::Migration[5.2] + def change + StudentWork.where(myshixun_id: nil).update_all(myshixun_id: 0) + end +end diff --git a/lib/tasks/statistic_subject_info.rake b/lib/tasks/statistic_subject_info.rake new file mode 100644 index 000000000..6373d7170 --- /dev/null +++ b/lib/tasks/statistic_subject_info.rake @@ -0,0 +1,111 @@ +desc "统计实践课程的学习统计数据" + +namespace :subjects do + task data_statistic: :environment do + puts("---------------------data_statistic_begin") + Rails.logger.info("---------------------data_statistic_begin") + subjects = Subject.where(status: 2) + subjects.find_each do |subject| + puts("---------------------data_statistic: #{subject.id}") + Rails.logger.info("---------------------data_statistic: #{subject.id}") + sr = SubjectRecord.find_or_create_by!(subject_id: subject.id) + data = Subjects::DataStatisticService.new(subject) + study_count = data.study_count + # 总人数没有变化的话,不同课堂之类的变化了 + course_study_count = (study_count == sr.study_count ? sr.course_study_count : data.course_study_count) + passed_count = (study_count == sr.study_count ? sr.passed_count : data.passed_count) + course_used_count = (study_count == sr.study_count ? sr.course_used_count : data.course_used_count) + school_used_count = (study_count == sr.study_count ? sr.school_used_count : data.school_used_count) + update_params = { + study_count: study_count, + course_study_count: course_study_count, + initiative_study: (study_count - course_study_count), + passed_count: passed_count, + course_used_count: course_used_count, + school_used_count: school_used_count + } + sr.update_attributes!(update_params) + end + puts("---------------------data_statistic_end") + Rails.logger.info("---------------------data_statistic_end") + end + + task course_info_statistic: :environment do + puts("---------------------course_info_statistic_begin") + Rails.logger.info("---------------------course_info_statistic_begin") + subjects = Subject.where(status: 2) + subjects.find_each do |subject| + puts("---------------------course_info_statistic: #{subject.id}") + Rails.logger.info("---------------------course_info_statistic: #{subject.id}") + data = Subjects::CourseUsedInfoService.call(subject) + data.each do |key| + scr = SubjectCourseRecord.find_or_create_by!(school_id: key[:school_id], subject_id: subject.id) + update_params = { + school_name: key[:school_name], + course_count: key[:course_count], + student_count: key[:student_count], + choice_shixun_num: key[:choice_shixun_num], + choice_shixun_frequency: key[:choice_shixun_frequency] + } + scr.update_attributes(update_params) + end + end + puts("---------------------course_info_statistic_end") + Rails.logger.info("---------------------course_info_statistic_end") + end + + task shixun_info_statistic: :environment do + puts("---------------------shixun_info_statistic_begin") + Rails.logger.info("---------------------shixun_info_statistic_begin") + subjects = Subject.where(status: 2) + subjects.find_each(batch_size: 100) do |subject| + puts("---------------------shixun_info_statistic: #{subject.id}") + Rails.logger.info("---------------------shixun_info_statistic: #{subject.id}") + data = Subjects::ShixunUsedInfoService.call(subject) + data.each do |key| + ssi = SubjectShixunInfo.find_or_create_by!(shixun_id: key[:shixun_id], subject_id: subject.id) + update_params = { + stage: key[:stage], + shixun_name: key[:name], + challenge_count: key[:challenge_count], + course_count: key[:course_count], + school_count: key[:school_count], + used_count: key[:used_count], + passed_count: key[:passed_count], + evaluate_count: key[:evaluate_count], + passed_ave_time: key[:passed_ave_time] + } + ssi.update_attributes(update_params) + end + end + puts("---------------------shixun_info_statistic_end") + Rails.logger.info("---------------------shixun_info_statistic_end") + end + + task user_info_statistic: :environment do + puts("---------------------user_info_statistic_begin") + Rails.logger.info("---------------------user_info_statistic_begin") + subjects = Subject.where(status: 2) + subjects.find_each(batch_size: 100) do |subject| + puts("---------------------user_info_statistic: #{subject.id}") + data = Subjects::UserUsedInfoService.call(subject) + data.each do |key| + sui = SubjectUserInfo.find_or_create_by!(user_id: key[:user_id], subject_id: subject.id) + update_params = { + username: key[:name], + passed_myshixun_count: key[:passed_myshixun_count], + passed_games_count: key[:passed_games_count], + code_line_count: key[:code_line_count], + evaluate_count: key[:evaluate_count], + cost_time: key[:cost_time] + } + sui.update_attributes(update_params) + end + end + puts("---------------------user_info_statistic_end") + Rails.logger.info("---------------------user_info_statistic_end") + end + + + + end diff --git a/public/react/public/index.html b/public/react/public/index.html index 303128b18..4aa03bc6b 100755 --- a/public/react/public/index.html +++ b/public/react/public/index.html @@ -7,6 +7,18 @@ + + + + + + + + + + + + diff --git a/public/react/src/common/quillForEditor/FillBlot.js b/public/react/src/common/quillForEditor/FillBlot.js index 144b499ee..2f9414253 100644 --- a/public/react/src/common/quillForEditor/FillBlot.js +++ b/public/react/src/common/quillForEditor/FillBlot.js @@ -4,16 +4,17 @@ * @Github: * @Date: 2020-01-06 09:02:29 * @LastEditors : tangjiang - * @LastEditTime : 2020-01-09 11:58:52 + * @LastEditTime : 2020-01-09 15:00:13 */ import Quill from 'quill'; // let Inline = Quill.import('blots/inline'); -const BlockEmbed = Quill.import('blots/block/embed'); +const BlockEmbed = Quill.import('blots/embed'); class FillBlot extends BlockEmbed { static create (value) { - const node = super.cerate(); + const node = super.cerate(value); // node.classList.add('icon icon-bianji2'); // node.setAttribute('data-fill', 'fill'); + console.log('编辑器值===》》》》》', value); node.setAttribute('data_index', value.data_index); node.nodeValue = value.text; return node; @@ -28,7 +29,7 @@ class FillBlot extends BlockEmbed { } -FillBlot.blotName = "fill"; +FillBlot.blotName = "fill-blot"; FillBlot.tagName = "span"; export default FillBlot; diff --git a/public/react/src/common/quillForEditor/index.js b/public/react/src/common/quillForEditor/index.js index f892e9b8d..525feba09 100644 --- a/public/react/src/common/quillForEditor/index.js +++ b/public/react/src/common/quillForEditor/index.js @@ -4,7 +4,7 @@ * @Github: * @Date: 2019-12-18 08:49:30 * @LastEditors : tangjiang - * @LastEditTime : 2020-01-09 11:56:10 + * @LastEditTime : 2020-01-10 15:05:27 */ import './index.scss'; import 'quill/dist/quill.core.css'; // 核心样式 @@ -31,14 +31,16 @@ Quill.register(ImageBlot); Quill.register(Size); Quill.register(Font, true); // Quill.register({'modules/toolbar': Toolbar}); -Quill.register(FillBlot); +Quill.register({ + 'formats/fill': FillBlot +}); // Quill.register(Color); function QuillForEditor ({ placeholder, readOnly, - autoFocus, + autoFocus = false, options, value, imgAttrs = {}, // 指定图片的宽高 @@ -194,10 +196,11 @@ function QuillForEditor ({ }); _quill.getModule('toolbar').addHandler('fill', (e) => { + // console.log('点击了填空=====>>>>>>', e); setFillCount(fillCount + 1); const range = _quill.getSelection(true); // _quill.insertText(range.index, '▁', { 'data_index': fillCount }); - _quill.insertEmbed(range.index, 'span', { + _quill.insertEmbed(range.index, 'fill', { text: '▁', 'data_index': fillCount }); @@ -229,16 +232,21 @@ function QuillForEditor ({ } const current = value - // console.log('+++++', current); if (!deepEqual(previous, current)) { setSelection(quill.getSelection()) if (typeof value === 'string') { - quill.clipboard.dangerouslyPasteHTML(value, 'api') + quill.clipboard.dangerouslyPasteHTML(value, 'api'); + if (autoFocus) { + quill.focus(); + } else { + quill.blur(); + } } else { quill.setContents(value) + if (autoFocus) quill.focus(); } } - }, [quill, value, setQuill]); + }, [quill, value, setQuill, autoFocus]); // 清除选择区域 useEffect(() => { @@ -272,13 +280,6 @@ function QuillForEditor ({ } }, [quill, handleOnChange]); - useEffect(() => { - if (!quill) return; - if (autoFocus) { - quill.focus(); - } - }, [quill, autoFocus]); - // 返回结果 return (
diff --git a/public/react/src/modules/courses/boards/TopicDetail.js b/public/react/src/modules/courses/boards/TopicDetail.js index d42b68c17..e8767fb87 100644 --- a/public/react/src/modules/courses/boards/TopicDetail.js +++ b/public/react/src/modules/courses/boards/TopicDetail.js @@ -65,7 +65,7 @@ class TopicDetail extends Component { const topicId = this.props.match.params.topicId const bid = this.props.match.params.boardId - + const memoUrl = `/messages/${topicId}.json`; this.setState({ memoLoading: true @@ -73,7 +73,7 @@ class TopicDetail extends Component { axios.get(memoUrl,{ }) .then((response) => { - + if (response.data.status === -1) { setTimeout(() => { this.props.showNotification('帖子不存在!') @@ -81,7 +81,7 @@ class TopicDetail extends Component { // this.props.toListPage(response.data.data.course_id, bid) return; } else { - + this.setState({ memo: Object.assign({}, { ...response.data.data, @@ -93,7 +93,7 @@ class TopicDetail extends Component { // const { memo_replies, memo } = response.data; // let hasMoreComments = false; - // if (memo_replies && memo_replies.length === 10 && memo.total_replies_count > 10) { + // if (memo_replies && memo_replies.length === 10 && memo.total_replies_count > 10) { // // 遍历一遍,计算下是否还有评论未加载 // let totalCount = 10; // memo_replies.forEach(item=>{ @@ -123,14 +123,14 @@ class TopicDetail extends Component { }) this.fetchReplies() - - $('body>#root').on('onMemoDelete', (event) => { + + $('body>#root').on('onMemoDelete', (event) => { // const val = $('body>#root').data('onMemoDelete') const val = window.onMemoDelete ; this.onMemoDelete( JSON.parse(decodeURIComponent(val)) ) }) - + } onPaginationChange = (pageCount) => { @@ -157,7 +157,7 @@ class TopicDetail extends Component { this.props.showNotification('删除成功'); const props = Object.assign({}, this.props, {}) this.props.toListPage( Object.assign({}, this.props.match.params, {'coursesId': this.state.memo.course_id} ) ) - + } else if (status === -1) { this.props.showNotification('帖子已被删除'); this.props.history.push(`/forums`) @@ -168,11 +168,11 @@ class TopicDetail extends Component { } componentDidUpdate(prevProps, prevState, snapshot) { - // if (this.state.memo && this.state.memo.content + // if (this.state.memo && this.state.memo.content // && (!prevProps.memo || prevProps.memo.content != this.state.memo.content) ) { if (this.state.memo && this.state.memo.content && prevState.memoLoading === true && this.state.memoLoading === false) { // md渲染content,等xhr执行完(即memoLoading变化),memo.content更新后初始化md - + setTimeout(()=>{ // var shixunDescr = window.editormd.markdownToHTML("memo_content_editorMd", { // htmlDecode: "style,script,iframe", // you can filter tags decode @@ -183,7 +183,7 @@ class TopicDetail extends Component { // }); }, 200) } - + } clickPraise(){ @@ -192,7 +192,7 @@ class TopicDetail extends Component { const url = memo.user_praise ? '/praise_tread/unlike.json' : `/praise_tread/like.json`; const _method = memo.user_praise ? axios.delete : axios.post let _data = { - object_id: memo.id, + object_id: memo.id, object_type: 'message', //Discuss } if (memo.user_praise) { @@ -204,10 +204,10 @@ class TopicDetail extends Component { ..._data }, { - + } ).then((response) => { - + const newMemo = Object.assign({}, this.state.memo) newMemo.praises_count = newMemo.user_praise ? newMemo.praises_count - 1 : newMemo.praises_count + 1 newMemo.total_praises_count = newMemo.user_praise ? newMemo.total_praises_count - 1 : newMemo.total_praises_count + 1 @@ -248,10 +248,10 @@ class TopicDetail extends Component { className="mr12 color9B9B overflowHidden1" length="58" style={{maxWidth: '480px'}}> {fileName} - + {item.filesize} - +
) }) @@ -268,7 +268,7 @@ class TopicDetail extends Component { permission: true, // children: children, child_message_count: reply.total_count, - hidden: reply.is_hidden, + hidden: reply.is_hidden, id: reply.id, image_url: reply.author.image_url, reward: null, // @@ -289,7 +289,7 @@ class TopicDetail extends Component { }) .then((response) => { const { replies, liked, total_replies_count, total_count } = response.data.data - + const memo = Object.assign({}, this.state.memo) memo.user_praise = liked memo.total_replies_count = total_replies_count; @@ -322,15 +322,15 @@ class TopicDetail extends Component { return; } const url = `/messages/${id}/reply.json`; - + const { comments } = this.state; const user = this._getUser(); /* 移除末尾的空行 .replace(/(\n

\n\t
\n<\/p>)*$/g,''); - + */ - + commentContent = handleContentBeforeCreateSecondLevelComment(commentContent) if (!commentContent) { this.props.showNotification('不能为空') @@ -340,9 +340,9 @@ class TopicDetail extends Component { content: commentContent }, { - } + } ).then((response) => { - if (response.data.data.id) { + if (response.data.data.id) { let newId = response.data.data.id; const commentIndex = this._findById(id, comments); const parentComment = comments[commentIndex] @@ -361,7 +361,7 @@ class TopicDetail extends Component { memo: newMemo2 }) } - + }).catch((error) => { console.log(error) }) @@ -369,14 +369,14 @@ class TopicDetail extends Component { // 公共接口 --- 删除回复 deleteComment = (parrentComment, childCommentId) => { handleDeleteComment(this, parrentComment, childCommentId, 'message') - + } // 公共接口 --- 回复点赞 commentPraise = (discussId) => { handleCommentPraise(this, discussId, 'message', (old_user_praise) => { const newMemo2 = Object.assign({}, this.state.memo); - newMemo2.total_praises_count = old_user_praise + newMemo2.total_praises_count = old_user_praise ? newMemo2.total_praises_count - 1 : newMemo2.total_praises_count + 1; this.setState({ memo: newMemo2 @@ -390,7 +390,7 @@ class TopicDetail extends Component { createNewComment = (commentContent, id, editor) => { let content = handleContentBeforeCreateNew(commentContent); const { memo } = this.props; - + const url = `/messages/${id}/reply.json`; // const url = `/api/v1/memos/${memo.id}/reply`; @@ -399,7 +399,7 @@ class TopicDetail extends Component { content: content }, { - } + } ).then((response) => { if (response.data.status === -1) { console.error('服务端异常') @@ -407,15 +407,15 @@ class TopicDetail extends Component { } // this.props.showNotification('帖子发表成功') - if (response.data) { + if (response.data) { const _id = response.data.data.id; // ke editor.html && editor.html(''); editor.afterBlur && editor.afterBlur() // md editor.setValue && editor.setValue('') - - + + const user = this._getUser(); this.setState({ comments: addNewComment(comments, _id, content, user, this.props.isSuperAdmin(), this) @@ -427,8 +427,8 @@ class TopicDetail extends Component { }) this.refs.editor.showEditor(); this.refs.editor.close(); - - + + } }).catch((error) => { console.log(error) @@ -444,7 +444,7 @@ class TopicDetail extends Component { }) .then((response) => { const { replies, liked, total_replies_count } = response.data.data - + // const memo = Object.assign({}, this.state.memo) // memo.total_replies_count = total_replies_count; this.setState({ @@ -460,19 +460,19 @@ class TopicDetail extends Component { // 置顶 setTop(memo) { // const params = { - // sticky: memo.sticky ? 0 : 1, + // sticky: memo.sticky ? 0 : 1, // } - // if (this.state.p_s_order) { + // if (this.state.p_s_order) { // params.order = this.state.p_s_order; // } - // if (this.state.p_forum_id) { + // if (this.state.p_forum_id) { // params.forum_id = this.state.p_forum_id; // } // let paramsUrl = urlStringify(params) const set_top_or_down_Url = `/messages/${memo.id}/sticky_top.json`; // 获取memo list axios.put(set_top_or_down_Url, { - + }) .then((response) => { const status = response.data.status @@ -487,7 +487,7 @@ class TopicDetail extends Component { console.log(error) }) } - + setRewardDialogVisible = (visible) => { this.setState({ goldRewardDialogOpen: visible @@ -512,7 +512,7 @@ class TopicDetail extends Component { } } - + render() { const { match, history } = this.props const { recommend_shixun, current_user,author_info } = this.props; @@ -567,7 +567,7 @@ class TopicDetail extends Component {

{memo.subject} - { !!memo.sticky && 置顶} { !!memo.reward && @@ -578,9 +578,9 @@ class TopicDetail extends Component {
} - +
-
+
@@ -625,7 +625,7 @@ class TopicDetail extends Component { {memo.visits || '1'} - { !!memo.total_replies_count && + { !!memo.total_replies_count && @@ -633,8 +633,8 @@ class TopicDetail extends Component { } - {!!memo.total_praises_count && - + {!!memo.total_praises_count && + { memo.total_praises_count } @@ -654,12 +654,12 @@ class TopicDetail extends Component {
- +
{/* */} - {memo.is_md == true ? - - : + {memo.is_md == true ? + + :
}
@@ -674,17 +674,17 @@ class TopicDetail extends Component {
- { memo.attachments && !!memo.attachments.length && + { memo.attachments && !!memo.attachments.length &&
{this.renderAttachment()}
}
- - {!isCourseEnd && } - {/* onClick={ this.createNewComment } + {/* onClick={ this.createNewComment } enableReplyTo={true} */}
- - - {/* { true ? : + + + {/* { true ? :
写评论
} */}
- - + +
- { total_count > REPLY_PAGE_COUNT && + { total_count > REPLY_PAGE_COUNT && } {!isCourseEnd &&
写评论
} -
- +
+ diff --git a/public/react/src/modules/courses/common/comments/CommonReply.js b/public/react/src/modules/courses/common/comments/CommonReply.js index 8b7817e85..42ec3d65a 100644 --- a/public/react/src/modules/courses/common/comments/CommonReply.js +++ b/public/react/src/modules/courses/common/comments/CommonReply.js @@ -18,7 +18,7 @@ import { generateComments, generateChildComments, _findById, handleContentBefore const REPLY_PAGE_COUNT = 10 const $ = window.$; -/* +/* 相比较GraduateTopicReply 改动的地方 列表接口名 /graduation_tasks/${graduation_topic_id}/show_comment.json?parent_id=${parent.id}&limit=500 回复类型名 jour_type: this.props.jour_type, @@ -34,7 +34,7 @@ class CommonReply extends Component{ componentDidMount(){ this.fetchReplies() - + } _getUser() { const { current_user } = this.props; @@ -58,7 +58,7 @@ class CommonReply extends Component{ // m_parent_id reply_id: memo.user_id || this.state.homework_user_id } - } + } ).then((response) => { if (response.data.status === -1) { console.error('服务端异常') @@ -66,15 +66,15 @@ class CommonReply extends Component{ } // this.props.showNotification('帖子发表成功') - if (response.data && response.data.id) { + if (response.data && response.data.id) { const _id = response.data.id; // md editor.setValue && editor.setValue('') this.refs.editor.close && this.refs.editor.close() - + const user = this._getUser(); const isSuperAdmin = this.props.isSuperAdmin() - + this.setState({ comments: addNewComment(this.state.comments, _id, content, user, isSuperAdmin, this), total_count: this.state.total_count + 1 @@ -98,13 +98,13 @@ class CommonReply extends Component{ return; } const url = `/users/reply_message.json`; - + const { comments } = this.state; const user = this._getUser(); const graduation_topic_id = this.props.memo.id const commentIndex = this._findById(id, comments); let comment = comments[commentIndex]; - + commentContent = handleContentBeforeCreateSecondLevelComment(commentContent) axios.post(url, { journals_for_message: { @@ -117,9 +117,9 @@ class CommonReply extends Component{ } }, { - } + } ).then((response) => { - if (response.data.id) { + if (response.data.id) { let newId = response.data.id; const newMemo2 = Object.assign({}, this.props.memo); @@ -132,7 +132,7 @@ class CommonReply extends Component{ }) } - + }).catch((error) => { console.log(error) }) @@ -146,7 +146,7 @@ class CommonReply extends Component{ }) .then((response) => { const { comments } = response.data - + // const memo = Object.assign({}, this.state.memo) // memo.sum_replies_count = sum_replies_count; @@ -164,7 +164,7 @@ class CommonReply extends Component{ this.fetchReplies() }) } - + fetchReplies = () => { const graduation_topic_id = this.props.memo.id const course_id = this.props.course_id @@ -174,7 +174,7 @@ class CommonReply extends Component{ }) .then((response) => { const { comments, messages_count, homework_user_id, parent_messages_count } = response.data - + this.setState({ comments: generateComments(comments, this.transformReply), // : this.state.comments.concat(comments), @@ -185,7 +185,7 @@ class CommonReply extends Component{ console.log(error) }) } - + transformReply = (reply, children = []) => { const isAdmin = this.props.isAdmin() const isSuperAdmin = this.props.isSuperAdmin() @@ -194,7 +194,7 @@ class CommonReply extends Component{ isSuperAdmin: isSuperAdmin, permission: true, // children: children, - hidden: reply.hidden, + hidden: reply.hidden, id: reply.id, image_url: reply.author.image_url, reward: null, // @@ -249,7 +249,7 @@ class CommonReply extends Component{ padding-bottom: 30px; } `} - - - - {/* { true ? : + + + {/* { true ? :
写评论
} */} - - { total_count > REPLY_PAGE_COUNT && + + { total_count > REPLY_PAGE_COUNT &&
写评论
diff --git a/public/react/src/modules/courses/graduation/topics/GraduateTopicReply.js b/public/react/src/modules/courses/graduation/topics/GraduateTopicReply.js index 4e318a0c1..df6152c04 100644 --- a/public/react/src/modules/courses/graduation/topics/GraduateTopicReply.js +++ b/public/react/src/modules/courses/graduation/topics/GraduateTopicReply.js @@ -28,7 +28,7 @@ class GraduateTopicReply extends Component{ componentDidMount(){ this.fetchReplies() - + } _getUser() { const { current_user } = this.props; @@ -52,7 +52,7 @@ class GraduateTopicReply extends Component{ // m_parent_id reply_id: memo.user_id } - } + } ).then((response) => { if (response.data.status === -1) { console.error('服务端异常') @@ -60,18 +60,18 @@ class GraduateTopicReply extends Component{ } // this.props.showNotification('帖子发表成功') - if (response.data && response.data.id) { + if (response.data && response.data.id) { const _id = response.data.id; // md editor.setValue && editor.setValue('') - + const user = this._getUser(); this.setState({ comments: addNewComment(this.state.comments, _id, content, user, this.props.isSuperAdmin(), this), total_count: this.state.total_count + 1 }) this.refs.editor.showEditor(); - + } }).catch((error) => { console.log(error) @@ -89,13 +89,13 @@ class GraduateTopicReply extends Component{ return; } const url = `/users/reply_message.json`; - + const { comments } = this.state; const user = this._getUser(); const graduation_topic_id = this.props.memo.id const commentIndex = this._findById(id, comments); let comment = comments[commentIndex]; - + commentContent = handleContentBeforeCreateSecondLevelComment(commentContent) axios.post(url, { journals_for_message: { @@ -107,9 +107,9 @@ class GraduateTopicReply extends Component{ } }, { - } + } ).then((response) => { - if (response.data.id) { + if (response.data.id) { let newId = response.data.id; this.setState({ @@ -122,7 +122,7 @@ class GraduateTopicReply extends Component{ memo: newMemo2 }) } - + }).catch((error) => { console.log(error) }) @@ -136,7 +136,7 @@ class GraduateTopicReply extends Component{ }) .then((response) => { const { comments } = response.data - + // const memo = Object.assign({}, this.state.memo) // memo.sum_replies_count = sum_replies_count; @@ -154,7 +154,7 @@ class GraduateTopicReply extends Component{ this.fetchReplies() }) } - + fetchReplies = () => { const graduation_topic_id = this.props.memo.id const course_id = this.props.course_id @@ -164,7 +164,7 @@ class GraduateTopicReply extends Component{ }) .then((response) => { const { comments, messages_count } = response.data - + this.setState({ comments: generateComments(comments, this.transformReply), // : this.state.comments.concat(comments), @@ -174,7 +174,7 @@ class GraduateTopicReply extends Component{ console.log(error) }) } - + transformReply = (reply, children = []) => { const isAdmin = this.props.isAdmin() const isSuperAdmin = this.props.isSuperAdmin() @@ -184,7 +184,7 @@ class GraduateTopicReply extends Component{ permission: true, // children: children, child_message_count: reply.child_message_count, - hidden: reply.hidden, + hidden: reply.hidden, id: reply.id, image_url: reply.author.image_url, reward: null, // @@ -226,7 +226,7 @@ class GraduateTopicReply extends Component{ return( -
- - - {/* { true ? : + + + {/* { true ? :
写评论
} */}
- - { total_count > REPLY_PAGE_COUNT && + + { total_count > REPLY_PAGE_COUNT &&
写评论
diff --git a/public/react/src/modules/developer/newOrEditTask/leftpane/editorTab/index.js b/public/react/src/modules/developer/newOrEditTask/leftpane/editorTab/index.js index 349404dfd..6fc264663 100644 --- a/public/react/src/modules/developer/newOrEditTask/leftpane/editorTab/index.js +++ b/public/react/src/modules/developer/newOrEditTask/leftpane/editorTab/index.js @@ -4,7 +4,7 @@ * @Github: * @Date: 2019-11-20 10:35:40 * @LastEditors : tangjiang - * @LastEditTime : 2020-01-09 14:18:37 + * @LastEditTime : 2020-01-10 15:06:23 */ import './index.scss'; // import 'katex/dist/katex.css'; @@ -453,6 +453,7 @@ class EditTab extends React.Component { colon={ false } > 10) { + if (memo_replies && memo_replies.length === 10 && memo.replies_count > 10) { // 遍历一遍,计算下是否还有评论未加载 let totalCount = 10; memo_replies.forEach(item=>{ @@ -96,7 +96,7 @@ class MemoDetail extends Component { }) delete response.data.memo_replies; // reset - response.data.memo.praise_count = response.data.memo.memo_praise_count + response.data.memo.praise_count = response.data.memo.memo_praise_count this.props.initForumState(response.data) // const user = response.data.current_user; // user.tidding_count = response.data.tidding_count; @@ -110,14 +110,14 @@ class MemoDetail extends Component { console.log(error) }) - $('body>#root').on('onMemoDelete', (event) => { + $('body>#root').on('onMemoDelete', (event) => { // const val = $('body>#root').data('onMemoDelete') const val = window.onMemoDelete ; this.onMemoDelete( JSON.parse(decodeURIComponent(val)) ) }) - + } componentWillUnmount() { $('body>#root').off('onMemoDelete') @@ -134,7 +134,7 @@ class MemoDetail extends Component { this.props.showNotification('删除成功'); this.props.history.push(`/forums`) - + } else if (status === -1) { this.props.showNotification('帖子已被删除'); this.props.history.push(`/forums`) @@ -145,7 +145,7 @@ class MemoDetail extends Component { } componentDidUpdate(prevProps, prevState, snapshot) { - // if (this.props.memo && this.props.memo.content + // if (this.props.memo && this.props.memo.content // && (!prevProps.memo || prevProps.memo.content != this.props.memo.content) ) { if (this.props.memo && this.props.memo.content && prevState.memoLoading === true && this.state.memoLoading === false) { // md渲染content,等xhr执行完(即memoLoading变化),memo.content更新后初始化md @@ -191,7 +191,7 @@ class MemoDetail extends Component { const ar = item.url.split('/') const fileName = item.title let filesize = item.filesize - + attachments.push( ) }) @@ -241,7 +241,7 @@ class MemoDetail extends Component { /* 移除末尾的空行 .replace(/(\n

\n\t
\n<\/p>)*$/g,''); - + */ if (commentContent) { commentContent = commentContent.replace(/(\n

\n\t
\n<\/p>)*$/g,''); @@ -254,10 +254,10 @@ class MemoDetail extends Component { }, { // withCredentials: true - } + } ).then((response) => { response.data.memo = response.data - if (response.data.memo) { + if (response.data.memo) { let newDiscuss = response.data.memo; var commentIndex = this._findById(id, comments); @@ -278,8 +278,8 @@ class MemoDetail extends Component { // "position": newDiscuss.position, "time": "1分钟前", "praise_count": 0, - - "user_id": newDiscuss.author_id, + + "user_id": newDiscuss.author_id, }) @@ -292,9 +292,9 @@ class MemoDetail extends Component { const $ = window.$ var view_selector = `.commentItemMDEditorView_${id}` $(view_selector).hide(); - } + } + - this.setState({ // runTesting: false, comments: comments @@ -320,15 +320,15 @@ class MemoDetail extends Component { deleteCommentId = childCommentId; } const url = `/memos/${deleteCommentId}.json` - let comments = this.state.comments; + let comments = this.state.comments; axios.delete(url, { // withCredentials: true - } + } ).then((response) => { // TODO 删除成功或失败 - if (response.data && response.data.status === 0) { + if (response.data && response.data.status === 0) { const commentIndex = this._findById(parrentComment.id, comments); // https://stackoverflow.com/questions/29527385/removing-element-from-array-in-component-state @@ -371,13 +371,13 @@ class MemoDetail extends Component { }, { // withCredentials: true - } + } ).then((response) => { - if (response.data.praise_count === 0 || response.data.praise_count) { - + if (response.data.praise_count === 0 || response.data.praise_count) { + comments[commentIndex].user_praise = !comments[commentIndex].user_praise; comments[commentIndex].praise_count = response.data.praise_count; - + this.setState({ comments }) @@ -406,9 +406,9 @@ class MemoDetail extends Component { }, { // withCredentials: true - } + } ).then((response) => { - if (response.data && response.data.code) { + if (response.data && response.data.code) { const commentIndex = this._findById(parrentComment.id, comments); if (childComment) { @@ -418,13 +418,13 @@ class MemoDetail extends Component { parrentComment.children[childCommentIndex] = newChildComment comments[commentIndex] = parrentComment; - + this.setState({ comments }) } else { comments[commentIndex].reward = response.data.code; - + this.setState({ comments }) @@ -449,14 +449,14 @@ class MemoDetail extends Component { }, { // withCredentials: true - } + } ).then((response) => { - if (response.data.status === -1) { + if (response.data.status === -1) { showNotification(response.data.message) return; } - if (response.data.status === 0) { - + if (response.data.status === 0) { + if (!childCommentId) { comment.hidden = !comment.hidden; this.setState({ @@ -468,7 +468,7 @@ class MemoDetail extends Component { childComment.hidden = !childComment.hidden; this.setState({ comments }) } - + } // {"message":"Couldn't find Discuss with id=911","status":-1} @@ -481,7 +481,7 @@ class MemoDetail extends Component { const { memo } = this.props; if(content != undefined){ content = content.replace(/(\n

\n\t
\n<\/p>)*$/g,''); - + var beforeImage = content.split(""); if(beforeImage[0] == "" && afterImage[1] == ""){ @@ -500,13 +500,13 @@ class MemoDetail extends Component { }, { // withCredentials: true - } + } ).then((response) => { if (response.data.status === -1) { console.error('服务端异常') return; } - if (response.data) { + if (response.data) { response.data.memo = response.data const newMemo = response.data.memo; // ke @@ -533,11 +533,11 @@ class MemoDetail extends Component { "user_praise": false, "time": "1分钟前", "praise_count": 0, - - "user_id": user.user_id, + + "user_id": user.user_id, }) - + this.setState({ comments }) @@ -558,11 +558,11 @@ class MemoDetail extends Component { const user = this._getUser(); const url = `/memos/${memo.id}/more_reply.json?page=${pageCount}`; axios.get(url, { - + }, { // withCredentials: true - } + } ).then((response) => { if (response.data.status === -1) { console.error('服务端异常') @@ -575,7 +575,7 @@ class MemoDetail extends Component { }) return; } - if (response.data.memos_count) { + if (response.data.memos_count) { const newComments = comments.concat(memo_replies); const hasMoreComments = memo_replies.length === 10 this.setState({ @@ -595,12 +595,12 @@ class MemoDetail extends Component { // 置顶 setTop(memo) { const params = { - sticky: memo.sticky ? 0 : 1, + sticky: memo.sticky ? 0 : 1, } - if (this.state.p_s_order) { + if (this.state.p_s_order) { params.order = this.state.p_s_order; } - if (this.state.p_forum_id) { + if (this.state.p_forum_id) { params.forum_id = this.state.p_forum_id; } let paramsUrl = urlStringify(params) @@ -628,7 +628,7 @@ class MemoDetail extends Component { const { memo, author_info } = this.props; const newMemo = Object.assign({}, memo); const _reward = parseInt(inputVal) - + const url = `/discusses/${memo.id}/reward_code.json` axios.post(url, { @@ -667,6 +667,8 @@ class MemoDetail extends Component { } // --------------------------------------------------------------------------------------------帖子獎勵 END showCommentInput = () => { + + debugger if (window.__useKindEditor === true) { this.refs.editor.showEditor(); } else { @@ -702,8 +704,8 @@ class MemoDetail extends Component { margin-top: 6px; } `} - - {/* overflowHidden1 */} {memo.subject} - { memo.sticky && 置顶} - { !!memo.reward && + { !!memo.reward && - @@ -749,8 +751,8 @@ class MemoDetail extends Component {

} - {/* 返回 @@ -773,7 +775,7 @@ class MemoDetail extends Component { {memo.viewed_count} - { !!memo.replies_count && + { !!memo.replies_count && {memo.replies_count} @@ -784,11 +786,11 @@ class MemoDetail extends Component {
- +
{ !memo.is_md ?
: - +
- 发送 diff --git a/public/react/src/modules/forums/MemoDetailMDEditor.js b/public/react/src/modules/forums/MemoDetailMDEditor.js index f00b4aeae..8076c5e6a 100644 --- a/public/react/src/modules/forums/MemoDetailMDEditor.js +++ b/public/react/src/modules/forums/MemoDetailMDEditor.js @@ -27,7 +27,7 @@ class MemoDetailMDEditor extends Component { componentDidUpdate(prevProps, prevState, snapshot) { if (this.props.memo && (!prevProps.memo || this.props.memo.id != prevProps.memo.id)) { // this.keEditor = window.sd_create_editor_from_data(this.props.memo.id, null, "100%", "Memo"); - // window._kk = this.keEditor + // window._kk = this.keEditor } } @@ -48,7 +48,7 @@ class MemoDetailMDEditor extends Component { console.log('create_editorMD_4comment') var commentMDEditor = window.create_editorMD_4comment("memo_comment_editorMd", '', this.props.height || 240, placeholder, imageUrl, () => { // commentMDEditor.focus() - + this.initDrag() commentMDEditor.cm.on("change", (_cm, changeObj) => { @@ -64,8 +64,8 @@ class MemoDetailMDEditor extends Component { }); this.commentMDEditor = commentMDEditor; window.commentMDEditor = commentMDEditor; - - }, window.__tt) + + }, window.__tt) } componentDidMount() { !this.props.usingMockInput && this.initMDEditor() @@ -75,8 +75,13 @@ class MemoDetailMDEditor extends Component { } onCommit = () => { + + if(this.props.checkIfProfileCompleted()===false){ + this.props.showhideAccountPhoneemailDialog() + return + } const content = this.commentMDEditor.getValue(); - // this.props.showError == + // this.props.showError == if (this.props.showError == true) { if (!content || content.trim() == "") { this.setState({ @@ -103,18 +108,18 @@ class MemoDetailMDEditor extends Component { window.$(document).trigger("onReply", { commentContent: content , id: this.props.memo.id, editor: this.commentMDEditor } ); } - + } showEditor() { - // $("html, body").animate({ scrollTop: $('.commentInput:visible').offset().top - 100 }, 1000, () => { - // if (this.commentMDEditor) { - // this.commentMDEditor.cm.focus() - // } else { - // this.onMockInputClick() - // } - // }); + $("html, body").animate({ scrollTop: $('.commentInput:visible').offset().top - 100 }, 1000, () => { + if (this.commentMDEditor) { + this.commentMDEditor.cm.focus() + } else { + this.onMockInputClick() + } + }); } close = () => { this.setState({isInited: false}) @@ -166,16 +171,16 @@ class MemoDetailMDEditor extends Component { width:100%!important; } `} -
- {this.props.buttonText || '发送'}
-
{errorMsg} }
- {this.props.buttonText || '发送'} diff --git a/public/react/src/modules/forums/MemoDetailMDEditortwo.js b/public/react/src/modules/forums/MemoDetailMDEditortwo.js index 257294452..eafc1451f 100644 --- a/public/react/src/modules/forums/MemoDetailMDEditortwo.js +++ b/public/react/src/modules/forums/MemoDetailMDEditortwo.js @@ -96,13 +96,13 @@ class MemoDetailMDEditortwo extends Component { } showEditor() { - // $("html, body").animate({ scrollTop: $('#commentInput').offset().top - 100 }, 1000, () => { - // if (this.commentMDEditor) { - // this.commentMDEditor.cm.focus() - // } else { - // $('#commentInput input')[0].click() - // } - // }); + $("html, body").animate({ scrollTop: $('#commentInput').offset().top - 100 }, 1000, () => { + if (this.commentMDEditor) { + this.commentMDEditor.cm.focus() + } else { + $('#commentInput input')[0].click() + } + }); } onMockInputClick = () => { this.setState({isInited: true}) diff --git a/public/react/src/modules/login/Trialapplication.js b/public/react/src/modules/login/Trialapplication.js index 094d683e0..be0b18edb 100644 --- a/public/react/src/modules/login/Trialapplication.js +++ b/public/react/src/modules/login/Trialapplication.js @@ -194,13 +194,13 @@ class Trialapplication extends Component { //短信验证 SMSverification = () => { + let logins=this.state.login; var url = `/accounts/get_verification_code.json`; - axios.get((url), { params: { login: this.state.login, type: 3, - smscode:setmiyah(this.state.logins) + smscode:setmiyah(logins) } }).then((result) => { //验证有问题{"status":1,"message":"success"} diff --git a/public/react/src/modules/login/Trialapplicationysl.js b/public/react/src/modules/login/Trialapplicationysl.js index ce6c28329..d685e1846 100644 --- a/public/react/src/modules/login/Trialapplicationysl.js +++ b/public/react/src/modules/login/Trialapplicationysl.js @@ -210,12 +210,13 @@ class Trialapplicationysl extends Component { //短信验证 SMSverification = () => { + let logins=this.state.login; var url = `/accounts/get_verification_code.json`; axios.get((url), { params: { login: this.state.login, type: 3, - smscode:setmiyah(this.state.logins) + smscode:setmiyah(logins) } }).then((result) => { //验证有问题{"status":1,"message":"success"} diff --git a/public/react/src/modules/tpm/TPMIndexHOC.js b/public/react/src/modules/tpm/TPMIndexHOC.js index aa88d7ea7..363acdba1 100644 --- a/public/react/src/modules/tpm/TPMIndexHOC.js +++ b/public/react/src/modules/tpm/TPMIndexHOC.js @@ -166,6 +166,27 @@ export function TPMIndexHOC(WrappedComponent) { document.title="翻转课堂"; } + // if(this.props.match.path==="/"){ + // document.title="EduCoder-IT实践教学平台_信息技术类精品课程网_大学生MOOC平台"; + // }else if(this.props.match.path==="/403"){ + // document.title="你没有权限访问"; + // }else if(this.props.match.path==="/nopage"){ + // document.title="没有找到该页面"; + // }else if(this.props.match.path==="/shixuns"){ + // document.title="EduCoder-IT实践教学平台_信息技术类精品课程网_大学生MOOC平台"; + // }else if(this.props.match.path==="/paths"){ + // document.title="实践课程_项目实战开发_web前端开发实训_web后端开发实战_人工智能技术-EduCoder"; + // }else if(this.props.match.path==="/courses"){ + // document.title="实训项目_php后端开发_app前端开发_java_python实训_C语言入门课程-EduCoder"; + // }else if(this.props.match.path==="/competitions"){ + // document.title="在线竞赛_计算机应用大赛_编程大赛_大学生设计大赛_全国高校绿色计算大赛-EduCoder"; + // }else if(this.props.match.path==="/moop_cases"){ + // document.title="教学案例-EduCoder"; + // }else if(this.props.match.path==="/forums"){ + // document.title="交流问答-EduCoder"; + // }else if(this.props.match.path==="/forums"){ + // document.title="交流问答-EduCoder"; + // } $.ajaxSetup({ cache: true diff --git a/public/react/src/modules/tpm/component/TPMRightSection.js b/public/react/src/modules/tpm/component/TPMRightSection.js index e6dc1da98..2cfe0047a 100644 --- a/public/react/src/modules/tpm/component/TPMRightSection.js +++ b/public/react/src/modules/tpm/component/TPMRightSection.js @@ -64,7 +64,7 @@ class TPMRightSection extends Component { Progresssum=(parseInt(TPMRightSectionData&&TPMRightSectionData.complete_count) / parseInt(TPMRightSectionData&&TPMRightSectionData.challenge_count))*100; } - + // console.log(this.props&&this.props.is_jupyter===true) return (
- {this.state.isopentitletype==="Less"?"":this.state.opentitletype===true?this.opentitle()} className={"pointer Breadcrumbfont color-grey-9 "}> + + {this.props&&this.props.is_jupyter===true&&this.props&&this.props.user.user_identity==="学生"?"":this.state.isopentitletype==="Less"?"":this.state.opentitletype===true?this.opentitle()} className={"pointer Breadcrumbfont color-grey-9 "}> 阅读全文 :this.opentitle()} className={"pointer Breadcrumbfont color-grey-9 "}> 收起全文 diff --git a/public/react/src/modules/tpm/shixuns/ShixunCard.js b/public/react/src/modules/tpm/shixuns/ShixunCard.js index 5086dd14d..a292f4d87 100644 --- a/public/react/src/modules/tpm/shixuns/ShixunCard.js +++ b/public/react/src/modules/tpm/shixuns/ShixunCard.js @@ -193,11 +193,11 @@ class ShixunCard extends Component {

- + {item.is_jupyter===false? {item.challenges_count} - + :""} {/**/} {/**/} diff --git a/public/react/src/modules/user/FindPasswordComponent.js b/public/react/src/modules/user/FindPasswordComponent.js index d9d7f1493..baf099909 100644 --- a/public/react/src/modules/user/FindPasswordComponent.js +++ b/public/react/src/modules/user/FindPasswordComponent.js @@ -157,12 +157,13 @@ class LoginRegisterComponent extends Component { } //短信验证 SMSverification = () => { + let logins=this.state.login; var url = `/accounts/get_verification_code.json`; axios.get((url), { params: { login: this.state.login, type: 2, - smscode:setmiyah(this.state.logins) + smscode:setmiyah(logins) } }).then((result) => { //验证有问题{"status":1,"message":"success"} diff --git a/public/react/src/modules/user/LoginRegisterComponent.js b/public/react/src/modules/user/LoginRegisterComponent.js index 0bff604d0..d00d54371 100644 --- a/public/react/src/modules/user/LoginRegisterComponent.js +++ b/public/react/src/modules/user/LoginRegisterComponent.js @@ -608,12 +608,13 @@ class LoginRegisterComponent extends Component { }; //短信验证 SMSverification = () => { + let logins=this.state.login; var url = `/accounts/get_verification_code.json`; axios.get((url), { params: { login: this.state.logins, type: 1, - smscode:setmiyah(this.state.logins) + smscode:setmiyah(logins) } }).then((result) => { //验证有问题{"status":1,"message":"success"} diff --git a/public/react/src/search/searchc.css b/public/react/src/search/searchc.css index 73de87236..d9132a436 100644 --- a/public/react/src/search/searchc.css +++ b/public/react/src/search/searchc.css @@ -20,11 +20,14 @@ justify-content: center; } +.packinput .ant-input-group-addon{ + border: 1px solid #4cacff!important; +} .packinput .ant-input-group-addon .ant-btn{ width:137px !important; font-size: 18px; height: 53px; - background:rgba(76,172,255,1); + border-color: #4cacff !important; } .tabtitle{ diff --git a/spec/models/subject_course_record_spec.rb b/spec/models/subject_course_record_spec.rb new file mode 100644 index 000000000..bf2daffc8 --- /dev/null +++ b/spec/models/subject_course_record_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe SubjectCourseRecord, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/models/subject_record_spec.rb b/spec/models/subject_record_spec.rb new file mode 100644 index 000000000..6dd9f7b4d --- /dev/null +++ b/spec/models/subject_record_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe SubjectRecord, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/models/subject_shixun_info_spec.rb b/spec/models/subject_shixun_info_spec.rb new file mode 100644 index 000000000..83d4b4bf9 --- /dev/null +++ b/spec/models/subject_shixun_info_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe SubjectShixunInfo, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/models/subject_user_info_spec.rb b/spec/models/subject_user_info_spec.rb new file mode 100644 index 000000000..60c8a76e6 --- /dev/null +++ b/spec/models/subject_user_info_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe SubjectUserInfo, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end