diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb index 23240fa75..99cb013b7 100644 --- a/app/controllers/accounts_controller.rb +++ b/app/controllers/accounts_controller.rb @@ -185,6 +185,9 @@ class AccountsController < ApplicationController send_type = verify_type(login_type, type) verification_code = code.sample(6).join + sign = Digest::MD5.hexdigest("#{OPENKEY}#{value}") + tip_exception(501, "请求不合理") if sign != params[:smscode] + logger.info("########get_verification_code: login_type: #{login_type}, send_type:#{send_type}, ") # 记录验证码 diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index dd015ba9e..f68784db8 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -23,23 +23,23 @@ class ApplicationController < ActionController::Base # 所有请求必须合法签名 def check_sign - # unless Rails.env.development? - # Rails.logger.info("66666 #{params}") - # suffix = request.url.split(".").last.split("?").first - # suffix_arr = ["xls", "xlsx", "pdf"] # excel文件先注释 - # unless suffix_arr.include?(suffix) - # if params[:client_key].present? - # randomcode = params[:randomcode] - # # tip_exception(501, "请求不合理") unless (Time.now.to_i - randomcode.to_i).between?(0,5) - # - # sign = Digest::MD5.hexdigest("#{OPENKEY}#{randomcode}") - # Rails.logger.info("2222 #{sign}") - # tip_exception(501, "请求不合理") if sign != params[:client_key] - # else - # tip_exception(501, "请求不合理") - # end - # end - # end + if !Rails.env.development? && EduSetting.get("host_name") != "https://test-newweb.educoder.net" + Rails.logger.info("66666 #{params}") + suffix = request.url.split(".").last.split("?").first + suffix_arr = ["xls", "xlsx", "pdf"] # excel文件先注释 + unless suffix_arr.include?(suffix) + if params[:client_key].present? + randomcode = params[:randomcode] + # tip_exception(501, "请求不合理") unless (Time.now.to_i - randomcode.to_i).between?(0,5) + + sign = Digest::MD5.hexdigest("#{OPENKEY}#{randomcode}") + Rails.logger.info("2222 #{sign}") + tip_exception(501, "请求不合理") if sign != params[:client_key] + else + tip_exception(501, "请求不合理") + end + end + end end # 全局配置参数 @@ -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/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/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 7df9aae89..8e23590ef 100644 --- a/app/controllers/subjects_controller.rb +++ b/app/controllers/subjects_controller.rb @@ -7,7 +7,7 @@ class SubjectsController < ApplicationController :search_members, :add_subject_members, :statistics, :shixun_report, :school_report, :up_member_position, :down_member_position, :update_team_title] before_action :require_admin, only: [:copy_subject] - before_action :shixun_marker, only: [:new, :create, :add_shixun_to_stage] + before_action :shixun_marker, only: [:add_shixun_to_stage] include ApplicationHelper @@ -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 2af43b6f5..e74290c84 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/templates/shixun_work/shixun_work.html.erb b/app/templates/shixun_work/shixun_work.html.erb index 76a269f3f..9a8481f94 100644 --- a/app/templates/shixun_work/shixun_work.html.erb +++ b/app/templates/shixun_work/shixun_work.html.erb @@ -178,20 +178,21 @@ 实训详情

<%#= ApplicationController.helpers.javascript_include_tag "/codemirror/lib/codemirror", "/codemirror/mode/javascript/javascript", "/codemirror/addon/hint/show-hint", "/codemirror/addon/hint/javascript-hint", "/codemirror/addon/selection/active-line", "/codemirror/addon/lint/javascript-lint", "/codemirror/addon/lint/css-lint", "/codemirror/addon/lint/lint", "/codemirror/addon/lint/json-lint", "/editormd/lib/codemirror/addon/lint/css-lint" %> - <% @games.each_with_index do |game, index| %> + <% @challenges.each_with_index do |challenge, index| %> + <% game = @games.select{|game| game.challenge_id == challenge.id}.first if @games %>

- <% if game.challenge.st == 1 %> + <% if challenge.st == 1 %> <% else %> <% end %> - 第<%= index+1 %>关<%= game.challenge.subject %> + 第<%= index+1 %>关<%= challenge.subject %>

- <% if game.outputs.present? %> + <% if game.present? && game.outputs.present? %> @@ -209,7 +210,7 @@
评测次数
<% end %> - <% if game.try(:lastest_code).present? && game.challenge.st == 0 %> + <% if game.present? && game.try(:lastest_code).present? && challenge.st == 0 %>

最近通过的代码 @@ -240,129 +241,129 @@ window.onload = function() { console.debug("window.onload"); - <% @games.map(&:id).each do |game_id| %> + <% if @games.present? %> + <% @games.map(&:id).each do |game_id| %> var ele = document.getElementById("content_show_<%= game_id %>"); if (ele) { - var ide = CodeMirror.fromTextArea(ele, { - lineNumbers: true, - theme: "default", - // extraKeys: {"Ctrl-Q": "autocomplete"}, // 快捷键 - indentUnit: 4, //代码缩进为一个tab的距离 - matchBrackets: true, - autoRefresh: true, - smartIndent: true,//智能换行 - styleActiveLine: true, - lineWrapping: true, - lint: true, - readOnly: "nocursor" - }); + var ide = CodeMirror.fromTextArea(ele, { + lineNumbers: true, + theme: "default", + // extraKeys: {"Ctrl-Q": "autocomplete"}, // 快捷键 + indentUnit: 4, //代码缩进为一个tab的距离 + matchBrackets: true, + autoRefresh: true, + smartIndent: true,//智能换行 + styleActiveLine: true, + lineWrapping: true, + lint: true, + readOnly: "nocursor" + }); - ide.setSize("auto", ide.lineCount() * 18); + ide.setSize("auto", ide.lineCount() * 18); } - <% end %> + <% end %> + // 基于准备好的dom,初始化echarts实例 + if(document.getElementById('shixun_skill_chart')){ + var effChart = echarts.init(document.getElementById('shixun_skill_chart')); + // 指定图表的配置项和数据 + var option = { + grid: { + left: '3%', + right: '9%', + bottom: '3%', + containLabel: true + }, + tooltip : {}, + xAxis : [ + { + type : 'value', + name: '学生序号', + scale:true, + axisLabel : { + formatter: ' ' + }, + axisTick:{ + show:false + }, + splitLine: { + show: false + } + } + ], + yAxis : [ + { + type : 'value', + name : '工作效率', + scale:true, + axisLabel : { + formatter: '{value} ' + }, + splitLine: { + show: false + } + } + ], + series : [ + { + name:'', + type:'scatter', + data: <%= @echart_data[:efficiency_list] %>, + itemStyle:{ + normal:{color:'#2e65ad'} + }, + markArea: { + silent: true, + itemStyle: { + normal: { + color: 'transparent', + borderWidth: 1, + borderType: 'dashed' + } + } + }, + markPoint : { + data : [ + { + name: 'daiao', + xAxis:<%= @myself_eff[0] %>, + yAxis:<%= @myself_eff[1] %> + } + ], + itemStyle: { + normal:{ + color:'#c23531' + } + } + }, + markLine : { + lineStyle: { + normal: { + type: 'solid', + color:'#c23531' + } + }, + data : [ + {type : 'average', name: '中位值'} + ] + } + }, + { + name:'二班', + type:'scatter', + data: [<%= @myself_eff %>], + itemStyle:{ + color:'#c23531' + } + } + ] + }; + // 使用刚指定的配置项和数据显示图表 + effChart.setOption(option); + console.debug(<%= @myself_consume %>); + } - // 基于准备好的dom,初始化echarts实例 - if(document.getElementById('shixun_skill_chart')){ - var effChart = echarts.init(document.getElementById('shixun_skill_chart')); - // 指定图表的配置项和数据 - var option = { - grid: { - left: '3%', - right: '9%', - bottom: '3%', - containLabel: true - }, - tooltip : {}, - xAxis : [ - { - type : 'value', - name: '学生序号', - scale:true, - axisLabel : { - formatter: ' ' - }, - axisTick:{ - show:false - }, - splitLine: { - show: false - } - } - ], - yAxis : [ - { - type : 'value', - name : '工作效率', - scale:true, - axisLabel : { - formatter: '{value} ' - }, - splitLine: { - show: false - } - } - ], - series : [ - { - name:'', - type:'scatter', - data: <%= @echart_data[:efficiency_list] %>, - itemStyle:{ - normal:{color:'#2e65ad'} - }, - markArea: { - silent: true, - itemStyle: { - normal: { - color: 'transparent', - borderWidth: 1, - borderType: 'dashed' - } - } - }, - markPoint : { - data : [ - { - name: 'daiao', - xAxis:<%= @myself_eff[0] %>, - yAxis:<%= @myself_eff[1] %> - } - ], - itemStyle: { - normal:{ - color:'#c23531' - } - } - }, - markLine : { - lineStyle: { - normal: { - type: 'solid', - color:'#c23531' - } - }, - data : [ - {type : 'average', name: '中位值'} - ] - } - }, - { - name:'二班', - type:'scatter', - data: [<%= @myself_eff %>], - itemStyle:{ - color:'#c23531' - } - } - ] - }; - // 使用刚指定的配置项和数据显示图表 - effChart.setOption(option); - console.debug(<%= @myself_consume %>); - } - - if(document.getElementById('shixun_skill_chart')) { + if(document.getElementById('shixun_overall_ablility_chart')) { var ablChart = echarts.init(document.getElementById('shixun_overall_ablility_chart')); var dataBJ = <%= @echart_data[:consume_list] %>; var schema = [ @@ -477,6 +478,8 @@ // 使用刚指定的配置项和数据显示图表。 ablChart.setOption(option1); } + <% 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 7d85d66db..efa7b001e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -407,6 +407,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/images/educoder/xcx/SMIDCard.png b/public/images/educoder/xcx/SMIDCard.png new file mode 100644 index 000000000..cea96596d Binary files /dev/null and b/public/images/educoder/xcx/SMIDCard.png differ diff --git a/public/images/educoder/xcx/ZYIDCard.png b/public/images/educoder/xcx/ZYIDCard.png new file mode 100644 index 000000000..7f2085fce Binary files /dev/null and b/public/images/educoder/xcx/ZYIDCard.png differ 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/App.js b/public/react/src/App.js index dabe4a50d..247e7939b 100644 --- a/public/react/src/App.js +++ b/public/react/src/App.js @@ -769,7 +769,7 @@ class App extends Component { render={ (props) => () } /> - () }/> diff --git a/public/react/src/AppConfig.js b/public/react/src/AppConfig.js index 278ffb555..451f0a87b 100644 --- a/public/react/src/AppConfig.js +++ b/public/react/src/AppConfig.js @@ -49,7 +49,7 @@ if (isDev) { if(timestamp&&checkSubmitFlg===false){ $.ajax({url:proxy,async:false,success:function(data){ if(data.status===0){ - timestamp=data.message; + timestamp=data.data.t; } }}) checkSubmitFlg=true @@ -59,7 +59,7 @@ if (isDev) { }else if(checkSubmitFlg===false){ $.ajax({url:proxy,async:false,success:function(data){ if(data.status===0){ - timestamp=data.message; + timestamp=data.data.t; } }}) checkSubmitFlg=true @@ -127,7 +127,7 @@ export function initAxiosInterceptors(props) { if (window.location.port === "3007") { // let timestamp=railsgettimes(proxy); // console.log(timestamp) - railsgettimes(`${proxy}/api/main/first_stamp.json`); + railsgettimes(`http://api.m.taobao.com/rest/api3.do?api=mtop.common.getTimestamp`); let newopens=md5(opens+timestamp) config.url = `${proxy}${url}`; if (config.url.indexOf('?') == -1) { @@ -137,7 +137,7 @@ export function initAxiosInterceptors(props) { } } else { // 加api前缀 - railsgettimes(`/api/main/first_stamp.json`); + railsgettimes(`http://api.m.taobao.com/rest/api3.do?api=mtop.common.getTimestamp`); let newopens=md5(opens+timestamp) config.url = url; if (config.url.indexOf('?') == -1) { diff --git a/public/react/src/common/Component.js b/public/react/src/common/Component.js new file mode 100644 index 000000000..e49d83b84 --- /dev/null +++ b/public/react/src/common/Component.js @@ -0,0 +1,5 @@ +import md5 from 'md5'; +export function setmiyah(logins){ + const opens ="79e33abd4b6588941ab7622aed1e67e8"; + return md5(opens+logins); +} diff --git a/public/react/src/common/UrlTool.js b/public/react/src/common/UrlTool.js index 26f44a2e5..decc7dfc7 100644 --- a/public/react/src/common/UrlTool.js +++ b/public/react/src/common/UrlTool.js @@ -81,7 +81,7 @@ function railsgettimess(proxy) { if(checkSubmitFlgs===false){ $.ajax({url:proxy,async:false,success:function(data){ if(data.status===0){ - newtimestamp=data.message; + newtimestamp=data.data.t; } }}) checkSubmitFlgs=true @@ -92,7 +92,7 @@ function railsgettimess(proxy) { } export function Railsgettimes() { - railsgettimess(`${getUrl()}/api/main/first_stamp.json`); + railsgettimess(`http://api.m.taobao.com/rest/api3.do?api=mtop.common.getTimestamp`); } export function getUploadActionUrl(path, goTest) { diff --git a/public/react/src/common/educoder.js b/public/react/src/common/educoder.js index ca546ec56..c4988dce2 100644 --- a/public/react/src/common/educoder.js +++ b/public/react/src/common/educoder.js @@ -3,21 +3,22 @@ // export { default as OrderStateUtil } from '../routes/Order/components/OrderStateUtil'; export { getImageUrl as getImageUrl, getRandomNumber as getRandomNumber,getUrl as getUrl, publicSearchs as publicSearchs,getRandomcode as getRandomcode,getUrlmys as getUrlmys, getUrl2 as getUrl2, setImagesUrl as setImagesUrl - , getUploadActionUrl as getUploadActionUrl,getUploadActionUrltwo as getUploadActionUrltwo ,getUploadActionUrlthree as getUploadActionUrlthree, getUploadActionUrlOfAuth as getUploadActionUrlOfAuth - , getTaskUrlById as getTaskUrlById, TEST_HOST ,htmlEncode as htmlEncode } from './UrlTool'; + , getUploadActionUrl as getUploadActionUrl,getUploadActionUrltwo as getUploadActionUrltwo ,getUploadActionUrlthree as getUploadActionUrlthree, getUploadActionUrlOfAuth as getUploadActionUrlOfAuth + , getTaskUrlById as getTaskUrlById, TEST_HOST ,htmlEncode as htmlEncode ,getupload_git_file as getupload_git_file} from './UrlTool'; +export {setmiyah as setmiyah} from './Component'; export { default as queryString } from './UrlTool2'; export { SnackbarHOC as SnackbarHOC } from './SnackbarHOC'; export { trigger as trigger, on as on, off as off - , broadcastChannelPostMessage, broadcastChannelOnmessage } from './EventUtil'; + , broadcastChannelPostMessage, broadcastChannelOnmessage } from './EventUtil'; export { updatePageParams as updatePageParams } from './RouterUtil'; export { bytesToSize as bytesToSize } from './UnitUtil'; export { markdownToHTML, uploadNameSizeSeperator, appendFileSizeToUploadFile, appendFileSizeToUploadFileAll, isImageExtension, - downloadFile, sortDirections } from './TextUtil' + downloadFile, sortDirections } from './TextUtil' export { handleDateString, getNextHalfHourOfMoment,formatDuring } from './DateUtil' export { configShareForIndex, configShareForPaths, configShareForShixuns, configShareForCourses, configShareForCustom } from './util/ShareUtil' @@ -29,7 +30,7 @@ export { toStore as toStore, fromStore as fromStore } from './Store' export { trace_collapse, trace, debug, info, warn, error, trace_c, debug_c, info_c, warn_c, error_c } from './LogUtil' export { EDU_ADMIN, EDU_BUSINESS, EDU_SHIXUN_MANAGER, EDU_SHIXUN_MEMBER, EDU_CERTIFICATION_TEACHER - , EDU_GAME_MANAGER, EDU_TEACHER, EDU_NORMAL} from './Const' + , EDU_GAME_MANAGER, EDU_TEACHER, EDU_NORMAL} from './Const' export { default as AttachmentList } from './components/attachment/AttachmentList' diff --git a/public/react/src/common/quillForEditor/FillBlot.js b/public/react/src/common/quillForEditor/FillBlot.js index d36f2d4b1..2f9414253 100644 --- a/public/react/src/common/quillForEditor/FillBlot.js +++ b/public/react/src/common/quillForEditor/FillBlot.js @@ -4,35 +4,32 @@ * @Github: * @Date: 2020-01-06 09:02:29 * @LastEditors : tangjiang - * @LastEditTime : 2020-01-06 16:04:46 + * @LastEditTime : 2020-01-09 15:00:13 */ import Quill from 'quill'; - -let Inline = Quill.import('blots/inline'); - -class FillBlot extends Inline { +// let Inline = Quill.import('blots/inline'); +const BlockEmbed = Quill.import('blots/embed'); +class FillBlot extends BlockEmbed { static create (value) { - const node = super.cerate(); - node.classList.add('icon icon-bianji2'); - node.setAttribute('data-fill', 'fill'); - node.addEventListener('DOMNodeRemoved', function () { - alert(123); - }, false); + 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; } static value (node) { return { - dataSet: node.getAttribute('data-fill'), - onDOMNodeRemoved: () => { - alert('123456'); - } + // dataSet: node.getAttribute('data-fill'), + data_index: node.getAttribute('data_index') } } } -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 2cded3fc3..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:01:51 + * @LastEditTime : 2020-01-10 15:05:27 */ import './index.scss'; import 'quill/dist/quill.core.css'; // 核心样式 @@ -18,12 +18,9 @@ import deepEqual from './deepEqual.js' import { fetchUploadImage } from '../../services/ojService.js'; import { getImageUrl } from 'educoder' import ImageBlot from './ImageBlot'; -import { Modal } from 'antd'; -// import Toolbar from 'quill/modules/toolbar'; -import FillBlot from './FillBlot'; +import FillBlot from './FillBlot'; const Size = Quill.import('attributors/style/size'); const Font = Quill.import('formats/font'); -const { confirm } = Modal; // const Color = Quill.import('attributes/style/color'); Size.whitelist = ['12px', '14px', '16px', '18px', '20px', false]; Font.whitelist = ['SimSun', 'SimHei','Microsoft-YaHei','KaiTi','FangSong','Arial','Times-New-Roman','sans-serif']; @@ -34,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 = {}, // 指定图片的宽高 @@ -96,19 +95,38 @@ function QuillForEditor ({ }, backspace: { key: 'Backspace', + /** + * @param {*} range + * { index, // 删除元素的位置 + * length // 删除元素的个数, 当删除一个时, length=0, 其它等于删除的元素的个数 + * } + * @param {*} context 上下文 + */ handler: function (range, context) { console.log('调用了删除按钮', range, context); - // 1. 获取删除的文件 - // 2. 判断删除的文件中包含空格的个数 - // 3. 循环调用删除方法 - const r = window.confirm('确定要删除吗?') - console.log('+++++', quill); - if (r) { - // 调用传入的删除事件 - return true - } else { - return false; - } + /** + * 1. 根据range中的index及length值获取删除的起始位置 + * length === 0 -> start = index - 1; + * length !== 0 -> start = index + * 2. 获取删除的元素内容 + * ctx = this.quill.getText(start, length === 0 ? 1 : length); + * 3. 判断当前删除的下划线是第几个 + */ + const {index, length} = range; + const _start = length === 0 ? index - 1 : index; + const _length = length || 1; + let delCtx = this.quill.getText(_start, _length); + // aa + console.log(delCtx.match(/▁/g)); + console.log('删除的文本信息=====>>>>', delCtx); + // const r = window.confirm('确定要删除吗?') + // if (r) { + // // 调用传入的删除事件 + // return true + // } else { + // return false; + // } + return true; } } }; @@ -178,9 +196,14 @@ function QuillForEditor ({ }); _quill.getModule('toolbar').addHandler('fill', (e) => { + // console.log('点击了填空=====>>>>>>', e); setFillCount(fillCount + 1); const range = _quill.getSelection(true); - _quill.insertText(range.index, '▁'); + // _quill.insertText(range.index, '▁', { 'data_index': fillCount }); + _quill.insertEmbed(range.index, 'fill', { + text: '▁', + 'data_index': fillCount + }); // 点击填空图标时,插入一个下划线 // 1. 获取编辑器内容 }); @@ -209,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(() => { @@ -242,33 +270,6 @@ function QuillForEditor ({ quill.on( 'text-change', (handler = (delta, oldDelta, source) => { - // let del = false; - // let delLen = 1; - // delta.ops.forEach(o => { - // // 存在删除并且只删除一个 - // if (o.delete) { - // del = true; - // } - // }); - // 删除编辑器内容 - // if (del) { - // delLen = delta.ops[0].retain || 1; // 删除数组的长度 - // // 获取删除的内容并判断其它是否有填空内容 - // console.log('原编辑器内容', oldDelta); - // console.log('编辑器内容', quillCtx); - // } - // 获取删除的内容 - // oldDelta - // if (del) { - // const ops = oldDelta.ops; - // const len = ops.length; - // // if (ops[len - 1] && ops[len - 1].insert) { - // // const str = ops[len - 1].insert; - // // const _len = str.length; - // // const _last = str.substr(_len - 1); - // // console.log('删除的一项', _last); - // // } - // } const _ctx = quill.getContents(); setQuillCtx(_ctx); handleOnChange(quill.getContents()); // getContents: 检索编辑器内容 @@ -279,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/competitions/Competitioncommon/CompetitionCommonChild/CompetitionContentspdfChild/CompetitionContentspdfpeopledata.js b/public/react/src/modules/competitions/Competitioncommon/CompetitionCommonChild/CompetitionContentspdfChild/CompetitionContentspdfpeopledata.js index 1afbf16a7..befecc817 100644 --- a/public/react/src/modules/competitions/Competitioncommon/CompetitionCommonChild/CompetitionContentspdfChild/CompetitionContentspdfpeopledata.js +++ b/public/react/src/modules/competitions/Competitioncommon/CompetitionCommonChild/CompetitionContentspdfChild/CompetitionContentspdfpeopledata.js @@ -1,7 +1,7 @@ import React, {Component} from 'react'; import {Button, Layout, Input, Form} from 'antd'; import axios from 'axios'; -import {getImageUrl} from 'educoder'; +import {setmiyah} from 'educoder'; import mycompetotionchild from './mycompetotionchild.css'; import {getHiddenName} from "../../../../user/account/AccountBasicEdit"; import '../../../../courses/css/Courses.css' @@ -200,9 +200,10 @@ class CompetitionContentspdfpeopledata extends Component { this.props.showNotification(`请先输入${index == 3 ? "手机号码" : "邮箱地址"}`); return; } + let smscode=setmiyah(login) axios.get((url), { params: { - login, type + login, type,smscode } }).then((result) => { if (result) { diff --git a/public/react/src/modules/competitions/Competitioncommon/CompetitionCommonChild/CompetitionContentspdfChild/Mailboxvalidation.js b/public/react/src/modules/competitions/Competitioncommon/CompetitionCommonChild/CompetitionContentspdfChild/Mailboxvalidation.js index 934369aac..fd049dc55 100644 --- a/public/react/src/modules/competitions/Competitioncommon/CompetitionCommonChild/CompetitionContentspdfChild/Mailboxvalidation.js +++ b/public/react/src/modules/competitions/Competitioncommon/CompetitionCommonChild/CompetitionContentspdfChild/Mailboxvalidation.js @@ -1,7 +1,7 @@ import React, {Component} from 'react'; import {Button, Layout, Input, Form} from 'antd'; import axios from 'axios'; -import {getImageUrl} from 'educoder'; +import {setmiyah} from 'educoder'; import mycompetotionchild from './mycompetotionchild.css'; import {getHiddenName} from "../../../../user/account/AccountBasicEdit"; import '../../../../courses/css/Courses.css' @@ -78,6 +78,7 @@ class Mailboxvalidation extends Component { let url = `/accounts/get_verification_code.json` let login = ''; let values = this.props.form.getFieldsValue(); + if (index == 3) { //绑定手机号码 login = values.phone; @@ -100,13 +101,20 @@ class Mailboxvalidation extends Component { this.props.showNotification(`请先输入${index == 3 ? "手机号码" : "邮箱地址"}`); return; } + let smscode=setmiyah(login) axios.get((url), { params: { - login, type + login, type,smscode } }).then((result) => { if (result) { // 倒计时 + if(result.data.status===1){ + this.props.showNotification("验证码已发送,请注意查收"); + }else if(result.data.status===-2){ + this.props.showNotification(result.data.message); + } + this.setState({ secondsFlag: true }) diff --git a/public/react/src/modules/competitions/Competitioncommon/CompetitionCommonChild/CompetitionContentspdfChild/Phonenumberverification.js b/public/react/src/modules/competitions/Competitioncommon/CompetitionCommonChild/CompetitionContentspdfChild/Phonenumberverification.js index fa0b20b7a..0fe7e2bc0 100644 --- a/public/react/src/modules/competitions/Competitioncommon/CompetitionCommonChild/CompetitionContentspdfChild/Phonenumberverification.js +++ b/public/react/src/modules/competitions/Competitioncommon/CompetitionCommonChild/CompetitionContentspdfChild/Phonenumberverification.js @@ -1,7 +1,7 @@ import React, {Component} from 'react'; import {Button, Layout, Input, Form} from 'antd'; import axios from 'axios'; -import {getImageUrl} from 'educoder'; +import {setmiyah} from 'educoder'; import mycompetotionchild from './mycompetotionchild.css'; import {getHiddenName} from "../../../../user/account/AccountBasicEdit"; import '../../../../courses/css/Courses.css' @@ -77,6 +77,7 @@ class Phonenumberverification extends Component { let url = `/accounts/get_verification_code.json` let login = ''; let values = this.props.form.getFieldsValue(); + if (index == 3) { //绑定手机号码 login = values.phone; @@ -99,13 +100,19 @@ class Phonenumberverification extends Component { this.props.showNotification(`请先输入${index == 3 ? "手机号码" : "邮箱地址"}`); return; } + let smscode=setmiyah(login) axios.get((url), { params: { - login, type + login, type,smscode } }).then((result) => { if (result) { // 倒计时 + if(result.data.status===1){ + this.props.showNotification("验证码已发送,请注意查收"); + }else if(result.data.status===-2){ + this.props.showNotification(result.data.message); + } this.setState({ secondsFlag: true }) 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/busyWork/NewWorkForm.js b/public/react/src/modules/courses/busyWork/NewWorkForm.js index 6740f7579..edd83c9e1 100644 --- a/public/react/src/modules/courses/busyWork/NewWorkForm.js +++ b/public/react/src/modules/courses/busyWork/NewWorkForm.js @@ -109,19 +109,21 @@ class NewWorkForm extends Component{ // 输入title changeTitle=(e)=>{ - console.log(e.target.value.length); + this.setState({ title_num: parseInt(e.target.value.length) }) } + + handleSubmit = () => { const courseId = this.state.course_id || this.props.match.params.coursesId ; this.props.form.validateFieldsAndScroll((err, values) => { if(err && err.personNum) delete err.personNum; - console.log(values) + const mdContnet = this.contentMdRef.current.getValue().trim(); - console.log(mdContnet) + values.description = mdContnet; // return; @@ -133,15 +135,19 @@ class NewWorkForm extends Component{ if (isGroup) { if (!min_num) { this.props.showNotification('最小人数不能为空'); + this.props.scrollToAnchor("numberofgroups"); return; } else if (min_num < 1) { this.props.showNotification('最小人数不能小于1'); + this.props.scrollToAnchor("numberofgroups"); return; } else if (!max_num) { this.props.showNotification('最大人数不能为空'); + this.props.scrollToAnchor("numberofgroups"); return; } else if (max_num < min_num) { this.props.showNotification('最大人数不能小于最小人数'); + this.props.scrollToAnchor("numberofgroups"); return; } @@ -254,7 +260,7 @@ class NewWorkForm extends Component{ if (response.data) { const { status } = response.data; if (status == 0) { - console.log('--- success') + this.setState((state) => { const index = state[stateName].indexOf(file); @@ -272,16 +278,16 @@ class NewWorkForm extends Component{ }); } max_num_change = (val) => { - if (val < 2) { - // this.setState({ - // max_num: 2, - // }) - return; - } + // if (val < 2) { + // // this.setState({ + // // max_num: 2, + // // }) + // return; + // } const { min_num } = this.state; this.setState({ max_num: val, - min_num: val <= min_num ? val - 1 : min_num + // min_num: val <= min_num ? val - 1 : min_num }) } personNumValidator = (rule, value, callback) => { @@ -337,7 +343,7 @@ class NewWorkForm extends Component{ onChange: this.handleContentUploadChange, onRemove: (file) => this.onAttachmentRemove(file, 'contentFileList'), beforeUpload: (file) => { - console.log('beforeUpload', file.name); + const isLt150M = file.size / 1024 / 1024 < 150; if (!isLt150M) { this.props.showNotification('文件大小必须小于150MB!'); @@ -356,7 +362,7 @@ class NewWorkForm extends Component{ onChange: this.handleAnswerUploadChange, onRemove: (file) => this.onAttachmentRemove(file, 'answerFileList'), beforeUpload: (file) => { - console.log('beforeUpload', file.name); + const isLt150M = file.size / 1024 / 1024 < 150; if (!isLt150M) { this.props.showNotification('文件大小必须小于150MB!'); @@ -461,7 +467,7 @@ class NewWorkForm extends Component{ (单个文件150M以内) - + { isGroup && +

{/* max={has_commit ? init_min_num : null } */} @@ -508,6 +514,7 @@ class NewWorkForm extends Component{ } +

{ 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/competitions/Competitioncommon/CompetitionCommonChild/CompetitionContentspdfChild/CompetitionContentspdfpeopledata.js b/public/react/src/modules/courses/competitions/Competitioncommon/CompetitionCommonChild/CompetitionContentspdfChild/CompetitionContentspdfpeopledata.js index 1afbf16a7..b4826241a 100644 --- a/public/react/src/modules/courses/competitions/Competitioncommon/CompetitionCommonChild/CompetitionContentspdfChild/CompetitionContentspdfpeopledata.js +++ b/public/react/src/modules/courses/competitions/Competitioncommon/CompetitionCommonChild/CompetitionContentspdfChild/CompetitionContentspdfpeopledata.js @@ -1,7 +1,7 @@ import React, {Component} from 'react'; import {Button, Layout, Input, Form} from 'antd'; import axios from 'axios'; -import {getImageUrl} from 'educoder'; +import {setmiyah} from 'educoder'; import mycompetotionchild from './mycompetotionchild.css'; import {getHiddenName} from "../../../../user/account/AccountBasicEdit"; import '../../../../courses/css/Courses.css' @@ -176,6 +176,7 @@ class CompetitionContentspdfpeopledata extends Component { // 获取验证码 getCode = (index) => { let url = `/accounts/get_verification_code.json` + let login = ''; let values = this.props.form.getFieldsValue(); if (index == 3) { @@ -200,9 +201,10 @@ class CompetitionContentspdfpeopledata extends Component { this.props.showNotification(`请先输入${index == 3 ? "手机号码" : "邮箱地址"}`); return; } + let smscode=setmiyah(login) axios.get((url), { params: { - login, type + login, type,smscode } }).then((result) => { if (result) { diff --git a/public/react/src/modules/courses/competitions/Competitioncommon/CompetitionCommonChild/CompetitionContentspdfChild/Mailboxvalidation.js b/public/react/src/modules/courses/competitions/Competitioncommon/CompetitionCommonChild/CompetitionContentspdfChild/Mailboxvalidation.js index 934369aac..f9125dfe5 100644 --- a/public/react/src/modules/courses/competitions/Competitioncommon/CompetitionCommonChild/CompetitionContentspdfChild/Mailboxvalidation.js +++ b/public/react/src/modules/courses/competitions/Competitioncommon/CompetitionCommonChild/CompetitionContentspdfChild/Mailboxvalidation.js @@ -1,7 +1,7 @@ import React, {Component} from 'react'; import {Button, Layout, Input, Form} from 'antd'; import axios from 'axios'; -import {getImageUrl} from 'educoder'; +import {setmiyah} from 'educoder'; import mycompetotionchild from './mycompetotionchild.css'; import {getHiddenName} from "../../../../user/account/AccountBasicEdit"; import '../../../../courses/css/Courses.css' @@ -78,6 +78,7 @@ class Mailboxvalidation extends Component { let url = `/accounts/get_verification_code.json` let login = ''; let values = this.props.form.getFieldsValue(); + if (index == 3) { //绑定手机号码 login = values.phone; @@ -100,13 +101,20 @@ class Mailboxvalidation extends Component { this.props.showNotification(`请先输入${index == 3 ? "手机号码" : "邮箱地址"}`); return; } + + let smscode=setmiyah(login) axios.get((url), { params: { - login, type + login, type,smscode } }).then((result) => { if (result) { // 倒计时 + if(result.data.status===1){ + this.props.showNotification("验证码已发送,请注意查收"); + }else if(result.data.status===-2){ + this.props.showNotification(result.data.message); + } this.setState({ secondsFlag: true }) diff --git a/public/react/src/modules/courses/competitions/Competitioncommon/CompetitionCommonChild/CompetitionContentspdfChild/Phonenumberverification.js b/public/react/src/modules/courses/competitions/Competitioncommon/CompetitionCommonChild/CompetitionContentspdfChild/Phonenumberverification.js index fa0b20b7a..e1c680dd0 100644 --- a/public/react/src/modules/courses/competitions/Competitioncommon/CompetitionCommonChild/CompetitionContentspdfChild/Phonenumberverification.js +++ b/public/react/src/modules/courses/competitions/Competitioncommon/CompetitionCommonChild/CompetitionContentspdfChild/Phonenumberverification.js @@ -1,7 +1,7 @@ import React, {Component} from 'react'; import {Button, Layout, Input, Form} from 'antd'; import axios from 'axios'; -import {getImageUrl} from 'educoder'; +import {setmiyah} from 'educoder'; import mycompetotionchild from './mycompetotionchild.css'; import {getHiddenName} from "../../../../user/account/AccountBasicEdit"; import '../../../../courses/css/Courses.css' @@ -77,6 +77,7 @@ class Phonenumberverification extends Component { let url = `/accounts/get_verification_code.json` let login = ''; let values = this.props.form.getFieldsValue(); + if (index == 3) { //绑定手机号码 login = values.phone; @@ -99,13 +100,20 @@ class Phonenumberverification extends Component { this.props.showNotification(`请先输入${index == 3 ? "手机号码" : "邮箱地址"}`); return; } + + let smscode=setmiyah(login) axios.get((url), { params: { - login, type + login, type,smscode } }).then((result) => { if (result) { // 倒计时 + if(result.data.status===1){ + this.props.showNotification("验证码已发送,请注意查收"); + }else if(result.data.status===-2){ + this.props.showNotification(result.data.message); + } this.setState({ secondsFlag: true }) diff --git a/public/react/src/modules/courses/exercise/Exercisesetting.js b/public/react/src/modules/courses/exercise/Exercisesetting.js index 0230c9bc7..0e613a554 100644 --- a/public/react/src/modules/courses/exercise/Exercisesetting.js +++ b/public/react/src/modules/courses/exercise/Exercisesetting.js @@ -638,7 +638,7 @@ class Exercisesetting extends Component{ {getFieldDecorator('unified_setting') ( - 统一设置 )} @@ -664,7 +664,7 @@ class Exercisesetting extends Component{ disabledDate={disabledDate} onChange={this.onChangeTimepublish} value={publish_time && moment(publish_time,"YYYY-MM-DD HH:mm")} - disabled={ publish_timetype===true?true:!flagPageEdit } + disabled={ this.props.isAdmin()===true?publish_timetype===true?true:!flagPageEdit:true} >

@@ -692,7 +692,7 @@ class Exercisesetting extends Component{ disabledDate={disabledDate} onChange={this.onChangeTimeEnd} value={end_time && moment(end_time,"YYYY-MM-DD HH:mm")} - disabled={ end_timetype===true?this.props.isAdmin()?!flagPageEdit:true:!flagPageEdit} + disabled={ this.props.isAdmin()===true? end_timetype===true?this.props.isAdmin()?!flagPageEdit:true:!flagPageEdit:true} > @@ -729,7 +729,7 @@ class Exercisesetting extends Component{ {getFieldDecorator('time') ( - )} @@ -746,7 +746,7 @@ class Exercisesetting extends Component{ {getFieldDecorator('question_random') ( - 题目顺序随机打乱 + 题目顺序随机打乱 )} (选中,则学生答题时,题目顺序按照题型随机显示) @@ -755,7 +755,7 @@ class Exercisesetting extends Component{ {getFieldDecorator('choice_random') ( - 选项顺序随机打乱 + 选项顺序随机打乱 )} (选中,则学生答题时,选项顺序随机显示) @@ -776,7 +776,7 @@ class Exercisesetting extends Component{ {getFieldDecorator('score_open') ( - 公开成绩 + 公开成绩 )} (选中,则在试卷截止时间之后,已提交答题的学生可以查看其它学生的成绩,否则只能查看自己的成绩) @@ -785,7 +785,7 @@ class Exercisesetting extends Component{ {getFieldDecorator('answer_open') ( - 公开答案 + 公开答案 )} (选中,则在试卷截止时间之后,已提交答题的学生可以查看试卷题目的答案,否则不能查看) @@ -794,7 +794,7 @@ class Exercisesetting extends Component{ {getFieldDecorator('show_statistic') ( - 公开统计 + 公开统计 )} (选中,则在试卷截止时间之后,已提交答题的学生可以查看答题统计,否则不能查看) diff --git a/public/react/src/modules/courses/exercise/Testpapersettinghomepage.js b/public/react/src/modules/courses/exercise/Testpapersettinghomepage.js index 47f42405d..63bdbd170 100644 --- a/public/react/src/modules/courses/exercise/Testpapersettinghomepage.js +++ b/public/react/src/modules/courses/exercise/Testpapersettinghomepage.js @@ -364,7 +364,8 @@ class Testpapersettinghomepage extends Component{

答题列表 {Commonheadofthetestpaper&&Commonheadofthetestpaper.show_statistic===true? - 统计结果:""} + Commonheadofthetestpaper && Commonheadofthetestpaper.exercise_status===3? + 统计结果:"":""} 设置 } diff --git a/public/react/src/modules/courses/graduation/tasks/GraduationTaskssetting.js b/public/react/src/modules/courses/graduation/tasks/GraduationTaskssetting.js index 57851a9dd..f90ca57f1 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduationTaskssetting.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduationTaskssetting.js @@ -374,7 +374,7 @@ class GraduationTaskssettingapp extends Component{ funcrosscomment=(e)=>{ let {latetime,end_time,allowlate,commenttime,commenttimeone}=this.state; let commenttimetype=commenttime===null||commenttime===""; -debugger + let newlatetimea=moment(new Date()).add(7, 'days').format("YYYY-MM-DD HH:mm"); let newcommenttimea=moment(new Date()).format("YYYY-MM-DD HH:mm"); @@ -388,7 +388,7 @@ debugger let newcommenttimed=moment(end_time).add(8, 'days').format("YYYY-MM-DD HH:mm"); if(e.target.checked===true){ - debugger + if(allowlate===1||allowlate===true){ if(latetime===null||latetime===""){ 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/courses/poll/PollDetailTabForth.js b/public/react/src/modules/courses/poll/PollDetailTabForth.js index f5c49f0fe..076e1dbec 100644 --- a/public/react/src/modules/courses/poll/PollDetailTabForth.js +++ b/public/react/src/modules/courses/poll/PollDetailTabForth.js @@ -111,8 +111,10 @@ class PollDetailTabForth extends Component{ } // 已有设置数据的查询 - getSettingInfo=()=>{ - this.props.newgetPollInfo(); + getSettingInfo=(type)=>{ + if(type!=1){ + this.props.newgetPollInfo(); + } let pollId=this.props.match.params.pollId; let url=`/polls/${pollId}/poll_setting.json`; axios.get(url).then((result)=>{ @@ -254,7 +256,7 @@ class PollDetailTabForth extends Component{ this.commitSetting((result)=>{ if(result.status==200){ this.props.showNotification(`${result.data.message}`); - this.getSettingInfo(); + this.getSettingInfo(1); this.setState({ flagPageEdit:false }) @@ -275,7 +277,7 @@ class PollDetailTabForth extends Component{ this.commitSetting((result)=>{ if(result.status==200){ this.props.showNotification(`${result.data.message}`); - this.getSettingInfo(); + this.getSettingInfo(1); this.setState({ flagPageEdit:false }) @@ -453,7 +455,7 @@ class PollDetailTabForth extends Component{ this.setState({ flagPageEdit:false }) - this.getSettingInfo(); + this.getSettingInfo(1); } diff --git a/public/react/src/modules/courses/poll/PollDetailTabForthRules.js b/public/react/src/modules/courses/poll/PollDetailTabForthRules.js index 8cc0adc02..f8f7b2fe2 100644 --- a/public/react/src/modules/courses/poll/PollDetailTabForthRules.js +++ b/public/react/src/modules/courses/poll/PollDetailTabForthRules.js @@ -402,7 +402,7 @@ class PollDetailTabForthRules extends Component{ } value={rule.course_group_id} onChange={(value,option)=>this.changeClasses(value,option,r)} - disabled={rule.p_timeflag===undefined?moment(rule.publish_time,dataformat) <= moment()?true:!flagPageEdit: rule.e_timeflag ===undefined?rule.publish_time===null?false:!flagPageEdit:rule.p_timeflag == true ? true : !flagPageEdit} + disabled={this.props.isAdmin()===true?rule.p_timeflag===undefined?moment(rule.publish_time,dataformat) <= moment()?true:!flagPageEdit: rule.e_timeflag ===undefined?rule.publish_time===null?false:!flagPageEdit:rule.p_timeflag == true ? true : !flagPageEdit:true} > { courseGroup && courseGroup.length > 0 && courseGroup.map((team,t)=>{ @@ -436,7 +436,7 @@ class PollDetailTabForthRules extends Component{ format="YYYY-MM-DD HH:mm" disabledTime={disabledDateTime} disabledDate={disabledDate} - disabled={ rule.p_timeflag===undefined?moment(rule.publish_time,dataformat) <= moment()?true:!flagPageEdit: rule.e_timeflag ===undefined?rule.publish_time===null?false:!flagPageEdit:rule.p_timeflag == true ? true : !flagPageEdit} + disabled={ this.props.isAdmin()===true?rule.p_timeflag===undefined?moment(rule.publish_time,dataformat) <= moment()?true:!flagPageEdit: rule.e_timeflag ===undefined?rule.publish_time===null?false:!flagPageEdit:rule.p_timeflag == true ? true : !flagPageEdit:true} style={{"height":"42px",width:'100%'}} > @@ -463,9 +463,10 @@ class PollDetailTabForthRules extends Component{ disabledTime={disabledDateTime} disabledDate={disabledDate} disabled={ + this.props.isAdmin()===true? this.props.type==="Exercise"||this.props.type==="polls"? rule.e_timeflag === undefined ? rule.publish_time === null ? false : moment(rule.end_time, dataformat) <= moment() ?this.props.isAdmin()?!flagPageEdit: true : !flagPageEdit : rule.e_timeflag == true ? this.props.isAdmin()?!flagPageEdit :true : !flagPageEdit: - rule.e_timeflag === undefined ? rule.publish_time === null ? false : moment(rule.end_time, dataformat) <= moment() ? true : !flagPageEdit : rule.e_timeflag == true ? true : !flagPageEdit + rule.e_timeflag === undefined ? rule.publish_time === null ? false : moment(rule.end_time, dataformat) <= moment() ? true : !flagPageEdit : rule.e_timeflag == true ? true : !flagPageEdit:true } style={{"height":"42px"}} > 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 4784b553a..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 11:04:44 + * @LastEditTime : 2020-01-10 15:06:23 */ import './index.scss'; // import 'katex/dist/katex.css'; diff --git a/public/react/src/modules/developer/studentStudy/leftpane/commitRecord/index.js b/public/react/src/modules/developer/studentStudy/leftpane/commitRecord/index.js index a25eec4b8..07ecdf7f3 100644 --- a/public/react/src/modules/developer/studentStudy/leftpane/commitRecord/index.js +++ b/public/react/src/modules/developer/studentStudy/leftpane/commitRecord/index.js @@ -4,7 +4,7 @@ * @Github: * @Date: 2019-11-27 09:49:33 * @LastEditors : tangjiang - * @LastEditTime : 2019-12-27 22:40:32 + * @LastEditTime : 2020-01-09 14:06:34 */ import './index.scss'; import React, { useState, useEffect } from 'react'; @@ -86,24 +86,14 @@ const CommitRecord = (props) => { // 复制面板 let clipboard; // const [recordDetail, setRecordDetail] = useState({}); - const [renderCtx, setRenderCtx] = useState(() => { - return function () { - return ''; - } - }); + // const [renderCtx, setRenderCtx] = useState(() => { + // return function () { + // return ''; + // } + // }); // 渲染提交记录详情 - const renderRecordDetail = () => { - const { - id, - // error_line, - error_msg, - // execute_memory, - // execute_time, - // input, - // output, - status, - // expected_output - } = commitRecordDetail; + const renderRecordDetail = (commitRecordDetail = {}) => { + const {id, status} = commitRecordDetail; if (Object.keys(commitRecordDetail).length > 0) { // console.log('当前状态====》》》', status); const classes = status === 0 ? 'record_result_suc' : 'record_result_err'; @@ -150,17 +140,25 @@ const CommitRecord = (props) => { // // setPagination(pageConfig); // }, [commitRecord]); // 提交详情变化时,显示当前提交信息 - useEffect(() => { - // setRecordDetail(commitRecordDetail); - if (operateType === 'submit') { - setRenderCtx(() => (renderRecordDetail)) - } - }, [commitRecordDetail, operateType]); + // useEffect(() => { + // // setRecordDetail(commitRecordDetail); + // if (operateType === 'submit') { + // setRenderCtx(() => (renderRecordDetail)) + // } + // }, [commitRecordDetail, operateType]); // 复制功能 let count = 0; - useEffect(() => { - clipboard = new ClipboardJS('#copyError'); - clipboard && clipboard.on('success', (e) => { + // useEffect(() => { + + // }, []); + + const clickCopyErrInfo = () => { + count = 0; + if (!clipboard) { + console.log('==========>>>>>>>', 11111111111); + clipboard = new ClipboardJS('#copyError'); + } + clipboard.on('success', (e) => { e.clearSelection(); if (count > 0) return; count++; @@ -169,26 +167,7 @@ const CommitRecord = (props) => { message.destroy(); }, 3000); }); - - return () => { - clipboard = null; - } - }, []); - - const clickCopyErrInfo = () => { - count = 0; } - // if (commitRecordDetail.status !== 0) { - // clipboard.on('success', (e) => { - // console.log('成功=====》》》》》'); - // message.success('复制成功'); - // e.clearSelection(); - // }); - // } - // - // const handleTableChange = (pagination) => { - // setPagination(Object.assign({}, pagination)); - // } const handlePaginationChange = (page) => { setCurrent(page); @@ -204,9 +183,53 @@ const CommitRecord = (props) => { display: pages.total > pages.limit ? 'block' : 'none' }; + const {status, id} = commitRecordDetail || {}; + const classes = status === 0 ? 'record_result_suc' : 'record_result_err'; + const showErrorCode = status !== 0 ? `ecord_error_info show_error_code` : `ecord_error_info`; + const showErrorCopy = status !== 0 ? `copy_error show_error_copy` : `copy_error`; + + // if (!clipboard) { + // console.log('==========>>>>>>>', 11111111111); + // clipboard = new ClipboardJS('#copyError'); + // } + // clipboard.on('success', (e) => { + // e.clearSelection(); + // // if (count > 0) return; + // // count++; + // message.success('复制成功'); + // setTimeout(() => { + // message.destroy(); + // }, 3000); + // }); + + // return () => { + // clipboard = null; + // } + return (
- {renderCtx()} + {renderRecordDetail(commitRecordDetail)} + {/*
+

+ 执行结果: {reviewResult[status]} +

+

+ + 复制错误信息 + +

+

+ + 显示详情 + +

+
+
+ +
*/}
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; } `} - -
{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 d7782e4cc..be0b18edb 100644 --- a/public/react/src/modules/login/Trialapplication.js +++ b/public/react/src/modules/login/Trialapplication.js @@ -8,7 +8,7 @@ import Dialog, { } from 'material-ui/Dialog'; import axios from 'axios'; import './LoginDialog.css' -import {broadcastChannelPostMessage} from 'educoder' +import {setmiyah} from 'educoder' import {Tabs, Input, Checkbox, Button, notification, Menu} from 'antd'; @@ -194,16 +194,22 @@ 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(logins) } }).then((result) => { //验证有问题{"status":1,"message":"success"} // console.log(result); - + if(result.data.status===1){ + this.props.showNotification("验证码已发送,请注意查收"); + }else if(result.data.status===-2){ + this.props.showNotification(result.data.message); + } }).catch((error) => { console.log(error); diff --git a/public/react/src/modules/login/Trialapplicationysl.js b/public/react/src/modules/login/Trialapplicationysl.js index 97064cbd4..d685e1846 100644 --- a/public/react/src/modules/login/Trialapplicationysl.js +++ b/public/react/src/modules/login/Trialapplicationysl.js @@ -8,7 +8,7 @@ import Dialog, { } from 'material-ui/Dialog'; import axios from 'axios'; -import {broadcastChannelPostMessage} from 'educoder' +import {setmiyah} from 'educoder' import {Tabs, Input, Checkbox, Button, notification, Menu} from 'antd'; @@ -210,16 +210,22 @@ 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(logins) } }).then((result) => { //验证有问题{"status":1,"message":"success"} // console.log(result); - + if(result.data.status===1){ + this.props.showNotification("验证码已发送,请注意查收"); + }else if(result.data.status===-2){ + this.props.showNotification(result.data.message); + } }).catch((error) => { console.log(error); diff --git a/public/react/src/modules/modals/Bottomsubmit.js b/public/react/src/modules/modals/Bottomsubmit.js index 670049003..16174c480 100644 --- a/public/react/src/modules/modals/Bottomsubmit.js +++ b/public/react/src/modules/modals/Bottomsubmit.js @@ -12,7 +12,6 @@ class Bottomsubmit extends Component { cannelfun = () => { // window.location.href= - debugger if(this.props.Cohetepaperbool===true){ this.props.setCohetepaperbool(false); }else { diff --git a/public/react/src/modules/paths/Index.js b/public/react/src/modules/paths/Index.js index 241dac94e..7a1c3d301 100644 --- a/public/react/src/modules/paths/Index.js +++ b/public/react/src/modules/paths/Index.js @@ -7,6 +7,7 @@ import {BrowserRouter as Router,Route,Switch} from 'react-router-dom'; import Loadable from 'react-loadable'; import Loading from '../../Loading'; import { TPMIndexHOC } from '../tpm/TPMIndexHOC'; +import NewFooter from "../tpm/NewFooter"; const PathsDetail = Loadable({ loader: () => import('./PathDetail/PathDetailIndex'), @@ -26,7 +27,6 @@ const ShixunPaths = Loadable({ loading:Loading, }) - class Index extends Component{ constructor(props) { super(props) @@ -37,14 +37,14 @@ class Index extends Component{ - ()} > - ()} > {/*编辑页面*/} - ()} > diff --git a/public/react/src/modules/paths/NewStatistics/NewStatistics.js b/public/react/src/modules/paths/NewStatistics/NewStatistics.js new file mode 100644 index 000000000..e5acd759a --- /dev/null +++ b/public/react/src/modules/paths/NewStatistics/NewStatistics.js @@ -0,0 +1,36 @@ +import React,{ Component } from "react"; +import { Skeleton ,Spin ,PageHeader} from "antd"; +class NewStatistics extends Component{ + constructor(props){ + super(props); + this.state = { + + } + } + + + render(){ + + return( +
+
+
+
+ + + +
+
+
+
+ ) + } +} + +export default NewStatistics; \ No newline at end of file diff --git a/public/react/src/modules/projectPackages/PackageIndexNewandEdit/PackageIndexNEIBannerConcent.js b/public/react/src/modules/projectPackages/PackageIndexNewandEdit/PackageIndexNEIBannerConcent.js index ac82e9ca0..562ca08ae 100644 --- a/public/react/src/modules/projectPackages/PackageIndexNewandEdit/PackageIndexNEIBannerConcent.js +++ b/public/react/src/modules/projectPackages/PackageIndexNewandEdit/PackageIndexNEIBannerConcent.js @@ -2,7 +2,7 @@ import React, {Component} from 'react'; import {Link} from "react-router-dom"; import axios from 'axios'; import { Input , Spin, Icon ,Button,Pagination,DatePicker} from 'antd'; -import { handleDateString,getUrl,bytesToSize} from 'educoder'; +import { handleDateString,getUrl,setmiyah} from 'educoder'; import locale from 'antd/lib/date-picker/locale/zh_CN'; import MDEditors from '../MDEditors'; import PhoneModel from './PhoneModel'; @@ -194,13 +194,18 @@ class PackageIndexNEIBannerConcent extends Component { params: { login: contact_phone, type: 5, + smscode:setmiyah(contact_phone) } }).then((result) => { //验证有问题{"status":1,"message":"success"} // console.log(result); - this.openNotification("验证码已发送,请注意查收!",2); - + // this.openNotification("验证码已发送,请注意查收"); + if(result.data.status===1){ + this.openNotification("验证码已发送,请注意查收"); + }else if(result.data.status===-2){ + this.openNotification(result.data.message); + } }).catch((error) => { console.log(error); diff --git a/public/react/src/modules/projectPackages/PackageIndexNewandEdit/PhoneModel.js b/public/react/src/modules/projectPackages/PackageIndexNewandEdit/PhoneModel.js index 99d63e7c2..d918111d7 100644 --- a/public/react/src/modules/projectPackages/PackageIndexNewandEdit/PhoneModel.js +++ b/public/react/src/modules/projectPackages/PackageIndexNewandEdit/PhoneModel.js @@ -71,7 +71,7 @@ class PhoneModel extends Component { // }).then((result) => { // //验证有问题{"status":1,"message":"success"} // // console.log(result); - // this.openNotification("验证码已发送,请注意查收!",2); + // this.openNotification("验证码已发送,请注意查收"); // // // }).catch((error) => { diff --git a/public/react/src/modules/question/Paperreview.js b/public/react/src/modules/question/Paperreview.js index c0660d544..b321a40a2 100644 --- a/public/react/src/modules/question/Paperreview.js +++ b/public/react/src/modules/question/Paperreview.js @@ -25,6 +25,7 @@ import Paperreview_item from "./Paperreview_item" import Bottomsubmit from "../../modules/modals/Bottomsubmit"; import Comthetestpaperst from "./comthetestpaper/Comthetestpaperst"; import NewMyShixunModel from "../question/NewMyShixunModel"; +import IntelligentModel from "../question/component/IntelligentModel" //人工组卷预览 class Paperreview extends Component { constructor(props) { @@ -52,6 +53,7 @@ class Paperreview extends Component { duration:null, newmyshixunmodelbool:false, artificialtype:"artificial", + Intelligentformation:false, } // single_questions:null, 单选题 @@ -66,26 +68,12 @@ class Paperreview extends Component { //初始化 componentDidMount() { console.log("Paperreview.js"); - console.log(this.props.match.params.type); + console.log(this.props.match.params); this.setState({ artificialtype:this.props.match.params.type }) - if(this.props.match.params.type==="artificial"){ - //人工组卷 - - var data = {} + var data = {}; this.getdata(data); - }else{ - //智能组卷 - // - var data = { - exam_setting_id:this.props.match.params.id - } - this.getdata(data); - } - - - let urls = `/disciplines.json`; axios.get(urls, { params: { @@ -148,6 +136,18 @@ class Paperreview extends Component { getdata = (data) => { + + if(this.props.match.params.type==="artificial"){ + //人工组卷 + + + }else{ + //智能组卷 + // + data = { + exam_setting_id:this.props.match.params.id + } + } const url = `/item_baskets.json`; this.setState({ booljupyterurls: true, @@ -248,7 +248,7 @@ class Paperreview extends Component { }else{ //智能组卷 - + this.setIntelligentformation(true); } @@ -274,30 +274,103 @@ class Paperreview extends Component { } setnewmyshixunmodelbool=(bool)=>{ - if(bool===true){ - let scrollToTop = window.setInterval(function() { - let pos = window.pageYOffset; - if ( pos > 0 ) { - window.scrollTo( 0, pos - 20 ); // how far to scroll on each step - } else { - window.clearInterval( scrollToTop ); + //人工组卷 + if(bool===true){ + let scrollToTop = window.setInterval(function() { + let pos = window.pageYOffset; + if ( pos > 0 ) { + window.scrollTo( 0, pos - 20 ); // how far to scroll on each step + } else { + window.clearInterval( scrollToTop ); + } + }, 2); + } + this.setState({ + newmyshixunmodelbool:bool + }) + var data = {} + this.getdata(data); + + + + + } + + //换题型 + Replacementtype=(value)=>{ + var item_types=""; + if(value==="单选题"){ + item_types="SINGLE"; + } + else if(value==="多选题"){ + item_types="MULTIPLE"; + + } + else if(value==="判断题"){ + item_types="JUDGMENT"; + + } + else if(value==="编程题"){ + item_types="PROGRAM"; + + } + const url=`/examination_intelligent_settings/${this.props.match.params.id}/exchange_items.json`; + let data={ + item_type:item_types, + } + axios.post(url, data) + .then((result) => { + if (result.data.status == 0) { + console.log(result); + var data = {} + this.getdata(data); } - }, 2); + }).catch((error) => { + console.log(error); + }) + } + //换题 + Changingtopics=(id)=>{ + const url=`/examination_intelligent_settings/${this.props.match.params.id}/exchange_one_item.json`; + let data={ + item_id:id, } + axios.post(url, data) + .then((result) => { + if (result.data.status == 0) { + console.log(result); + var data = {} + this.getdata(data); + } + }).catch((error) => { + console.log(error); + }) + } + + setIntelligentformation=(bool)=>{ this.setState({ - newmyshixunmodelbool:bool + Intelligentformation:bool }) - var data = {} - this.getdata(data); + } + Confirmationofvolumeformations=()=>{ + this.setState({ + Intelligentformation:false + }) + } render() { - let {page, limit, count, Headertop, visible, placement, modalsType, item_type,artificialtype,Cohetepaperbool,newmyshixunmodelbool} = this.state; + let {page, limit, count, Headertop, visible, placement, modalsType, item_type,artificialtype,Cohetepaperbool,newmyshixunmodelbool,Intelligentformation} = this.state; const params = this.props && this.props.match && this.props.match.params; // //console.log(params); return (
+ { + Intelligentformation===true? + this.getdata(data)} {...this.state} {...this.props} exam_id={this.props.match.params.id} Confirmationofvolumeformations={()=>this.Confirmationofvolumeformations()}> + :"" + } { newmyshixunmodelbool===true? +
+ +
+ + {getFieldDecorator('classroom', { + rules: [{required: true, message: "不能为空"}], + })( + + + + + )} +
+
+
+ +
+ +
+ + + {getFieldDecorator('kssc')()} + 分钟 + +
+ + + +
提示:组卷完成后,在试卷库—我的试卷库查看!
+ +
+ +
+ this.props.Confirmationofvolumeformations()}>取消 + + +
+ + ) + } +} + +const IntelligentModels = Form.create({name: 'IntelligentModel'})(IntelligentModel); +export default IntelligentModels; diff --git a/public/react/src/modules/question/component/Itembankstop.js b/public/react/src/modules/question/component/Itembankstop.js index 4b3cfa0f6..5a2fc7b9c 100644 --- a/public/react/src/modules/question/component/Itembankstop.js +++ b/public/react/src/modules/question/component/Itembankstop.js @@ -200,7 +200,7 @@ class Itembankstop extends Component { this.handleFormtixing(this.props.item_banksedit.item_type); } if (this.props.item_banksedit.difficulty) { - this.handleFormLayoutChange(this.props.item_banksedit.difficulty); + this.handleFormLayoutChangeysl(this.props.item_banksedit.difficulty); } if (this.props.item_banksedit.tag_disciplines) { this.handletag_disciplinesChange(this.props.item_banksedit.tag_disciplines); @@ -366,7 +366,18 @@ class Itembankstop extends Component { }); } + handleFormLayoutChangeysl = (value) => { + //难度塞选 + ////console.log("难度塞选"); + ////console.log(value); + this.props.form.setFieldsValue({ + rbnd: value+ "", + }); + this.setState({ + rbnd: value + "", + }) + } handleFormLayoutChange = (e) => { //难度塞选 ////console.log("难度塞选"); diff --git a/public/react/src/modules/question/component/Listjihe.js b/public/react/src/modules/question/component/Listjihe.js index 695fe77fd..408575053 100644 --- a/public/react/src/modules/question/component/Listjihe.js +++ b/public/react/src/modules/question/component/Listjihe.js @@ -135,6 +135,23 @@ class Listjihe extends Component { itemssname=items.name } + + var itemsnamesy=""; + try { + itemsnamesy= JSON.parse(items&&items.program_attr&&items.program_attr.description); + + }catch (e) { + itemsnamesy=items&&items.program_attr&&items.program_attr.description; + } + + var analysisnames=""; + try { + analysisnames= JSON.parse(items&&items.analysis); + + }catch (e) { + analysisnames=items&&items.analysis; + } + return (
@@ -217,7 +234,7 @@ class Listjihe extends Component { >

@@ -232,6 +249,12 @@ class Listjihe extends Component {

{ items === undefined || items === null ? "" : items.choices.map((object, index) => { + var string="" + try { + string=JSON.parse(object.choice_text); + }catch (e) { + string=object.choice_text; + } return (

{tagArray[index]}

@@ -244,7 +267,7 @@ class Listjihe extends Component { object.choice_text.length>0? :"" @@ -425,7 +448,7 @@ class Listjihe extends Component { : "" diff --git a/public/react/src/modules/question/component/SingleEditor.js b/public/react/src/modules/question/component/SingleEditor.js index 36f9bc93a..899c5c197 100644 --- a/public/react/src/modules/question/component/SingleEditor.js +++ b/public/react/src/modules/question/component/SingleEditor.js @@ -421,7 +421,7 @@ class SingleEditor extends Component{ { item===undefined||item===null||item===""? :
{ + //难度塞选 + ////console.log("难度塞选"); + ////console.log(value); + this.props.form.setFieldsValue({ + rbnd: value + "", + }); + this.setState({ + rbnd: value + "", + }) + + } handleFormLayoutChange = (e) => { //难度塞选 ////console.log("难度塞选"); ////console.log(value); + this.props.form.setFieldsValue({ rbnd: e.target.value + "", }); @@ -761,7 +776,7 @@ class Comthetestpaperst extends Component { className={"fl construction yslzxueshis "} dataSource={optionss} > - + )}
diff --git a/public/react/src/modules/question/comthetestpaper/Intelligentcomponents.js b/public/react/src/modules/question/comthetestpaper/Intelligentcomponents.js index c40961dbb..43deace7d 100644 --- a/public/react/src/modules/question/comthetestpaper/Intelligentcomponents.js +++ b/public/react/src/modules/question/comthetestpaper/Intelligentcomponents.js @@ -229,6 +229,12 @@ class Intelligentcomponents extends Component { rbly: e.target.value + "", }) + try { + this.props.getdatassssy(e.target.value); + }catch (e) { + + } + } handleFormLayoutChange = (e) => { // console.log("handleFormLayoutChange"); @@ -280,6 +286,12 @@ class Intelligentcomponents extends Component { knowledgepoints2: _result, }) + try { + this.props.getdatassss(this.state.Knowpoints); + }catch (e) { + + } + } handleFormzhishidian = (value) => { @@ -334,6 +346,12 @@ class Intelligentcomponents extends Component { this.setState({ rbzsd: undefined, }) + + try { + this.props.getdatasss(parseInt(value[1])); + }catch (e) { + + } } handleFormtixing = (value) => { @@ -353,7 +371,7 @@ class Intelligentcomponents extends Component { ////console.log('Clicked! But prevent default.'); } deletesobject = (item, index) => { - debugger + var tmp = this.state.Knowpoints; for (var i = 0; i < tmp.length; i++) { if (i ===index) { @@ -390,6 +408,12 @@ class Intelligentcomponents extends Component { } } + //删除知识点 + try { + this.props.getdatassss(this.state.Knowpoints); + }catch (e) { + + } } @@ -476,7 +500,12 @@ class Intelligentcomponents extends Component { }).catch((error) => { //console.log(error); }) + //新增知识点 + try { + this.getdatassss(this.state.Knowpoints); + }catch (e) { + } this.setState({ NewknTypedel:false }) @@ -764,21 +793,29 @@ class Intelligentcomponents extends Component { -

题型及数量

-
- this.props.getdatas()} ref={dom => { - this.$dxt = dom; - }}> - this.props.getdatas()} ref={dom => { - this.$ddxt = dom; - }}> - this.props.getdatas()} ref={dom => { - this.$pdt = dom; - }}> - this.props.getdatas()} ref={dom => { - this.$bct = dom; - }}> + { + this.props.single_question_count===0&&this.props.multiple_question_count===0&&this.props.judgement_question_count===0&& + this.props.program_question_count===0? + "" + : +
+

题型及数量

+
+ this.props.getdatas()} ref={dom => { + this.$dxt = dom; + }}> + this.props.getdatas()} ref={dom => { + this.$ddxt = dom; + }}> + this.props.getdatas()} ref={dom => { + this.$pdt = dom; + }}> + this.props.getdatas()} ref={dom => { + this.$bct = dom; + }}> +
+ }
diff --git a/public/react/src/modules/question/questioncss/questioncom.css b/public/react/src/modules/question/questioncss/questioncom.css index ae405001a..e69162010 100644 --- a/public/react/src/modules/question/questioncss/questioncom.css +++ b/public/react/src/modules/question/questioncss/questioncom.css @@ -760,6 +760,17 @@ font-size:12px; } +.szdfds{ + width:100px; + height:40px; + background:#FC7E30; + border-radius:4px 4px 0px 0px; + text-align: center; + color: #ffffff; + line-height: 40px; + margin-right: 27px; + font-size:12px; +} .pd20{ padding: 20px; @@ -1022,3 +1033,32 @@ .mr12{ margin-right: 12px; } +.tishiyuyan{ + color: #888888 !important; + font-size:14px; +} +.tishiyuyans{ + color: #4CACFF !important; + font-size:14px; +} +.tikutask-btn{ + width:80px; + height:34px; + background:rgba(204,204,204,1); + border-radius:4px; +} +.tikutask-btns{ + width:80px; + height:34px; + background:rgba(76,172,255,1); + border-radius:4px; +} +.w100{ + width: 100px !important; +} +.h34{ + height: 34px !important; +} +.lh34{ + line-height: 34px !important; +} diff --git a/public/react/src/modules/testpaper/Intecomponents.js b/public/react/src/modules/testpaper/Intecomponents.js index 4328cb400..a69d7185b 100644 --- a/public/react/src/modules/testpaper/Intecomponents.js +++ b/public/react/src/modules/testpaper/Intecomponents.js @@ -110,6 +110,7 @@ class Intecomponents extends Component { } + //难度 getdatas=()=>{ if (this.Judquestio.Getdatas().length === 0) { this.scrollToAnchor("Itembankstopid"); @@ -129,27 +130,96 @@ class Intecomponents extends Component { difficulty:this.Judquestio.Getdatas()[0].rbnd, } - axios.get(url, {params: { - data - }}).then((response) => { - if (response) { - console.log("智能组卷"); - console.log(response); - if(response.data){ - this.setState({ - single_question_count:response.data.single_question_count, - multiple_question_count:response.data.multiple_question_count, - judgement_question_count:response.data.judgement_question_count, - program_question_count:response.data.program_question_count, - }) - - } - - } - }); + this.getwangluodata(url,data); } + //课程 + getdatasss=(kech)=>{ + if (this.Judquestio.Getdatas().length === 0) { + this.scrollToAnchor("Itembankstopid"); + return false; + } + console.log(this.Judquestio.Getdatas()); + var myrbkc=[]; + var Getdatasdatas=this.Judquestio.Getdatas()[1].rbzsd; + for(let myda of Getdatasdatas) { + myrbkc.push(myda.id); + } + const url="/examination_intelligent_settings/optinal_items.json"; + var data={ + sub_discipline_id:kech, + tag_discipline_id:myrbkc, + source:this.Judquestio.Getdatas()[7].rbly, + difficulty:this.Judquestio.Getdatas()[0].rbnd, + } + + this.getwangluodata(url,data); + + } + //知识点 + getdatassss=(zhishidian)=>{ + if (this.Judquestio.Getdatas().length === 0) { + this.scrollToAnchor("Itembankstopid"); + return false; + } + console.log(this.Judquestio.Getdatas()); + var myrbkc=[]; + var Getdatasdatas=zhishidian; + for(let myda of Getdatasdatas) { + myrbkc.push(myda.id); + } + const url="/examination_intelligent_settings/optinal_items.json"; + var data={ + sub_discipline_id:this.Judquestio.Getdatas()[2].rbkc[1], + tag_discipline_id:myrbkc, + source:this.Judquestio.Getdatas()[7].rbly, + difficulty:this.Judquestio.Getdatas()[0].rbnd, + } + this.getwangluodata(url,data); + } + //来源 + getdatassssy=(rbly)=>{ + if (this.Judquestio.Getdatas().length === 0) { + this.scrollToAnchor("Itembankstopid"); + return false; + } + console.log(this.Judquestio.Getdatas()); + var myrbkc=[]; + var Getdatasdatas=this.Judquestio.Getdatas()[1].rbzsd; + for(let myda of Getdatasdatas) { + myrbkc.push(myda.id); + } + const url="/examination_intelligent_settings/optinal_items.json"; + var data={ + sub_discipline_id:this.Judquestio.Getdatas()[2].rbkc[1], + tag_discipline_id:myrbkc, + source:rbly, + difficulty:this.Judquestio.Getdatas()[0].rbnd, + } + this.getwangluodata(url,data); + } + + + getwangluodata=(url,data)=>{ + axios.post(url,data).then((response) => { + if (response) { + console.log("智能组卷"); + console.log(response); + if(response.data){ + this.setState({ + single_question_count:response.data.single_question_count, + multiple_question_count:response.data.multiple_question_count, + judgement_question_count:response.data.judgement_question_count, + program_question_count:response.data.program_question_count, + }) + + } + + } + }); + } + //难度 getdatass=(nandu)=>{ if (this.Judquestio.Getdatas().length === 0) { this.scrollToAnchor("Itembankstopid"); @@ -259,7 +329,7 @@ class Intecomponents extends Component { .then((result) => { if (result.data.status == 0) { console.log("组卷成功"); - this.props.history.push(`/IntegenerationSee/Intelligence/${result.data.exam_setting_id}`); + this.props.history.push(`/Integeneration/Intelligence/${result.data.exam_setting_id}`); } }).catch((error) => { console.log(error); @@ -315,7 +385,10 @@ class Intecomponents extends Component { program_question_count={this.state.program_question_count} getdatas={()=>this.getdatas()} getdatass={(nd)=>this.getdatass(nd)} - getJudquestio={(ref) => this.getJudquestio(ref)} + getJudquestio={(ref) => this.getJudquestio(ref)} + getdatasss={(e)=>this.getdatasss(e)} + getdatassss={(e)=>this.getdatassss(e)} + getdatassssy={(e)=>this.getdatassssy(e)} > @@ -328,6 +401,7 @@ class Intecomponents extends Component { { newmyshixunmodelbool === true ? "" : this.setCohetepaperbool(bool)} onSubmits={() => this.preservation()} url={'/paperlibrary'}> } diff --git a/public/react/src/modules/testpaper/component/Paperlibraryseeid_items.js b/public/react/src/modules/testpaper/component/Paperlibraryseeid_items.js index 0a6a718c3..7747574dd 100644 --- a/public/react/src/modules/testpaper/component/Paperlibraryseeid_items.js +++ b/public/react/src/modules/testpaper/component/Paperlibraryseeid_items.js @@ -78,6 +78,14 @@ class Paperlibraryseeid_items extends Component { if(itemssname===undefined){ itemssname=objectsingle.name } + + var itemsnamesy=""; + try { + itemsnamesy= JSON.parse(objectsingle&&objectsingle.program_attr&&objectsingle.program_attr.description); + + }catch (e) { + itemsnamesy=objectsingle&&objectsingle.program_attr&&objectsingle.program_attr.description; + } return (

: @@ -196,6 +204,12 @@ class Paperlibraryseeid_items extends Component {

{ objectsingle === undefined || objectsingle === null ? "" : objectsingle.choices.map((object, index) => { + var string="" + try { + string=JSON.parse(object.choice_text); + }catch (e) { + string=object.choice_text; + } return (

{tagArray[index]} @@ -207,7 +221,7 @@ class Paperlibraryseeid_items extends Component { object.choice_text.length>0? :"" : diff --git a/public/react/src/modules/tpm/NewHeader.js b/public/react/src/modules/tpm/NewHeader.js index 71b597747..419e82d21 100644 --- a/public/react/src/modules/tpm/NewHeader.js +++ b/public/react/src/modules/tpm/NewHeader.js @@ -656,11 +656,12 @@ submittojoinclass=(value)=>{ } - + if(type==="newshixuns"){ if(this.props&&this.props.current_user&&this.props.current_user.is_shixun_marker===false){ - this.setgoshowqqgtounp(true); - return; - } + this.setgoshowqqgtounp(true); + return; + } + } @@ -1294,7 +1295,7 @@ submittojoinclass=(value)=>{

  • this.getUser("/courses/new")}>{this.props.user&&this.props.user.main_site===false?"新建课堂":"新建翻转课堂"}
  • :"" } {shixuntype===true?"": -
  • this.getUser("/shixuns/new")}>新建实训项目
  • +
  • this.getUser("/shixuns/new","newshixuns")}>新建实训项目
  • } {this.props.user&&this.props.user.main_site===false?"":this.props.Headertop===undefined?"":
  • this.getUser("/paths/new")} >新建实践课程
  • } {this.props.user&&this.props.user.main_site===true?"":this.props.Headertop===undefined?"": diff --git a/public/react/src/modules/tpm/TPMIndexHOC.js b/public/react/src/modules/tpm/TPMIndexHOC.js index f46835959..363acdba1 100644 --- a/public/react/src/modules/tpm/TPMIndexHOC.js +++ b/public/react/src/modules/tpm/TPMIndexHOC.js @@ -35,14 +35,14 @@ if (!window['indexHOCLoaded']) { // $('head').append($('') // .attr('href', `${_url_origin}/stylesheets/educoder/antd.min.css?1525440977`)); $('head').append($('') - .attr('href', `${_url_origin}/stylesheets/css/edu-common.css?2021`)); + .attr('href', `${_url_origin}/stylesheets/css/edu-common.css?2`)); $('head').append($('') - .attr('href', `${_url_origin}/stylesheets/educoder/edu-main.css?2021`)); + .attr('href', `${_url_origin}/stylesheets/educoder/edu-main.css?2`)); // index.html有加载 $('head').append($('') - .attr('href', `${_url_origin}/stylesheets/educoder/edu-all.css?2021`)); + .attr('href', `${_url_origin}/stylesheets/educoder/edu-all.css?2`)); // $('head').append($('') @@ -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/TPMsettings/Configuration.js b/public/react/src/modules/tpm/TPMsettings/Configuration.js index f48314261..b3a0e6b64 100644 --- a/public/react/src/modules/tpm/TPMsettings/Configuration.js +++ b/public/react/src/modules/tpm/TPMsettings/Configuration.js @@ -66,7 +66,8 @@ export default class Shixuninformation extends Component { scope_partment: [], loading: false, opening_timetype:false, - use_scope_type:false + use_scope_type:false, + scope_partmenttype:false } } @@ -150,6 +151,16 @@ export default class Shixuninformation extends Component { return } } + if(use_scope===1){ + if(oldscope_partment.length===0){ + this.setState({ + scope_partmenttype:true + }) + this.props.showNotification("请选择指定单位公开") + return + } + } + let list=[] scope_partment.map((item,key)=>{ list.push(item) @@ -231,7 +242,8 @@ export default class Shixuninformation extends Component { if (scopetype === false) { datalist.push(e) this.setState({ - scope_partment: datalist + scope_partment: datalist, + scope_partmenttype:false }); } else { this.props.showNotification("请勿指定相同的单位") @@ -297,7 +309,7 @@ export default class Shixuninformation extends Component { const dateFormat = 'YYYY-MM-DD HH:mm'; // console.log() - console.log(this.props&&this.props.identity<8) + return (
    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 e95ea2b7f..baf099909 100644 --- a/public/react/src/modules/user/FindPasswordComponent.js +++ b/public/react/src/modules/user/FindPasswordComponent.js @@ -2,7 +2,7 @@ import React, {Component} from 'react'; import {BrowserRouter as Router, Route, Link, Switch} from "react-router-dom"; -import {getImageUrl} from 'educoder'; +import {setmiyah} from 'educoder'; import CheckInputysl1 from './CheckInputysl'; import CheckInputysl2 from './CheckInputysl'; import {Tabs, Input, Checkbox, Button, notification} from 'antd'; @@ -157,16 +157,22 @@ 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(logins) } }).then((result) => { //验证有问题{"status":1,"message":"success"} - this.openNotification("验证码已发送,请注意查收!",2); - + // this.openNotification("验证码已发送,请注意查收"); + if(result.data.status===1){ + this.openNotification("验证码已发送,请注意查收"); + }else if(result.data.status===-2){ + this.openNotification(result.data.message); + } }).catch((error) => { console.log(error); diff --git a/public/react/src/modules/user/LoginRegisterComponent.js b/public/react/src/modules/user/LoginRegisterComponent.js index 1fbfe4e35..d00d54371 100644 --- a/public/react/src/modules/user/LoginRegisterComponent.js +++ b/public/react/src/modules/user/LoginRegisterComponent.js @@ -1,8 +1,5 @@ import React, {Component} from 'react'; - -import {BrowserRouter as Router, Route, Link, Switch} from "react-router-dom"; - -import {getImageUrl,broadcastChannelPostMessage} from 'educoder'; +import {setmiyah,broadcastChannelPostMessage} from 'educoder'; import {Tabs, Input, Checkbox, Button, notification,Menu} from 'antd'; import passopen from '../../../src/images/login/passopen.png'; import passoff from '../../../src/images/login/passoff.png'; @@ -184,7 +181,7 @@ class LoginRegisterComponent extends Component { message: "提示", description: messge, onClick: () => { - console.log('Notification Clicked12312313123!'); + }, }); } @@ -217,7 +214,7 @@ class LoginRegisterComponent extends Component { } } onTabChange = (activeKey) => { - console.log("onTabChange"); + } // -------------------- LOGIN START //下次自动登入 @@ -229,7 +226,7 @@ class LoginRegisterComponent extends Component { isCorrectname = (value, id) => { if (id === 1) { - console.log(value.length); + if (value.length === 0) { this.setState({ Phonenumberisnotco: undefined, @@ -265,7 +262,7 @@ class LoginRegisterComponent extends Component { dragOk:false, Whethertoverify:this.state.Whethertoverify===true?false:true, }) - console.log("s0"); + return; } @@ -283,7 +280,7 @@ class LoginRegisterComponent extends Component { Phonenumberisnotcobool: false, dragOk:true, }) - console.log("s1"); + } else { this.setState({ Phonenumberisnotcos: undefined, @@ -307,11 +304,11 @@ class LoginRegisterComponent extends Component { dragOk:false, Whethertoverify:this.state.Whethertoverify===true?false:true, }); - console.log("s2"); + return } else { - console.log("s222222"); + this.setState({ Phonenumberisnotcos: undefined, Phonenumberisnotcobool: false, @@ -571,7 +568,7 @@ class LoginRegisterComponent extends Component { dragOk:false, Whethertoverify:this.state.Whethertoverify===true?false:true, }) - console.log("s5"); + } return; @@ -582,7 +579,7 @@ class LoginRegisterComponent extends Component { dragOk:false, Whethertoverify:this.state.Whethertoverify===true?false:true, }) - console.log("s6"); + return; } @@ -611,26 +608,30 @@ 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(logins) } }).then((result) => { //验证有问题{"status":1,"message":"success"} // console.log(result); - this.openNotification("验证码已发送,请注意查收!",2); - - + if(result.data.status===1){ + this.openNotification("验证码已发送,请注意查收"); + }else if(result.data.status===-2){ + this.openNotification(result.data.message); + } }).catch((error) => { - console.log(error); + }) } //显示和不显示密码 Showandhide = (e) => { - console.log("显示于隐藏"); + if (this.state.classpassbool === true) { this.setState({ passopens:passoff , @@ -649,7 +650,6 @@ class LoginRegisterComponent extends Component { //倒计时 getverificationcode = () => { - debugger // console.log(this.state.Phonenumberisnotcobool); // console.log(this.state.dragOk); if(this.state.logins === undefined || this.state.logins.length===0){ @@ -666,7 +666,7 @@ class LoginRegisterComponent extends Component { } if(this.state.pciphone===true) { if (this.state.dragOk === false) { - this.openNotification("拖动滑块验证"); + this.openNotification("请拖动滑块验证"); return; } } @@ -821,7 +821,7 @@ class LoginRegisterComponent extends Component { } //获取注册登入 loginInputonChanges = (e) => { - console.log(e.target.value); + var stirngt; if(e.target.value.length>0){ var str= e.target.value.replace(/\s*/g,"") @@ -874,7 +874,7 @@ class LoginRegisterComponent extends Component { this.setState({ tab:e.key }) - console.log(e.key); + if(e.key === 0){ this.setState({ Phonenumberisnotcos:undefined diff --git a/public/react/src/modules/user/account/AccountSecure.js b/public/react/src/modules/user/account/AccountSecure.js index 2e90824c9..07905b3a5 100644 --- a/public/react/src/modules/user/account/AccountSecure.js +++ b/public/react/src/modules/user/account/AccountSecure.js @@ -1,6 +1,6 @@ import React, { Component } from 'react'; -import { SnackbarHOC, getImageUrl, WordsBtn } from 'educoder'; +import { SnackbarHOC, setmiyah, WordsBtn } from 'educoder'; import { Form, Button, Input } from 'antd' import '../../courses/css/Courses.css' @@ -59,6 +59,7 @@ class AccountSecure extends Component { let url=`/accounts/get_verification_code.json` let login = ''; let values=this.props.form.getFieldsValue(); + if(index == 3){ //绑定手机号码 login=values.phone; @@ -81,11 +82,17 @@ class AccountSecure extends Component { this.props.showNotification(`请先输入${index==3?"手机号码":"邮箱地址"}`); return; } + let smscode=setmiyah(login) axios.get((url),{params:{ - login,type + login,type,smscode }}).then((result)=>{ if(result){ // 倒计时 + if(result.data.status===1){ + this.props.showNotification("验证码已发送,请注意查收"); + }else if(result.data.status===-2){ + this.props.showNotification(result.data.message); + } this.setState({ secondsFlag:true }) diff --git a/public/react/src/redux/actions/ojForUser.js b/public/react/src/redux/actions/ojForUser.js index abe323808..e7520c533 100644 --- a/public/react/src/redux/actions/ojForUser.js +++ b/public/react/src/redux/actions/ojForUser.js @@ -4,7 +4,7 @@ * @Github: * @Date: 2019-11-27 13:42:11 * @LastEditors : tangjiang - * @LastEditTime : 2020-01-07 17:27:40 + * @LastEditTime : 2020-01-09 14:14:47 */ import types from "./actionTypes"; import { Base64 } from 'js-base64'; @@ -207,7 +207,8 @@ export const codeEvaluate = (dispatch, identifier, type, time_limit, hackStatus, input: '', output: '', status: 2, - expected_output: '' + expected_output: '', + isPassed: false }; } else { // 成功返回结果 returnData = res.data.data; @@ -246,7 +247,7 @@ export const codeEvaluate = (dispatch, identifier, type, time_limit, hackStatus, dispatch(saveOpacityType(type)); // 首次通过时,提示评测通过并获得金币 // console.log('hack status ===>>', hackStatus); - if (hackStatus === 1 && !passed) { + if (hackStatus === 1 && !passed && returnData.isPassed) { dispatch({ type: types.UPDATE_HACK_PASSED, payload: true 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