diff --git a/README.md b/README.md index 8dcb6d131..90f519de4 100644 --- a/README.md +++ b/README.md @@ -1,69 +1,70 @@ -# README - -This README would normally document whatever steps are necessary to get the -application up and running. - -Things you may want to cover: - -* Ruby version - -* System dependencies - -* Configuration - -* Database creation - -* Database initialization - -* How to run the test suite - -* Services (job queues, cache servers, search engines, etc.) - -* Deployment instructions - -* ... -#### Jbuilder介绍 -Jbuilder: https://github.com/rails/jbuilder - -#### Rails5 介绍 -rails guide: https://ruby-china.github.io/rails-guides/v5.0/ - -#### API设计文档 -doc for api: https://www.showdoc.cc/web/#/127895880302646?page_id=729221359592009 -user:Hjqreturn PW:12345678 - -#### 测试版访问地址:https://testeduplus2.educoder.net - -#### 实训平台繁忙 - 仓库异常:繁忙等级(81) - -#### 新版域名跳转规则 -新版域名要求总结:testeduplus2.educoder.net/(主要提供实训、实训课堂等业务) -目前有两个域名testbdweb.educoder.net(老版:主要提供课堂、项目、个人主页、后台等服务) - -要求: -1、两服务域名都应该启动‘提供服务 - -2、如果请求链接包含以下的形式,则域名跳至testeduplus2.educoder.net -testeduplus2.educoder.net/shixuns -testeduplus2.educoder.net/shixuns/* -testeduplus2.educoder.net/paths -testeduplus2.educoder.net/paths/* -testeduplus2.educoder.net/myshixuns/ -testeduplus2.educoder.net/tasks/* -testeduplus2.educoder.net/games/* - -如果不满足上述需求的,域名全部跳转至testbdweb.educoder.net -比如:门户首页,如果访问:testeduplus2.educoder.net 应为没包含上述链接。则调制testbdweb.educoder.net -在比如:testeduplus2.educoder.net /users/Hjqreturn没包含上述规则,则跳转到testbdweb.educoder.net/users/Hjqreturn - - -# 需要重构user_extensions 相关sql语句的地方标记 REDO:Extention - -# 文件上传:ActiveStorage -# 新能:bootsnap - -# 注意事项: -# 第一次部署需要执行一些rake任务 -# 配置redis地址 +# README +https://www.trustie.net/issues/24719 +[云上实验室] Logo、导航、底部备案信息定制化 +This README would normally document whatever steps are necessary to get the +application up and running. + +Things you may want to cover: + +* Ruby version + +* System dependencies + +* Configuration + +* Database creation + +* Database initialization + +* How to run the test suite + +* Services (job queues, cache servers, search engines, etc.) + +* Deployment instructions + +* ... +#### Jbuilder介绍 +Jbuilder: https://github.com/rails/jbuilder + +#### Rails5 介绍 +rails guide: https://ruby-china.github.io/rails-guides/v5.0/ + +#### API设计文档 +doc for api: https://www.showdoc.cc/web/#/127895880302646?page_id=729221359592009 +user:Hjqreturn PW:12345678 + +#### 测试版访问地址:https://testeduplus2.educoder.net + +#### 实训平台繁忙 + 仓库异常:繁忙等级(81) + +#### 新版域名跳转规则 +新版域名要求总结:testeduplus2.educoder.net/(主要提供实训、实训课堂等业务) +目前有两个域名testbdweb.educoder.net(老版:主要提供课堂、项目、个人主页、后台等服务) + +要求: +1、两服务域名都应该启动‘提供服务 + +2、如果请求链接包含以下的形式,则域名跳至testeduplus2.educoder.net +testeduplus2.educoder.net/shixuns +testeduplus2.educoder.net/shixuns/* +testeduplus2.educoder.net/paths +testeduplus2.educoder.net/paths/* +testeduplus2.educoder.net/myshixuns/ +testeduplus2.educoder.net/tasks/* +testeduplus2.educoder.net/games/* + +如果不满足上述需求的,域名全部跳转至testbdweb.educoder.net +比如:门户首页,如果访问:testeduplus2.educoder.net 应为没包含上述链接。则调制testbdweb.educoder.net +在比如:testeduplus2.educoder.net /users/Hjqreturn没包含上述规则,则跳转到testbdweb.educoder.net/users/Hjqreturn + + +# 需要重构user_extensions 相关sql语句的地方标记 REDO:Extention + +# 文件上传:ActiveStorage +# 新能:bootsnap + +# 注意事项: +# 第一次部署需要执行一些rake任务 +# 配置redis地址 # 配置gitlab/intializers/gitlab_config.yml \ No newline at end of file diff --git a/app/controllers/admins/competition_settings_controller.rb b/app/controllers/admins/competition_settings_controller.rb new file mode 100644 index 000000000..390ad17e8 --- /dev/null +++ b/app/controllers/admins/competition_settings_controller.rb @@ -0,0 +1,20 @@ +class Admins::CompetitionSettingsController < Admins::BaseController + def show + @competition = current_competition + end + + def update + Admins::SaveLaboratorySettingService.call(current_competition, form_params) + render_ok + end + + private + + def current_competition + @_current_competition ||= Competition.find(params[:competition_id]) + end + + def form_params + params.permit(:identifier, :name, :nav_logo, :login_logo, :tab_logo, :footer, navbar: %i[name link hidden]) + end +end \ No newline at end of file diff --git a/app/controllers/admins/competitions_controller.rb b/app/controllers/admins/competitions_controller.rb new file mode 100644 index 000000000..3b9b63243 --- /dev/null +++ b/app/controllers/admins/competitions_controller.rb @@ -0,0 +1,46 @@ +class Admins::CompetitionsController < Admins::BaseController + include CustomSortable + before_action :find_competition, except: [:index] + + def index + params[:sort_by] = params[:sort_by].presence || 'created_on' + params[:sort_direction] = params[:sort_direction].presence || 'desc' + @competitions = custom_sort Competition.all, params[:sort_by], params[:sort_direction] + @params_page = params[:page] || 1 + @competitions = paginate @competitions + ids = @competitions.map(&:id) + @member_count_map = TeamMember.where(competition_id: ids).group(:competition_id).count + + respond_to do |format| + format.js + format.html + end + end + + def publish + @competition.update_attributes!(:published_at, Time.now) + end + + def unpublish + @competition.update_attributes!(:published_at, nil) + end + + def online_switch + if @competition.status + @competition.update_attributes!(status: false) + else + @competition.update_attributes!(status: true, online_time: Time.now) + end + end + + def enroll_list + + end + + private + + def find_competition + @competition = Competition.find_by(id: params[:id]) + end + +end \ No newline at end of file diff --git a/app/controllers/bind_users_controller.rb b/app/controllers/bind_users_controller.rb index 530aa9b73..354b2993b 100644 --- a/app/controllers/bind_users_controller.rb +++ b/app/controllers/bind_users_controller.rb @@ -17,6 +17,6 @@ class BindUsersController < ApplicationController private def create_params - params.permit(:login, :password, :type, :not_bind) + params.permit(:username, :password, :type, :not_bind) end end \ No newline at end of file diff --git a/app/controllers/boards_controller.rb b/app/controllers/boards_controller.rb index 1081a82ce..2bcc8d8f6 100644 --- a/app/controllers/boards_controller.rb +++ b/app/controllers/boards_controller.rb @@ -2,7 +2,7 @@ class BoardsController < ApplicationController before_action :require_login, :check_auth before_action :find_course, only: [:create] before_action :set_board, except: [:create] - before_action :teacher_or_admin_allowed + before_action :teacher_allowed def index @boards = @course.boards.includes(messages: [:last_reply, :author]) diff --git a/app/controllers/course_groups_controller.rb b/app/controllers/course_groups_controller.rb index 0e16d1bac..bfdb959b4 100644 --- a/app/controllers/course_groups_controller.rb +++ b/app/controllers/course_groups_controller.rb @@ -2,7 +2,7 @@ class CourseGroupsController < ApplicationController before_action :require_login, :check_auth before_action :set_group, except: [:create] before_action :find_course, only: [:create] - before_action :teacher_or_admin_allowed + before_action :teacher_allowed def create tip_exception("分班名称不能为空") if params[:name].blank? diff --git a/app/controllers/course_modules_controller.rb b/app/controllers/course_modules_controller.rb index 6e8afd525..0bef519fd 100644 --- a/app/controllers/course_modules_controller.rb +++ b/app/controllers/course_modules_controller.rb @@ -2,7 +2,8 @@ class CourseModulesController < ApplicationController before_action :require_login, :check_auth before_action :set_module, except: [:unhidden_modules] before_action :find_course, only: [:unhidden_modules] - before_action :teacher_or_admin_allowed + before_action :teacher_or_admin_allowed, except: [:add_second_category] + before_action :teacher_allowed, only: [:add_second_category] # 模块置顶 def sticky_module @@ -48,9 +49,9 @@ class CourseModulesController < ApplicationController tip_exception("已存在同名子目录") if @course_module.course_second_categories.exists?(name: params[:name].strip) ActiveRecord::Base.transaction do begin - @course_module.course_second_categories.create!(name: params[:name].strip, category_type: @course_module.module_type, + category = @course_module.course_second_categories.create!(name: params[:name].strip, category_type: @course_module.module_type, course_id: @course.id, position: @course_module.course_second_categories.count + 1) - normal_status(0, "添加成功") + render :json => {category_id: category.id, status: 0, message: "添加成功"} rescue Exception => e uid_logger_error(e.message) tip_exception("添加子目录失败") diff --git a/app/controllers/course_second_categories_controller.rb b/app/controllers/course_second_categories_controller.rb index e5c3366cd..2de1637f2 100644 --- a/app/controllers/course_second_categories_controller.rb +++ b/app/controllers/course_second_categories_controller.rb @@ -1,7 +1,7 @@ class CourseSecondCategoriesController < ApplicationController before_action :require_login, :check_auth before_action :set_category - before_action :teacher_or_admin_allowed + before_action :teacher_allowed # 目录重命名 def rename_category diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb index 0c643d15c..0b3e35519 100644 --- a/app/controllers/courses_controller.rb +++ b/app/controllers/courses_controller.rb @@ -35,7 +35,7 @@ class CoursesController < ApplicationController :transfer_to_course_group, :delete_from_course, :export_member_scores_excel, :search_users, :add_students_by_search, :get_historical_courses, :add_teacher_popup, :add_teacher, :export_couser_info, :export_member_act_score, - :update_informs, :new_informs, :delete_informs] + :update_informs, :new_informs, :delete_informs, :switch_to_student] before_action :admin_allowed, only: [:set_invite_code_halt, :set_public_or_private, :change_course_admin, :set_course_group, :create_group_by_importing_file, :update_task_position, :tasks_list] @@ -681,13 +681,19 @@ class CoursesController < ApplicationController course_member = @course.course_members.find_by!(user_id: current_user.id, is_active: 1) tip_exception("切换失败") if course_member.STUDENT? - course_student = CourseMember.find_by!(user_id: current_user.id, role: %i[STUDENT], course_id: @course.id) - course_member.update_attributes(is_active: 0) - course_student.update_attributes(is_active: 1) + course_student = CourseMember.find_by(user_id: current_user.id, role: %i[STUDENT], course_id: @course.id) + course_member.update_attributes!(is_active: 0) + if course_student + course_student.update_attributes!(is_active: 1) + else + # 学生身份不存在则创建 + CourseMember.create!(user_id: current_user.id, role: 4, course_id: @course.id) + CourseAddStudentCreateWorksJob.perform_later(@course.id, [current_user.id]) + end normal_status(0, "切换成功") rescue => e uid_logger_error("switch_to_student error: #{e.message}") - tip_exception("切换失败") + tip_exception(e.message) raise ActiveRecord::Rollback end end @@ -1127,7 +1133,7 @@ class CoursesController < ApplicationController def top_banner @user = current_user - @is_teacher = @user_course_identity < Course::STUDENT + @switch_student = Course::BUSINESS < @user_course_identity && @user_course_identity < Course::STUDENT @is_student = @user_course_identity == Course::STUDENT @course.increment!(:visits) end diff --git a/app/controllers/exercises_controller.rb b/app/controllers/exercises_controller.rb index 317760796..ee8e632b5 100644 --- a/app/controllers/exercises_controller.rb +++ b/app/controllers/exercises_controller.rb @@ -518,27 +518,27 @@ class ExercisesController < ApplicationController common_group = exercise_groups_ids & course_id #传入的班级与问卷已存在的班级的交集,即表示已有分班的 new_group_ids = course_id - common_group #新传入的班级id if common_group.count > 0 #判断试卷的分班设置是否存在,存在则更新,负责则新建 - ex_group_params = { + exercise_group_sets = exercise_groups.find_in_exercise_group("course_group_id",common_group) + exercise_group_sets.each do |the_group_setting| + ex_group_params = { :publish_time => exercise_publish_time, :end_time => exercise_end_time - } - exercise_group_sets = exercise_groups.find_in_exercise_group("course_group_id",common_group) - the_group_setting = exercise_group_sets.first - if the_group_setting.present? + } + the_group_setting_status = set_exercise_status(the_group_setting.publish_time,the_group_setting.end_time) if the_group_setting_status == 2 ex_group_params = { - :publish_time => the_group_setting.publish_time, - :end_time => exercise_end_time + :publish_time => the_group_setting.publish_time, + :end_time => exercise_end_time } elsif the_group_setting_status == 3 ex_group_params = { - :publish_time => the_group_setting.publish_time, - :end_time => the_group_setting.end_time + :publish_time => the_group_setting.publish_time, + :end_time => the_group_setting.end_time } end + the_group_setting.update_attributes!(ex_group_params) end - exercise_group_sets.update_all(ex_group_params) end if new_group_ids.size > 0 new_group_ids.each do |c| @@ -560,8 +560,9 @@ class ExercisesController < ApplicationController error_count == 0 normal_status(-1,"已发布/已截止的试卷不允许修改时间") else + # 未发布的分班设置才能删除 if old_exercise_groups.size > 0 - old_all_ex_groups = exercise_groups.find_in_exercise_group("course_group_id",old_exercise_groups) + old_all_ex_groups = exercise_groups.find_in_exercise_group("course_group_id",old_exercise_groups).exercise_group_not_published old_all_ex_groups.destroy_all end #试卷更新为exercise_group_setting的发布时间最小,截止时间最大 @@ -720,8 +721,8 @@ class ExercisesController < ApplicationController if exercise.unified_setting ex_status = exercise.exercise_status #则为试卷的状态 else - ex_status = exercise.exercise_group_settings.find_in_exercise_group("course_group_id",params[:group_ids]) - .exercise_group_not_published.present? ? 1 : 0 + ex_status = @course.course_groups.where(id: params[:group_ids]).size != + exercise.exercise_group_settings.where("course_group_id", params[:group_ids]).exercise_group_published.size ? 1 : 0 end if ex_status == 1 #如果试卷存在已发布的,或者是已截止的,那么则直接跳过 g_course = group_ids #表示是否传入分班参数,如果传入分班的参数,那么试卷的统一设置需修改 @@ -739,8 +740,8 @@ class ExercisesController < ApplicationController g_course.each_with_index do |i, index| exercise_group_setting = exercise.exercise_group_settings.find_in_exercise_group("course_group_id",i).first #根据课堂分班的id,寻找试卷所在的班级 group_end_time = params[:detail] ? group_end_times[index] : ex_end_time - if exercise_group_setting #如果该试卷分组存在,则更新,否则新建 - exercise_group_setting.update_attributes(publish_time: Time.now, end_time: group_end_time) + if exercise_group_setting.present? #如果该试卷分组存在,则更新,否则新建 + exercise_group_setting.update_attributes!(publish_time: Time.now, end_time: group_end_time) else p_course_group = { :exercise_id => exercise.id, @@ -1152,7 +1153,7 @@ class ExercisesController < ApplicationController # 1 老师权限,0 学生权限 @is_teacher_or = (@user_course_identity < Course::STUDENT) ? 1 : 0 @student_status = 2 - @exercise_questions = @exercise.exercise_questions.includes(:exercise_shixun_challenges,:exercise_standard_answers,:exercise_answers,:exercise_shixun_answers).order("question_number ASC") + @exercise_questions = @exercise.exercise_questions.includes(:exercise_shixun_challenges,:exercise_standard_answers,:exercise_answers,:exercise_shixun_answers,:exercise_answer_comments).order("question_number ASC") @question_status = [] get_exercise_status = @exercise.get_exercise_status(current_user) #当前用户的试卷状态 @ex_answer_status = @exercise.get_exercise_status(@ex_user&.user) #当前试卷用户的试卷状态 @@ -1715,9 +1716,9 @@ class ExercisesController < ApplicationController ques_number = q.question_number end if q.question_type != Exercise::PRACTICAL - ques_vote = q.exercise_answers.search_exercise_answer("user_id",user_id) + ques_vote = q.exercise_answers.select{|answer| answer.user_id == user_id} else - ques_vote = q.exercise_shixun_answers.search_shixun_answers("user_id",user_id) + ques_vote = q.exercise_shixun_answers.select{|answer| answer.user_id == user_id} end ques_status = 0 if ques_vote.present? diff --git a/app/controllers/files_controller.rb b/app/controllers/files_controller.rb index 791d145c2..117475894 100644 --- a/app/controllers/files_controller.rb +++ b/app/controllers/files_controller.rb @@ -9,19 +9,20 @@ class FilesController < ApplicationController before_action :set_pagination, only: %i[index public_with_course_and_project mine_with_course_and_project] before_action :validate_upload_params, only: %i[upload import] before_action :find_file, only: %i[show setting update] + before_action :publish_params, only: %i[upload import update] SORT_TYPE = %w[created_on downloads quotes] def index sort = params[:sort] || 0 # 0: 降序;1: 升序 sort_type = params[:sort_type] || 'created_on' # created_on:时间排序, downloads:下载次数排序; quotes: 引用次数排序 - course_second_category_id = params[:course_second_category_id] || 0 # 0: 为主目录, 其他为次目录id + @course_second_category_id = params[:course_second_category_id] || 0 # 0: 为主目录, 其他为次目录id @user = current_user - @attachments = course_second_category_id.to_i == 0 ? @course.attachments : @course.attachments.by_course_second_category_id(course_second_category_id) - @attachments = @attachments.includes(attachment_group_settings: :course_group, author: [:user_extension, :course_members]) + @attachments = @course_second_category_id.to_i == 0 ? @course.attachments.includes(:course_second_category) : @course.attachments.by_course_second_category_id(@course_second_category_id) + @attachments = @attachments.includes(author: [:user_extension, :course_members]) .ordered(sort: sort.to_i, sort_type: sort_type.strip) - get_category(@course, course_second_category_id) + get_category(@course, @course_second_category_id) @total_count = @attachments.size @publish_count = @attachments.published.size @unpublish_count = @total_count - @publish_count @@ -137,9 +138,9 @@ class FilesController < ApplicationController def upload attachment_ids = params[:attachment_ids] course_second_category_id = params[:course_second_category_id] || 0 # 0: 为主目录, 其他为次目录id - is_unified_setting = params.has_key?(:is_unified_setting) ? params[:is_unified_setting] : true - publish_time = params[:publish_time] - course_group_publish_times = params[:course_group_publish_times] || [] + # is_unified_setting = params.has_key?(:is_unified_setting) ? params[:is_unified_setting] : true + # publish_time = params[:publish_time] + # course_group_publish_times = params[:course_group_publish_times] || [] begin attachment_ids.each do |attchment_id| @@ -148,9 +149,12 @@ class FilesController < ApplicationController attachment.container = @course attachment.course_second_category_id = course_second_category_id attachment.description = params[:description] - attachment.is_public = params[:is_public] ? 1 : 0 - attachment.set_publish_time(publish_time) if is_unified_setting - attachment.set_course_group_publish_time(@course, course_group_publish_times) if @course.course_groups.size > 0 && !is_unified_setting && publish_time.blank? + attachment.is_public = params[:is_public] && @course.is_public == 1 ? 1 : 0 + attachment.is_publish = @atta_is_publish + attachment.delay_publish = @atta_delay_publish + attachment.publish_time = @atta_publish_time + # attachment.set_publish_time(publish_time) if is_unified_setting + # attachment.set_course_group_publish_time(@course, course_group_publish_times) if @course.course_groups.size > 0 && !is_unified_setting && publish_time.blank? attachment.save! end end @@ -188,8 +192,9 @@ class FilesController < ApplicationController attach_copied_obj.created_on = Time.now attach_copied_obj.author = current_user attach_copied_obj.is_public = 0 - attach_copied_obj.is_publish = 1 - attach_copied_obj.publish_time = Time.now + attach_copied_obj.is_publish = @atta_is_publish + attach_copied_obj.delay_publish = @atta_delay_publish + attach_copied_obj.publish_time = @atta_publish_time attach_copied_obj.course_second_category_id = course_second_category_id attach_copied_obj.copy_from = ori.copy_from.nil? ? ori.id : ori.copy_from if attach_copied_obj.attachtype == nil @@ -209,11 +214,7 @@ class FilesController < ApplicationController def update return normal_status(403, "您没有权限进行该操作") if current_user.course_identity(@course) >= 5 && @file.author != current_user - is_unified_setting = params[:is_unified_setting] - publish_time = params[:publish_time] - publish_time = format_time(Time.parse(publish_time)) unless publish_time.blank? is_public = params[:is_public] - course_group_publish_times = params[:course_group_publish_times] || [] @old_attachment = @file @new_attachment = Attachment.find_by_id params[:new_attachment_id] @@ -225,25 +226,29 @@ class FilesController < ApplicationController old_course_second_category_id = @old_attachment.course_second_category_id @old_attachment.copy_attributes_from_new_attachment(@new_attachment) - @old_attachment.is_public = is_public == true ? 1 : 0 if is_public @old_attachment.course_second_category_id = old_course_second_category_id @old_attachment.save! @new_attachment.delete end + @old_attachment.is_public = is_public == true && @course.is_public == 1 ? 1 : 0 + @old_attachment.is_publish = @atta_is_publish + @old_attachment.delay_publish = @atta_delay_publish + @old_attachment.publish_time = @atta_publish_time + if params[:description] && !params[:description].strip.blank? && params[:description] != @old_attachment.description @old_attachment.description = params[:description] end - @old_attachment.set_public(is_public) + # @old_attachment.set_public(is_public) - if is_unified_setting - @old_attachment.set_publish_time(publish_time) - @old_attachment.attachment_group_settings.destroy_all - end + # if is_unified_setting + # @old_attachment.set_publish_time(publish_time) + # @old_attachment.attachment_group_settings.destroy_all + # end - if publish_time.blank? && @course.course_groups.size > 0 && !is_unified_setting - @old_attachment.set_course_group_publish_time(@course, course_group_publish_times) - end + # if publish_time.blank? && @course.course_groups.size > 0 && !is_unified_setting + # @old_attachment.set_course_group_publish_time(@course, course_group_publish_times) + # end @old_attachment.save! rescue Exception => e @@ -304,11 +309,19 @@ class FilesController < ApplicationController end def file_validate_sort_type - normal_status(-2, "参数sort_tyope暂时只支持 'created_on', 'quotes', 'downloads'") if params.has_key?(:sort_type) && !SORT_TYPE.include?(params[:sort_type].strip) + normal_status(-2, "参数sort_type暂时只支持 'created_on', 'quotes', 'downloads'") if params.has_key?(:sort_type) && !SORT_TYPE.include?(params[:sort_type].strip) end def validate_upload_params find_attachment_ids find_course_second_category_id end + + def publish_params + tip_exception("缺少发布参数") if params[:delay_publish].blank? + tip_exception("缺少延期发布的时间参数") if params[:delay_publish].to_i == 1 && params[:publish_time].blank? + @atta_is_publish = params[:delay_publish].to_i == 1 && params[:publish_time].to_time > Time.now ? 0 : 1 + @atta_delay_publish = params[:delay_publish].to_i + @atta_publish_time = params[:delay_publish].to_i == 1 && params[:publish_time] ? params[:publish_time] : Time.now + end end diff --git a/app/controllers/homework_commons_controller.rb b/app/controllers/homework_commons_controller.rb index 83b80bec4..60cf2d6c5 100644 --- a/app/controllers/homework_commons_controller.rb +++ b/app/controllers/homework_commons_controller.rb @@ -160,7 +160,8 @@ class HomeworkCommonsController < ApplicationController # 作品状态 0: 未提交, 1 按时提交, 2 延迟提交 if params[:work_status].present? - work_status = params[:work_status].map{|status| status.to_i} + params_work_status = request.get? ? params[:work_status].split(",") : params[:work_status] + work_status = params_work_status.map{|status| status.to_i} all_student_works = @student_works.left_joins(:myshixun) @student_works = all_student_works.where(work_status: work_status) @@ -170,7 +171,8 @@ class HomeworkCommonsController < ApplicationController # 分班情况 unless params[:course_group].blank? - group_user_ids = @course.students.where(course_group_id: params[:course_group]).pluck(:user_id) + group_ids = request.get? ? params[:course_group].split(",") : params[:course_group] + group_user_ids = @course.students.where(course_group_id: group_ids).pluck(:user_id) # 有分组只可能是老师身份查看列表 @student_works = @student_works.where(user_id: group_user_ids) end @@ -482,7 +484,7 @@ class HomeworkCommonsController < ApplicationController publish_time = setting[:publish_time] == "" ? Time.now : setting[:publish_time] # 截止时间为空时取发布时间后一个月 - end_time = setting[:end_time] == "" ? Time.at(publish_time.to_time.to_i+30*24*3600) : setting[:end_time] + end_time = setting[:end_time] HomeworkGroupSetting.where(homework_common_id: @homework.id, course_group_id: setting[:group_id]). update_all(publish_time: publish_time, end_time: end_time) setting_group_ids << setting[:group_id] @@ -1170,7 +1172,7 @@ class HomeworkCommonsController < ApplicationController # 可立即截止的分班:统一设置则是用户管理的所有分班,否则是当前用户管理的分班中已发布且未截止的 charge_group_ids = @course.charge_group_ids(@current_user) # 当前用户管理的分班 group_ids = @homework.unified_setting ? charge_group_ids : - @homework.homework_group_settings.where(course_group_id: charge_group_ids).none_end.pluck(:course_group_id) + @homework.homework_group_settings.where(course_group_id: charge_group_ids).published_no_end.pluck(:course_group_id) @course_groups = @course.course_groups.where(id: group_ids) else tip_exception("没有可截止的分班") diff --git a/app/controllers/polls_controller.rb b/app/controllers/polls_controller.rb index da5917e1b..e5cb8b1c2 100644 --- a/app/controllers/polls_controller.rb +++ b/app/controllers/polls_controller.rb @@ -279,7 +279,8 @@ class PollsController < ApplicationController if poll.unified_setting pl_status = poll.polls_status #则为试卷的状态 else - pl_status = poll.poll_group_settings.find_in_poll_group("course_group_id",params[:group_ids]).poll_group_not_published.present? ? 1 : 0 #立即发布针对分组设置的全部未发布的班级才生效 + pl_status = @course.course_groups.where(id: params[:group_ids]).size != + poll.poll_group_settings.where("course_group_id",params[:group_ids]).poll_group_published.size ? 1 : 0 #立即发布针对分组设置的全部未发布的班级才生效 end if pl_status == 1 #如果问卷存在已发布的,或者是已截止的,那么则直接跳过 g_course = group_ids #表示是否传入分班参数,如果传入分班的参数,那么poll的统一设置需修改 @@ -782,27 +783,27 @@ class PollsController < ApplicationController common_group = poll_groups_ids & course_id #传入的班级与问卷已存在的班级的交集,即表示已有分班的 new_group_ids = course_id - common_group #新传入的班级id if common_group.size > 0 #传入的参数存在已发布的分班 - poll_group_params = { + poll_group = poll_groups.find_in_poll_group("course_group_id",common_group) + poll_group.each do |the_group_setting| + poll_group_params = { :publish_time => poll_publish_time, :end_time => poll_end_time - } - poll_group = poll_groups.find_in_poll_group("course_group_id",common_group) - the_group_setting = poll_group.first - if the_group_setting.present? + } + the_group_setting_status = set_poll_status(the_group_setting.publish_time,the_group_setting.end_time) if the_group_setting_status == 2 poll_group_params = { - :publish_time => the_group_setting.publish_time, - :end_time => poll_end_time + :publish_time => the_group_setting.publish_time, + :end_time => poll_end_time } elsif the_group_setting_status == 3 poll_group_params = { - :publish_time => the_group_setting.publish_time, - :end_time => the_group_setting.end_time + :publish_time => the_group_setting.publish_time, + :end_time => the_group_setting.end_time } end + the_group_setting.update_attributes(poll_group_params) end - poll_group.update_all(poll_group_params) end if new_group_ids.size > 0 new_group_ids.each do |c| @@ -824,8 +825,9 @@ class PollsController < ApplicationController error_count == 0 normal_status(-1,"已发布/已截止的问卷不允许修改时间") else + # 未发布的分班设置才能删除 if old_poll_groups.size > 0 - old_all_poll_groups = poll_groups.find_in_poll_group("course_group_id",old_poll_groups) + old_all_poll_groups = poll_groups.find_in_poll_group("course_group_id",old_poll_groups).poll_group_not_published old_all_poll_groups.destroy_all end #问卷更新为poll_group_setting的发布时间最小,截止时间最大 diff --git a/app/controllers/weapps/base_controller.rb b/app/controllers/weapps/base_controller.rb new file mode 100644 index 000000000..fadf10fb6 --- /dev/null +++ b/app/controllers/weapps/base_controller.rb @@ -0,0 +1,34 @@ +class Weapps::BaseController < ApplicationController + + private + + def require_wechat_login! + return if session_unionid.present? + + render_error('请先进行微信授权') + end + + def weapp_session_key + Wechat::Weapp.session_key(session_openid) + end + + def set_weapp_session_key(session_key) + Wechat::Weapp.write_session_key(session_openid, session_key) + end + + def session_openid + session[:openid] + end + + def set_session_openid(openid) + session[:openid] = openid + end + + def session_unionid + session[:unionid] + end + + def set_session_unionid(unionid) + session[:unionid] = unionid + end +end \ No newline at end of file diff --git a/app/controllers/weapps/code_sessions_controller.rb b/app/controllers/weapps/code_sessions_controller.rb new file mode 100644 index 000000000..7c1978e5f --- /dev/null +++ b/app/controllers/weapps/code_sessions_controller.rb @@ -0,0 +1,24 @@ +class Weapps::CodeSessionsController < Weapps::BaseController + def create + return render_error('code不能为空') if params[:code].blank? + + result = Wechat::Weapp.jscode2session(params[:code]) + + set_session_openid(result['openid']) + set_weapp_session_key(result['session_key']) # weapp session_key写入缓存 后续解密需要 + + # 已授权,绑定过账号 + open_user = OpenUser::Wechat.find_by(uid: result['unionid']) + if open_user.present? && open_user.user + set_session_unionid(result['unionid']) + successful_authentication(open_user.user) + else + # 新用户 + user_info = Wechat::Weapp.decrypt(result['session_key'], params[:encrypted_data], params[:iv]) + + set_session_unionid(user_info['unionId']) + end + + render_ok(openid: result['openid']) + end +end \ No newline at end of file diff --git a/app/controllers/weapps/homes_controller.rb b/app/controllers/weapps/homes_controller.rb new file mode 100644 index 000000000..efb80b898 --- /dev/null +++ b/app/controllers/weapps/homes_controller.rb @@ -0,0 +1,12 @@ +class Weapps::HomesController < Weapps::BaseController + def show + # banner图 + @images = PortalImage.where(status: true).order(position: :asc) + + # 热门实训 + @shixuns = Shixun.where(homepage_show: true).includes(:tag_repertoires, :challenges).limit(4) + + # 热门实践课程 + @subjects = Subject.where(homepage_show: true).includes(:shixuns, :repertoire).limit(4) + end +end \ No newline at end of file diff --git a/app/controllers/weapps/registers_controller.rb b/app/controllers/weapps/registers_controller.rb new file mode 100644 index 000000000..0cbab7fd4 --- /dev/null +++ b/app/controllers/weapps/registers_controller.rb @@ -0,0 +1,63 @@ +class Weapps::RegistersController < Weapps::BaseController + before_action :require_wechat_login! + + def create + # 查询验证码是否正确;type只可能是1或者8 + type = phone_mail_type(params[:login].strip) + code = params[:code].strip + + if type == 1 + uid_logger("start register by phone: type is #{type}") + pre = 'p' + email = nil + phone = params[:login] + verifi_code = VerificationCode.where(phone: phone, code: code, code_type: 1).last + else + uid_logger("start register by email: type is #{type}") + pre = 'm' + email = params[:login] + phone = nil + verifi_code = VerificationCode.where(email: email, code: code, code_type: 8).last + end + uid_logger("start register: verifi_code is #{verifi_code}, code is #{code}, time is #{Time.now.to_i - verifi_code.try(:created_at).to_i}") + # check_code = (verifi_code.try(:code) == code.strip && (Time.now.to_i - verifi_code.created_at.to_i) <= 10*60) + # todo 上线前请删除万能验证码"513231" + unless code == "513231" && request.subdomain == "test-newweb" + return render_error('验证码不正确') if verifi_code.try(:code) != code.strip + return render_error('验证码已失效') if !verifi_code&.effective? + end + + login = User.generate_login(pre) + @user = User.new(admin: false, login: login, mail: email, phone: phone, type: 'User') + @user.password = params[:password] + # 现在因为是验证码,所以在注册的时候就可以激活 + @user.activate + # 必须要用save操作,密码的保存是在users中 + ActiveRecord::Base.transaction do + @user.save! + UserExtension.create!(user_id: @user.id) + # 绑定微信号 + OpenUsers::Wechat.create!(user: @user, uid: session_unionid) + + # 注册完成,手机号或邮箱想可以奖励500金币 + RewardGradeService.call( + @user, + container_id: @user.id, + container_type: pre == 'p' ? 'Phone' : 'Mail', + score: 500 + ) + end + successful_authentication(@user) + session[:user_id] = @user.id + + render_ok + end + + private + + # 1 手机类型;0 邮箱类型 + # 注意新版的login是自动名生成的 + def phone_mail_type value + value =~ /^1\d{10}$/ ? 1 : 0 + end +end \ No newline at end of file diff --git a/app/controllers/weapps/sessions_controller.rb b/app/controllers/weapps/sessions_controller.rb new file mode 100644 index 000000000..f65111399 --- /dev/null +++ b/app/controllers/weapps/sessions_controller.rb @@ -0,0 +1,24 @@ +class Weapps::SessionsController < Weapps::BaseController + before_action :require_wechat_login! + + def create + return render_error('重复登录') if current_user.present? && current_user.logged? + + user = User.try_to_login(params[:login], params[:password]) + + return render_error('错误的账号或密码') if user.blank? + return render_error('违反平台使用规范,账号已被锁定') if user.locked? + return render_error('错误的账号或密码') unless user.check_password?(params[:password].to_s) + + if user.wechat_open_user && user.wechat_open_user.uid != session_unionid + render_error('该账号已被其它微信号绑定') + return + end + + # 绑定微信号 + OpenUsers::Wechat.create!(user: user, uid: session_unionid) if user.wechat_open_user.blank? + + successful_authentication(user) + render_ok + end +end \ No newline at end of file diff --git a/app/controllers/weapps/verifies_controller.rb b/app/controllers/weapps/verifies_controller.rb new file mode 100644 index 000000000..5d8f4056e --- /dev/null +++ b/app/controllers/weapps/verifies_controller.rb @@ -0,0 +1,8 @@ +class Weapps::VerifiesController < Weapps::BaseController + before_action :require_wechat_login! + + def create + valid = Wechat::Weapp.verify?(session_openid, params[:verify_string], params[:signature]) + render_ok(valid: valid) + end +end \ No newline at end of file diff --git a/app/forms/users/update_password_form.rb b/app/forms/users/update_password_form.rb index 023caa40f..4da341839 100644 --- a/app/forms/users/update_password_form.rb +++ b/app/forms/users/update_password_form.rb @@ -4,5 +4,4 @@ class Users::UpdatePasswordForm attr_accessor :password, :old_password validates :password, presence: true - validates :old_password, presence: true end \ No newline at end of file diff --git a/app/helpers/courses_helper.rb b/app/helpers/courses_helper.rb index fb7bd1a88..9afbdd3af 100644 --- a/app/helpers/courses_helper.rb +++ b/app/helpers/courses_helper.rb @@ -62,7 +62,7 @@ module CoursesHelper course_board = course.course_board "/courses/#{course.id}/boards/#{course_board.id}" when "course_group" - "/courses/#{course.id}/students" + "/courses/#{course.id}/course_groups" end end diff --git a/app/helpers/exercises_helper.rb b/app/helpers/exercises_helper.rb index ef9261990..e13f754be 100644 --- a/app/helpers/exercises_helper.rb +++ b/app/helpers/exercises_helper.rb @@ -10,9 +10,9 @@ module ExercisesHelper exercise_obj_status.each do |q| q_type = q.question_type if q_type == Exercise::PRACTICAL - answers_content = q.exercise_shixun_answers.search_shixun_answers("user_id",user_id) + answers_content = q.exercise_shixun_answers.select{|answer| answer.user_id == user_id} else - answers_content = q.exercise_answers.search_answer_users("user_id",user_id) + answers_content = q.exercise_answers.select{|answer| answer.user_id == user_id} end if q_type <= Exercise::JUDGMENT @@ -40,7 +40,7 @@ module ExercisesHelper ques_score = 0.0 end else - ques_score = answers_content.score_reviewed.select(:score).pluck(:score).sum + ques_score = answers_content.select{|answer| answer.score >= 0.0}.pluck(:score).sum end if ques_score >= q.question_score #满分作答为正确 @@ -64,7 +64,7 @@ module ExercisesHelper exercise_sub_status = exercise_questions.find_by_custom("question_type",Exercise::SUBJECTIVE) #主观题 @ex_sub_array = [] #主观题的已答/未答 exercise_sub_status.each do |s| - sub_answer = s.exercise_answers.search_answer_users("user_id",user_id) #主观题只有一个回答 + sub_answer = s.exercise_answers.select{|answer| answer.user_id == user_id} #主观题只有一个回答 if sub_answer.present? && sub_answer.first.score >= 0.0 if s.question_score <= sub_answer.first.score stand_status = 1 @@ -772,12 +772,12 @@ module ExercisesHelper question_comment = [] # user_score_pre = nil if ques_type == 5 - exercise_answers = q.exercise_shixun_answers.search_shixun_answers("user_id",ex_answerer_id) + exercise_answers = q.exercise_shixun_answers.select{|answer| answer.user_id == ex_answerer_id} else - exercise_answers = q.exercise_answers.search_exercise_answer("user_id",ex_answerer_id) #试卷用户的回答 + exercise_answers = q.exercise_answers.select{|answer| answer.user_id == ex_answerer_id} #试卷用户的回答 end if student_status == 2 #当前为老师,或为学生且已提交 - user_score_pre = exercise_answers.score_reviewed + user_score_pre = exercise_answers.select{|answer| answer.score >= 0.0} if ques_type == 4 #主观题时,且没有大于0的分数时,为空 user_score = user_score_pre.present? ? user_score_pre.pluck(:score).sum : nil elsif ques_type == 5 || ques_type == 3 @@ -829,7 +829,7 @@ module ExercisesHelper if ex_type == 4 #填空题/主观题/实训题有评论的 q_answer_id = exercise_answers.present? ? exercise_answers.first.id : nil - question_comment = q.exercise_answer_comments.search_answer_comments("exercise_answer_id",q_answer_id) + question_comment = q.exercise_answer_comments.select{|comment| comment.exercise_answer_id == q_answer_id} end { "user_score": (user_score.present? ? user_score.round(1).to_s : nil), diff --git a/app/helpers/export_helper.rb b/app/helpers/export_helper.rb index 28bef0a89..534a78dc1 100644 --- a/app/helpers/export_helper.rb +++ b/app/helpers/export_helper.rb @@ -452,7 +452,7 @@ module ExportHelper end end - out_file_name = "作品附件_#{homework_common&.course&.name}_#{homework_common.name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}.zip" + out_file_name = "作品附件_#{homework_common.name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}.zip" out_file_name.gsub!(" ", "-") out_file_name.gsub!("/", "_") out_file = find_or_pack(homework_common, homework_common.user_id, digests.sort){ diff --git a/app/libs/hot_search_keyword.rb b/app/libs/hot_search_keyword.rb new file mode 100644 index 000000000..e222bf3a7 --- /dev/null +++ b/app/libs/hot_search_keyword.rb @@ -0,0 +1,22 @@ +class HotSearchKeyword + class << self + def add(keyword) + return if keyword.blank? + Rails.cache.data.zincrby(redis_key, 1, keyword) + end + + def hot(limit = 5) + Rails.cache.data.zrevrange(redis_key, 0, limit - 1) + end + + def available? + Rails.cache.is_a?(ActiveSupport::Cache::RedisStore) + end + + private + + def redis_key + 'educoder:es:hot_keyword' + end + end +end \ No newline at end of file diff --git a/app/libs/wechat/app.rb b/app/libs/wechat/app.rb deleted file mode 100644 index 54f60fa2a..000000000 --- a/app/libs/wechat/app.rb +++ /dev/null @@ -1,11 +0,0 @@ -class Wechat::App - class << self - attr_accessor :appid, :secret - - delegate :access_token, :jscode2session, to: :client - - def client - @_client ||= Wechat::Client.new(appid, secret) - end - end -end \ No newline at end of file diff --git a/app/libs/wechat/weapp.rb b/app/libs/wechat/weapp.rb new file mode 100644 index 000000000..755c9351a --- /dev/null +++ b/app/libs/wechat/weapp.rb @@ -0,0 +1,47 @@ +class Wechat::Weapp + class << self + attr_accessor :appid, :secret + + delegate :access_token, :jscode2session, to: :client + + def client + @_client ||= Wechat::Client.new(appid, secret) + end + + def session_key(openid) + Rails.cache.read(session_key_cache_key(openid)) + end + + def write_session_key(openid, session_key) + Rails.cache.write(session_key_cache_key(openid), session_key) + end + + def verify?(openid, str, signature) + session_key = session_key(openid) + Digest::SHA1.hexdigest("#{str}#{session_key}") == signature + end + + def decrypt(session_key, encrypted_data, iv) + session_key = Base64.decode64(session_key) + encrypted_data = Base64.decode64(encrypted_data) + iv = Base64.decode64(iv) + + cipher = OpenSSL::Cipher::AES.new(128, :CBC) + cipher.decrypt + cipher.padding = 0 + cipher.key = session_key + cipher.iv = iv + data = cipher.update(encrypted_data) << cipher.final + result = JSON.parse(data[0...-data.last.ord]) + + raise Wechat::Error, '解密错误' if result.dig('watermark', 'appid') != appid + result + end + + private + + def session_key_cache_key(openid) + "weapp:#{appid}:#{openid}:session_key" + end + end +end \ No newline at end of file diff --git a/app/models/attachment.rb b/app/models/attachment.rb index ae28e7d52..8b7034ab9 100644 --- a/app/models/attachment.rb +++ b/app/models/attachment.rb @@ -9,6 +9,8 @@ class Attachment < ApplicationRecord belongs_to :course, foreign_key: :container_id, optional: true has_many :attachment_group_settings, :dependent => :destroy has_many :attachment_histories, -> { order(version: :desc) }, :dependent => :destroy + # 二级目录 + belongs_to :course_second_category, optional: true scope :by_filename_or_user_name, -> (keywords) { joins(:author).where("filename like :search or LOWER(concat(users.lastname, users.firstname)) LIKE :search", :search => "%#{keywords.split(" ").join('|')}%") unless keywords.blank? } @@ -96,7 +98,7 @@ class Attachment < ApplicationRecord def become_history history = self.attachment_histories.first - new_attachment_history = AttachmentHistory.new(self.attributes.except("id", "resource_bank_id", "unified_setting", "course_second_category_id").merge( + new_attachment_history = AttachmentHistory.new(self.attributes.except("id", "resource_bank_id", "unified_setting", "course_second_category_id", "delay_publish").merge( attachment_id: self.id, version: history.nil? ? 1 : history.version + 1, )) @@ -104,7 +106,7 @@ class Attachment < ApplicationRecord end def copy_attributes_from_new_attachment(new_attachment) - self.attributes = new_attachment.attributes.dup.except("id","container_id","container_type","is_public","downloads", "quotes",'is_publish','publish_time') + self.attributes = new_attachment.attributes.dup.except("id","container_id","container_type","is_public","downloads", "quotes",'is_publish','publish_time', "delay_publish") end def set_public(is_public) diff --git a/app/models/competition.rb b/app/models/competition.rb index 024478ad6..9055adefc 100644 --- a/app/models/competition.rb +++ b/app/models/competition.rb @@ -18,6 +18,29 @@ class Competition < ApplicationRecord after_create :create_competition_modules + def mode_type + case mode + when 1 + "课堂" + when 2 + "实训" + when 3 + "教学" + when 4 + "托管" + else + "--" + end + end + + def teacher_staff_num + teacher_staff ? "#{teacher_staff.minimum}~#{teacher_staff.maximum}" : "--" + end + + def member_staff_num + member_staff ? "#{member_staff.minimum}~#{member_staff.maximum}" : "--" + end + # 是否上架 def published? status? diff --git a/app/models/competition_mode_setting.rb b/app/models/competition_mode_setting.rb new file mode 100644 index 000000000..b6bafa7c3 --- /dev/null +++ b/app/models/competition_mode_setting.rb @@ -0,0 +1,3 @@ +class CompetitionModeSetting < ApplicationRecord + belongs_to :course +end diff --git a/app/models/homework_group_setting.rb b/app/models/homework_group_setting.rb index ae9491cb3..7a06d5a7a 100644 --- a/app/models/homework_group_setting.rb +++ b/app/models/homework_group_setting.rb @@ -6,6 +6,6 @@ class HomeworkGroupSetting < ApplicationRecord scope :none_published, -> {where("homework_group_settings.publish_time IS NULL OR homework_group_settings.publish_time > ?", Time.now)} scope :published_no_end, -> {where("homework_group_settings.publish_time IS NOT NULL AND homework_group_settings.publish_time < ? and homework_group_settings.end_time > ?", Time.now, Time.now)} - scope :none_end, -> {where("homework_group_settings.end_time IS NOT NULL AND homework_group_settings.end_time > ?", Time.now)} + scope :none_end, -> {where("homework_group_settings.end_time IS NULL or homework_group_settings.end_time > ?", Time.now)} end diff --git a/app/models/laboratory.rb b/app/models/laboratory.rb index 53e66ece0..f319ace80 100644 --- a/app/models/laboratory.rb +++ b/app/models/laboratory.rb @@ -19,7 +19,7 @@ class Laboratory < ApplicationRecord return if subdomain.blank? rails_env = EduSetting.get('rails_env') - subdomain = subdomain.slice(0, subdomain.size - rails_env.size - 1) if subdomain.end_with?(rails_env) # winse.dev => winse + subdomain = subdomain.slice(0, subdomain.size - rails_env.size - 1) if rails_env && subdomain.end_with?(rails_env) # winse.dev => winse find_by_identifier(subdomain) end diff --git a/app/models/user.rb b/app/models/user.rb index 11ffe084c..103f9e0b5 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -43,7 +43,7 @@ class User < ApplicationRecord has_many :myshixuns, :dependent => :destroy has_many :study_shixuns, through: :myshixuns, source: :shixun # 已学习的实训 has_many :course_messages - has_many :courses, dependent: :destroy + has_many :courses, foreign_key: 'tea_id', dependent: :destroy #试卷 has_many :exercise_banks, :dependent => :destroy @@ -274,7 +274,7 @@ class User < ApplicationRecord # 课堂的学生 def student_of_course?(course) - course.course_members.exists?(user_id: id, role: %i[STUDENT]) + course.course_members.exists?(user_id: id, role: %i[STUDENT], is_active: 1) end # 课堂成员 @@ -642,6 +642,14 @@ class User < ApplicationRecord login end + def bind_open_user?(type) + case type + when 'wechat' then wechat_open_user.present? + when 'qq' then qq_open_user.present? + else false + end + end + protected def validate_password_length # 管理员的初始密码是5位 diff --git a/app/queries/admins/laboratory_query.rb b/app/queries/admins/laboratory_query.rb index 21020216b..8667bb8ed 100644 --- a/app/queries/admins/laboratory_query.rb +++ b/app/queries/admins/laboratory_query.rb @@ -15,7 +15,7 @@ class Admins::LaboratoryQuery < ApplicationQuery keyword = strip_param(:keyword) if keyword.present? like_sql = 'schools.name LIKE :keyword OR laboratories.identifier LIKE :keyword' - laboratories = laboratories.joins(:school).where(like_sql, keyword: "%#{keyword}%") + laboratories = laboratories.left_joins(:school).where(like_sql, keyword: "%#{keyword}%") end custom_sort laboratories, params[:sort_by], params[:sort_direction] diff --git a/app/services/admins/save_laboratory_setting_service.rb b/app/services/admins/save_laboratory_setting_service.rb index 00e202cd9..f2a5c151e 100644 --- a/app/services/admins/save_laboratory_setting_service.rb +++ b/app/services/admins/save_laboratory_setting_service.rb @@ -30,7 +30,7 @@ class Admins::SaveLaboratorySettingService < ApplicationService hash = {} hash[:name] = strip nav[:name] hash[:link] = strip nav[:link] - hash[:hidden] = nav[:hidden].to_s == 0 + hash[:hidden] = nav[:hidden].to_s != '0' hash end end diff --git a/app/services/create_bind_user_service.rb b/app/services/create_bind_user_service.rb index 29818c493..f7fc5b6f6 100644 --- a/app/services/create_bind_user_service.rb +++ b/app/services/create_bind_user_service.rb @@ -15,14 +15,16 @@ class CreateBindUserService < ApplicationService return user end - bind_user = User.try_to_login(params[:login], params[:password]) + bind_user = User.try_to_login(params[:username], params[:password]) raise Error, '用户名或者密码错误' if bind_user.blank? + raise Error, '该账号已被其他微信号绑定,请更换其他账号进行绑定' if bind_user.bind_open_user?(params[:type].to_s) ActiveRecord::Base.transaction do open_user.user_id = bind_user.id open_user.save! - user.destroy! + user.user_extension.delete + user.delete end clear_can_bind_user_flag diff --git a/app/services/oauth/create_or_find_qq_account_service.rb b/app/services/oauth/create_or_find_qq_account_service.rb index 3b3c71367..691764ea2 100644 --- a/app/services/oauth/create_or_find_qq_account_service.rb +++ b/app/services/oauth/create_or_find_qq_account_service.rb @@ -17,7 +17,7 @@ class Oauth::CreateOrFindQqAccountService < ApplicationService new_user = true # 新用户 login = User.generate_login('q') - @user = User.new(login: login, nickname: params.dig('info', 'nickname')) + @user = User.new(login: login, nickname: params.dig('info', 'nickname'), type: 'User', status: User::STATUS_ACTIVE) end ActiveRecord::Base.transaction do diff --git a/app/services/oauth/create_or_find_wechat_account_service.rb b/app/services/oauth/create_or_find_wechat_account_service.rb index 717f4bbd4..0313054b7 100644 --- a/app/services/oauth/create_or_find_wechat_account_service.rb +++ b/app/services/oauth/create_or_find_wechat_account_service.rb @@ -24,7 +24,7 @@ class Oauth::CreateOrFindWechatAccountService < ApplicationService new_user = true # 新用户 login = User.generate_login('w') - @user = User.new(login: login, nickname: result['nickname']) + @user = User.new(login: login, nickname: result['nickname'], type: 'User', status: User::STATUS_ACTIVE) end ActiveRecord::Base.transaction do diff --git a/app/views/admins/competition_settings/show.html.erb b/app/views/admins/competition_settings/show.html.erb new file mode 100644 index 000000000..e69de29bb diff --git a/app/views/admins/competitions/enroll_list.html.erb b/app/views/admins/competitions/enroll_list.html.erb new file mode 100644 index 000000000..e69de29bb diff --git a/app/views/admins/competitions/index.html.erb b/app/views/admins/competitions/index.html.erb new file mode 100644 index 000000000..b97e26f94 --- /dev/null +++ b/app/views/admins/competitions/index.html.erb @@ -0,0 +1,9 @@ +<% define_admin_breadcrumbs do %> + <% add_admin_breadcrumb('竞赛列表', admins_competitions_path) %> +<% end %> + +
+ <%= render partial: 'admins/competitions/shared/list', locals: { competitions: @competitions } %> +
+ +<%= render partial: 'admins/shared/modal/upload_file_modal', locals: { title: '上传图片' } %> \ No newline at end of file diff --git a/app/views/admins/competitions/online_switch.js.erb b/app/views/admins/competitions/online_switch.js.erb new file mode 100644 index 000000000..e69de29bb diff --git a/app/views/admins/competitions/publish.js.erb b/app/views/admins/competitions/publish.js.erb new file mode 100644 index 000000000..e69de29bb diff --git a/app/views/admins/competitions/shared/_list.html.erb b/app/views/admins/competitions/shared/_list.html.erb new file mode 100644 index 000000000..8f215d54c --- /dev/null +++ b/app/views/admins/competitions/shared/_list.html.erb @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + <% if competitions.present? %> + <% competitions.each_with_index do |competition, index| %> + + <% page_no = list_index_no(@params_page.to_i, index) %> + <%= render partial: "admins/competitions/shared/td",locals: {competition: competition, page_no: page_no} %> + + <% end %> + <% else %> + <%= render 'admins/shared/no_data_for_table' %> + <% end %> + +
序号竞赛主标题竞赛副标题模式报名人数指导老师参赛者主题图片796*397创建时间 + 操作 +
+ +<%= render partial: 'admins/shared/paginate', locals: { objects: competitions } %> \ No newline at end of file diff --git a/app/views/admins/competitions/shared/_td.html.erb b/app/views/admins/competitions/shared/_td.html.erb new file mode 100644 index 000000000..d05974c86 --- /dev/null +++ b/app/views/admins/competitions/shared/_td.html.erb @@ -0,0 +1,27 @@ +<%= page_no %> + + <%= link_to competition.name, enroll_list_admins_competition_path(competition), :target => "_blank", :title => competition.name %> + +<%= competition.sub_title %> +<%= competition.mode_type %> +<%= @member_count_map&.fetch(competition.id, 0) || competition.team_members.count %> +<%= competition.teacher_staff_num %> +<%= competition.member_staff_num %> + + <% imageExists = File.exist?(disk_filename("Competition", competition.id)) %> + <% imageUrl = imageExists ? '/' + url_to_avatar(competition) + "?#{Time.now.to_i}" : '' %> + <%= image_tag(imageUrl, width: 60, height: 40, class: "preview-image competition-image-#{competition.id}", data: { toggle: 'tooltip', title: '点击预览' }, style: imageExists ? '' : 'display:none') %> + <%= javascript_void_link imageExists ? '重新上传' : '上传图片', class: 'action upload-competition-image-action', data: { source_id: competition.id, source_type: 'Competition', toggle: 'modal', target: '.admin-upload-file-modal' } %> + +<%= competition.created_at.strftime('%Y-%m-%d %H:%M') %> + + <%= link_to '配置', admins_competition_competition_setting_path(competition), class: 'action edit-action' %> + + <% if !competition.status? && competition.published_at.blank? %> + <%= link_to '发布', publish_admins_competition_path(competition), class: 'action publish-action', method: :post, remote: true %> + <% else %> + <%= link_to '取消发布', unpublish_admins_competition_path(competition), class: 'action unpublish-action', method: :post, remote: true %> + <% end %> + + <%= link_to competition.published? ? "下架" : "上架", online_switch_admins_competition_path(competition), class: 'action online-action', method: :post, remote: true %> + \ No newline at end of file diff --git a/app/views/admins/competitions/unpublish.js.erb b/app/views/admins/competitions/unpublish.js.erb new file mode 100644 index 000000000..e69de29bb diff --git a/app/views/admins/shared/_sidebar.html.erb b/app/views/admins/shared/_sidebar.html.erb index 145910928..ca6fb2a46 100644 --- a/app/views/admins/shared/_sidebar.html.erb +++ b/app/views/admins/shared/_sidebar.html.erb @@ -66,6 +66,8 @@ <% end %> +
  • <%= sidebar_item(admins_competitions_path, '竞赛', icon: 'trophy', controller: 'admins-competitions') %>
  • +
  • <%= sidebar_item_group('#setting-submenu', '网站建设', icon: 'cogs') do %>
  • <%= sidebar_item(admins_carousels_path, '轮播图', icon: 'image', controller: 'admins-carousels') %>
  • diff --git a/app/views/attachments/_attachment.json.jbuilder b/app/views/attachments/_attachment.json.jbuilder index a8ad0a286..a21bf31c4 100644 --- a/app/views/attachments/_attachment.json.jbuilder +++ b/app/views/attachments/_attachment.json.jbuilder @@ -4,10 +4,11 @@ json.is_public attachment.publiced? # json.is_lock attachment.locked?(@is_member) json.is_lock !attachment.publiced? json.is_publish attachment.published? +json.delay_publish attachment.delay_publish json.publish_time attachment.publish_time json.unified_setting attachment.unified_setting json.filesize number_to_human_size(attachment.filesize) -json.quotes attachment.quotes_count +# json.quotes attachment.quotes_count json.description attachment.description json.downloads_count attachment.downloads_count json.created_on attachment.created_on diff --git a/app/views/competitions/competitions/index.json.jbuilder b/app/views/competitions/competitions/index.json.jbuilder index f0d70f69e..400f17379 100644 --- a/app/views/competitions/competitions/index.json.jbuilder +++ b/app/views/competitions/competitions/index.json.jbuilder @@ -20,7 +20,7 @@ json.competitions do if section json.current_stage do - json.name = section.competition_stage.name + json.name section.competition_stage.name json.start_time section.display_start_time json.end_time section.display_end_time end diff --git a/app/views/courses/left_banner.json.jbuilder b/app/views/courses/left_banner.json.jbuilder index 681145769..f3b80b4f5 100644 --- a/app/views/courses/left_banner.json.jbuilder +++ b/app/views/courses/left_banner.json.jbuilder @@ -11,7 +11,7 @@ json.course_modules @course_modules.each do |mod| case mod.module_type when "course_group" # json.none_group_count @course.none_group_count - json.second_category left_group_info @course + # json.second_category left_group_info @course when "board" course_board = @course.course_board if course_board.present? diff --git a/app/views/courses/mine.json.jbuilder b/app/views/courses/mine.json.jbuilder index c82e31f6b..fc6a5becc 100644 --- a/app/views/courses/mine.json.jbuilder +++ b/app/views/courses/mine.json.jbuilder @@ -1,5 +1,6 @@ json.partial! "commons/success" -json.data do - json.array! @courses, :id, :name, :updated_at +json.data @courses do |course| + json.(course, :id, :name, :updated_at, :end_date) + json.created_at course.created_at.strftime("%Y-%m-%d") end diff --git a/app/views/courses/students.json.jbuilder b/app/views/courses/students.json.jbuilder index 0b5d7fe71..5788b44f2 100644 --- a/app/views/courses/students.json.jbuilder +++ b/app/views/courses/students.json.jbuilder @@ -1,7 +1,7 @@ json.students do json.array! @students do |student| json.user_id student.user_id - # json.login student.user.try(:login) + json.login student.user.try(:login) json.name student.user.try(:real_name) json.name_link user_path(student.user) json.student_id student.user.try(:student_id) diff --git a/app/views/courses/top_banner.json.jbuilder b/app/views/courses/top_banner.json.jbuilder index 877ffcdf1..9a0554585 100644 --- a/app/views/courses/top_banner.json.jbuilder +++ b/app/views/courses/top_banner.json.jbuilder @@ -15,7 +15,7 @@ json.is_admin @user_course_identity < Course::PROFESSOR json.is_public @course.is_public == 1 json.code_halt @course.invite_code_halt == 1 json.invite_code @course.invite_code_halt == 0 ? @course.generate_invite_code : "" -json.switch_to_student switch_student_role(@is_teacher, @course, @user) +json.switch_to_student @switch_student json.switch_to_teacher switch_teacher_role(@is_student, @course, @user) json.switch_to_assistant switch_assistant_role(@is_student, @course, @user) #json.join_course !@user.member_of_course?(@course) diff --git a/app/views/exercises/_user_exercise_info.json.jbuilder b/app/views/exercises/_user_exercise_info.json.jbuilder index bdac3a985..c351a9b26 100644 --- a/app/views/exercises/_user_exercise_info.json.jbuilder +++ b/app/views/exercises/_user_exercise_info.json.jbuilder @@ -65,7 +65,7 @@ json.exercise_questions do shixun_type: user_ques_answers[:shixun_type], ques_position: nil, edit_type:nil - if user_ques_comments.count > 0 + if user_ques_comments.size > 0 json.question_comments do json.partial! "exercises/exercise_comments", question_comment:user_ques_answers[:question_comment].first end diff --git a/app/views/files/index.json.jbuilder b/app/views/files/index.json.jbuilder index 7fe3bf5b7..0002cf299 100644 --- a/app/views/files/index.json.jbuilder +++ b/app/views/files/index.json.jbuilder @@ -13,7 +13,10 @@ json.data do json.author do json.partial! "users/user_simple", user: attachment.author end - json.partial! "files/course_groups", attachment_group_settings: attachment.attachment_group_settings + # json.partial! "files/course_groups", attachment_group_settings: attachment.attachment_group_settings + if @course_second_category_id.to_i == 0 + json.category_name attachment.course_second_category&.name + end end end end diff --git a/app/views/files/show.json.jbuilder b/app/views/files/show.json.jbuilder index 941e66619..71359ccfd 100644 --- a/app/views/files/show.json.jbuilder +++ b/app/views/files/show.json.jbuilder @@ -1,3 +1,3 @@ json.partial! 'attachments/attachment', attachment: @file -json.partial! "files/course_groups", attachment_group_settings: @file.attachment_group_settings +# json.partial! "files/course_groups", attachment_group_settings: @file.attachment_group_settings json.partial! "attachment_histories/list", attachment_histories: @attachment_histories \ No newline at end of file diff --git a/app/views/homework_commons/show.json.jbuilder b/app/views/homework_commons/show.json.jbuilder index e78166fe0..74b60af48 100644 --- a/app/views/homework_commons/show.json.jbuilder +++ b/app/views/homework_commons/show.json.jbuilder @@ -5,10 +5,11 @@ json.partial! "homework_btn_check", locals: {identity: @user_course_identity, ho json.partial! "student_btn_check", locals: {identity: @user_course_identity, homework: @homework, work: @work} json.description @homework.description - # 实训作业才有说明 if @homework.homework_type == "practice" json.explanation @homework.explanation +# else +# json.description @homework.description end # 附件 diff --git a/app/views/settings/show.json.jbuilder b/app/views/settings/show.json.jbuilder index 0765e303b..1fce12b77 100644 --- a/app/views/settings/show.json.jbuilder +++ b/app/views/settings/show.json.jbuilder @@ -2,9 +2,9 @@ json.setting do setting = @laboratory.laboratory_setting json.name setting.name || default_setting.name - json.nav_logo_url setting.nav_logo_url || default_setting.nav_logo_url - json.login_logo_url setting.login_logo_url || default_setting.login_logo_url - json.tab_logo_url setting.tab_logo_url || default_setting.tab_logo_url + json.nav_logo_url (setting.nav_logo_url || default_setting.nav_logo_url)&.[](1..-1) + json.login_logo_url (setting.login_logo_url || default_setting.login_logo_url)&.[](1..-1) + json.tab_logo_url (setting.tab_logo_url || default_setting.tab_logo_url)&.[](1..-1) json.navbar setting.navbar || default_setting.navbar diff --git a/app/views/weapps/homes/show.json.jbuilder b/app/views/weapps/homes/show.json.jbuilder new file mode 100644 index 000000000..d2a451030 --- /dev/null +++ b/app/views/weapps/homes/show.json.jbuilder @@ -0,0 +1,14 @@ +json.images do + json.array! @images do |image| + json.path image.link + json.image_url Util::FileManage.source_disk_file_url(image) + end +end + +json.shixuns do + json.partial! 'shixuns/shixun', locals: { shixuns: @shixuns } +end + +json.subjects do + json.partial! 'subjects/subject', locals: { subjects: @subjects } +end \ No newline at end of file diff --git a/config/configuration.yml.example b/config/configuration.yml.example index 612011a7f..6ead04a54 100644 --- a/config/configuration.yml.example +++ b/config/configuration.yml.example @@ -18,6 +18,9 @@ defaults: &defaults wechat: appid: 'test' secret: 'test' + weapp: + appid: 'test' + secret: 'test' development: <<: *defaults diff --git a/config/initializers/wechat_init.rb b/config/initializers/wechat_init.rb index 946e5f638..3fd8f9485 100644 --- a/config/initializers/wechat_init.rb +++ b/config/initializers/wechat_init.rb @@ -1,9 +1,12 @@ wechat_config = {} +weapp_config = {} begin config = Rails.application.config_for(:configuration) wechat_config = config['wechat'] + weapp_config = config['weapp'] raise 'wechat config missing' if wechat_config.blank? + raise 'weapp config missing' if weapp_config.blank? rescue => ex raise ex if Rails.env.production? @@ -12,5 +15,10 @@ rescue => ex wechat_config = {} end +# 网站应用 Wechat::OfficialAccount.appid = wechat_config['appid'] Wechat::OfficialAccount.secret = wechat_config['secret'] + +# 小程序 +Wechat::Weapp.appid = weapp_config['appid'] +Wechat::Weapp.secret = weapp_config['secret'] diff --git a/config/routes.rb b/config/routes.rb index 32725e8e9..4445278de 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -829,6 +829,14 @@ Rails.application.routes.draw do get '/auth/qq/callback', to: 'oauth/qq#create' get '/auth/wechat/callback', to: 'oauth/wechat#create' resource :bind_user, only: [:create] + + namespace :weapps do + resource :home, only: [:show] + resource :session, only: [:create] + resource :register, only: [:create] + resource :code_session, only: [:create] + resource :verify, only: [:create] + end end namespace :admins do @@ -980,6 +988,16 @@ Rails.application.routes.draw do resource :laboratory_setting, only: [:show, :update] resource :laboratory_user, only: [:create, :destroy] end + + resources :competitions, only: [:index, :destroy] do + member do + post :publish + post :unpublish + post :online_switch + get :enroll_list + end + resource :competition_setting, only: [:show, :update] + end end resources :colleges, only: [] do diff --git a/db/migrate/20191014061301_migrate_course_atta.rb b/db/migrate/20191014061301_migrate_course_atta.rb new file mode 100644 index 000000000..04d085c0d --- /dev/null +++ b/db/migrate/20191014061301_migrate_course_atta.rb @@ -0,0 +1,7 @@ +class MigrateCourseAtta < ActiveRecord::Migration[5.2] + def change + add_column :attachments, :delay_publish, :boolean, default: 0 + + Attachment.where(container_type: "Course").where(is_publish: 0).where("publish_time > '#{(Time.now).strftime("%Y-%m-%d %H:%M:%S")}'").update_all(delay_publish: 1) + end +end diff --git a/db/migrate/20191015013924_add_new_column_to_competitions.rb b/db/migrate/20191015013924_add_new_column_to_competitions.rb new file mode 100644 index 000000000..616a46059 --- /dev/null +++ b/db/migrate/20191015013924_add_new_column_to_competitions.rb @@ -0,0 +1,6 @@ +class AddNewColumnToCompetitions < ActiveRecord::Migration[5.2] + def change + add_column :competitions, :bonus, :integer, default: 0 + add_column :competitions, :mode, :integer, default: 0 + end +end diff --git a/db/migrate/20191015015723_create_competition_mode_settings.rb b/db/migrate/20191015015723_create_competition_mode_settings.rb new file mode 100644 index 000000000..5d170eeab --- /dev/null +++ b/db/migrate/20191015015723_create_competition_mode_settings.rb @@ -0,0 +1,11 @@ +class CreateCompetitionModeSettings < ActiveRecord::Migration[5.2] + def change + create_table :competition_mode_settings do |t| + t.references :course + t.datetime :start_time + t.datetime :end_time + + t.timestamps + end + end +end diff --git a/public/react/config/webpack.config.dev.js b/public/react/config/webpack.config.dev.js index fe525154f..ef38a18f8 100644 --- a/public/react/config/webpack.config.dev.js +++ b/public/react/config/webpack.config.dev.js @@ -32,7 +32,7 @@ module.exports = { // See the discussion in https://github.com/facebookincubator/create-react-app/issues/343.s // devtool: "cheap-module-eval-source-map", // 开启调试 - devtool: "source-map", // 开启调试 + //devtool: "source-map", // 开启调试 // These are the "entry points" to our application. // This means they will be the "root" imports that are included in JS bundle. // The first two entry points enable "hot" CSS and auto-refreshes for JS. diff --git a/public/react/public/index.html b/public/react/public/index.html index 321fbe0e5..9b757d2c4 100755 --- a/public/react/public/index.html +++ b/public/react/public/index.html @@ -8,10 +8,12 @@ - + + + - + - EduCoder + + diff --git a/public/react/src/App.js b/public/react/src/App.js index 9b85acfa8..fd945914a 100644 --- a/public/react/src/App.js +++ b/public/react/src/App.js @@ -9,7 +9,7 @@ import { Route, Switch } from 'react-router-dom'; - +import axios from 'axios'; import '@icedesign/base/dist/ICEDesignBase.css'; import '@icedesign/base/index.scss'; @@ -64,6 +64,18 @@ const EducoderLogin = Loadable({ loader: () => import('./modules/login/EducoderLogin'), loading: Loading, }) + +//微信登录 +const Otherlogin=Loadable({ + loader: () => import('./modules/login/Otherlogin'), + loading: Loading, +}) + +const Otherloginstart=Loadable({ + loader: () => import('./modules/login/Otherloginstart'), + loading: Loading, +}) + const TestIndex = Loadable({ loader: () => import('./modules/test'), loading: Loading, @@ -275,6 +287,7 @@ class App extends Component { Addcoursestypes:false, mydisplay:false, occupation:0, + mygetHelmetapi:undefined, } } @@ -315,7 +328,6 @@ class App extends Component { } componentDidMount() { this.disableVideoContextMenu(); - // force an update if the URL changes history.listen(() => { this.forceUpdate() @@ -324,7 +336,8 @@ class App extends Component { $("html").animate({ scrollTop: $('html').scrollTop() - 0 }) }); - initAxiosInterceptors(this.props) + initAxiosInterceptors(this.props); + this.getAppdata(); // // axios.interceptors.response.use((response) => { // // console.log("response"+response); @@ -350,15 +363,78 @@ class App extends Component { this.setState({ isRender:false, }) - } - - render() { + }; + //获取当前定制信息 + getAppdata=()=>{ + let url = "/setting.json"; + axios.get(url).then((response) => { + // console.log("app.js开始请求/setting.json"); + // console.log("获取当前定制信息"); + if(response){ + if(response.data){ + this.setState({ + mygetHelmetapi:response.data.setting + }); + document.title = response.data.setting.name; + var link = document.createElement('link'), + oldLink = document.getElementById('dynamic-favicon'); + link.id = 'dynamic-favicon'; + link.rel = 'shortcut icon'; + link.href = '/'+response.data.setting.tab_logo_url; + if (oldLink) { + document.head.removeChild(oldLink); + } + document.head.appendChild(link); + }else { + document.title = "EduCoder"; + var link = document.createElement('link'), + oldLink = document.getElementById('dynamic-favicon'); + link.id = 'dynamic-favicon'; + link.rel = 'shortcut icon'; + link.href = "/react/build/./favicon.ico"; + if (oldLink) { + document.head.removeChild(oldLink); + } + document.head.appendChild(link); + } + + }else{ + document.title = "EduCoder"; + var link = document.createElement('link'), + oldLink = document.getElementById('dynamic-favicon'); + link.id = 'dynamic-favicon'; + link.rel = 'shortcut icon'; + link.href = "/react/build/./favicon.ico"; + if (oldLink) { + document.head.removeChild(oldLink); + } + document.head.appendChild(link); + } + }).catch((error) => { + document.title = "EduCoder"; + var link = document.createElement('link'), + oldLink = document.getElementById('dynamic-favicon'); + link.id = 'dynamic-favicon'; + link.rel = 'shortcut icon'; + link.href = "/react/build/./favicon.ico"; + if (oldLink) { + document.head.removeChild(oldLink); + } + document.head.appendChild(link); + }); + }; + render() { + let{mygetHelmetapi}=this.state; + // console.log("appappapp"); + // console.log(mygetHelmetapi); return ( + + this.Modifyloginvalue()}> @@ -401,10 +477,28 @@ class App extends Component { { + + return () + } + } + /> + { + + return () + } + } /> + { + + return () + } + } /> {/*课堂*/} - + {/* */} @@ -484,7 +584,12 @@ class App extends Component { render={ (props)=>() }/> - + () + } + /> @@ -607,4 +712,4 @@ moment.defineLocale('zh-cn', { doy: 4 // The week that contains Jan 4th is the first week of the year. } }); -export default SnackbarHOC()(App); \ No newline at end of file +export default SnackbarHOC()(App) ; \ No newline at end of file diff --git a/public/react/src/AppConfig.js b/public/react/src/AppConfig.js index e1d5da561..9cf68503d 100644 --- a/public/react/src/AppConfig.js +++ b/public/react/src/AppConfig.js @@ -94,9 +94,15 @@ export function initAxiosInterceptors(props) { } } - if (requestMap[config.url] === true) { // 避免重复的请求 + if (config.method === "post") { + if (requestMap[config.url] === true) { // 避免重复的请求 导致页面f5刷新 也会被阻止 显示这个方法会影响到定制信息定制信息是get 请求 + // console.log(config); + // console.log(JSON.parse(config)); + // console.log(config.url); + // console.log("被阻止了是重复请求================================="); return false; } + } // 非file_update请求 if (config.url.indexOf('update_file') === -1) { requestMap[config.url] = true; diff --git a/public/react/src/common/course/WordsBtn.js b/public/react/src/common/course/WordsBtn.js index 85a85cfb6..68b278507 100644 --- a/public/react/src/common/course/WordsBtn.js +++ b/public/react/src/common/course/WordsBtn.js @@ -8,20 +8,20 @@ class WordsBtn extends Component { } render() { - let{to, href,targets, style2 }=this.props + let{to, href,targets, style2, style, className, ...others }=this.props return( { to==undefined&&targets==undefined ? {this.props.children}: targets!=undefined? {this.props.children} : {this.props.children} } diff --git a/public/react/src/modules/courses/ListPageIndex.js b/public/react/src/modules/courses/ListPageIndex.js index 730a1bdce..8c5652838 100644 --- a/public/react/src/modules/courses/ListPageIndex.js +++ b/public/react/src/modules/courses/ListPageIndex.js @@ -33,6 +33,12 @@ const StudentsList= Loadable({ loader: () => import('./members/studentsList'), loading: Loading, }); +//分班列表 +const CourseGroupList= Loadable({ + loader: () => import('./members/CourseGroupList'), + loading: Loading, +}); + const Eduinforms= Loadable({ loader: () => import('./gradinforms/Eduinforms.js'), loading: Loading, @@ -234,7 +240,7 @@ class ListPageIndex extends Component{ > () + (props) => () } > diff --git a/public/react/src/modules/courses/Resource/Fileslistitem.js b/public/react/src/modules/courses/Resource/Fileslistitem.js index 418c201b5..2610656cc 100644 --- a/public/react/src/modules/courses/Resource/Fileslistitem.js +++ b/public/react/src/modules/courses/Resource/Fileslistitem.js @@ -209,6 +209,9 @@ class Fileslistitem extends Component{ text-overflow:ellipsis; white-space:nowrap } + .mt2{ + margin-top:2px; + } `}
    window.$(`.sourceitem${index} input`).click() }>
    this.eventStop(event)}> @@ -248,6 +251,29 @@ class Fileslistitem extends Component{ :"" } {discussMessage.is_publish===false?:""} + + {this.props.isAdmin? + this.eventStop(event)}> + + this.settingList()}>设置 + + :""} + + {this.props.isStudent===true&&this.props.current_user.login===discussMessage.author.login? + this.eventStop(event)}> + + + this.settingList()}>设置 + + + + this.onDelete(discussMessage.id)}>删除 + + + :""}
    - {discussMessage.course_groups.length===0?"": -

    - {discussMessage.course_groups.map((item,key)=>{ - return( -

    - {item.course_group_name} - 将发布于 { moment(item.course_group_publish_time).format('YYYY-MM-DD HH:mm')} -
    - ) - })} - -

    } + {/*资源分班*/} + {/*{discussMessage.course_groups.length===0?"":*/} + {/*

    */} + {/*{discussMessage.course_groups.map((item,key)=>{*/} + {/*return(*/} + {/*

    */} + {/*{item.course_group_name}*/} + {/*将发布于 { moment(item.course_group_publish_time).format('YYYY-MM-DD HH:mm')}*/} + {/*
    */} + {/*)*/} + {/*})}*/} + + {/*

    }*/}

    {discussMessage.author.name} 大小 {discussMessage.filesize} 下载 {discussMessage.downloads_count} - 引用 {discussMessage.quotes} + {/*引用 {discussMessage.quotes}*/} {/*{moment(discussMessage.publish_time).format('YYYY-MM-DD HH:mm:ss')}*/} {/*{moment(discussMessage.publish_time).fromNow()}*/} @@ -302,33 +329,14 @@ class Fileslistitem extends Component{ { discussMessage.publish_time===null?"":discussMessage.is_publish===true?moment(discussMessage.publish_time).fromNow():moment(discussMessage.publish_time).format('YYYY-MM-DD HH:mm')} - {this.props.isAdmin? - this.eventStop(event)}> - - this.settingList()}>设置 - - :""} + {discussMessage&&discussMessage.category_name===null?"":this.props.child===false?

    所属目录:{discussMessage&&discussMessage.category_name} +
    :""} +

    - {this.props.isStudent===true&&this.props.current_user.login===discussMessage.author.login? - this.eventStop(event)}> - - this.settingList()}>设置 - - - this.onDelete(discussMessage.id)}>删除 - - - :""} -

    - - - -

    +

    } - {this.props.isAdmin()?parseInt(this.props.match.params.main_id)===parseInt(this.props.coursesids)?this.addDir()} className={"mr30 font-16"}>添加目录:"":""} + {/*{this.props.isAdmin()?parseInt(this.props.match.params.main_id)===parseInt(this.props.coursesids)?this.addDir()} className={"mr30 font-16"}>新建目录:"":""}*/} + {this.props.isAdmin()?this.addDir()} className={"mr30 font-16"}>新建目录:""} {this.props.isAdmin()?parseInt(this.props.match.params.main_id)!=parseInt(this.props.coursesids)?this.editDir(name)} className={"mr30 font-16"}>目录重命名:"":""} {this.props.isAdmin()||this.props.isStudent() ? this.addResource()}>选用资源:""} @@ -869,7 +908,7 @@ class Fileslists extends Component{ {/*})}*/} {this.props.isAdmin()?parseInt(this.props.match.params.main_id)===filesId&&filesId?

    - this.addDir()}>添加目录 + this.addDir()}>新建目录

    :"":""} @@ -877,16 +916,24 @@ class Fileslists extends Component{ :""} - - {this.props.isAdmin()||this.props.isStudent()?
  • - {sorttype === 'created_on' ? '更新时间排序':sorttype === 'downloads' ?'下载次数排序':'引用次数排序'} - -
      - {/*className={sorttype === 'created_on'?"none":""} className={sorttype === 'quotes'?"none":""} className={sorttype === 'downloads'?"none":""} */} -
    • this.onSortTypeChange('created_on')}>更新时间排序
    • -
    • this.onSortTypeChange('downloads')}>下载次数排序
    • -
    • this.onSortTypeChange('quotes')}>引用次数排序
    • -
    + + {this.props.isAdmin()||this.props.isStudent()?
  • this.onSortTypeChange('created_on')}> + 更新时间 + + + +
  • :""}
    @@ -918,6 +965,7 @@ class Fileslists extends Component{
    this.refs['addDirModal'].open()}> - 添加目录 + 新建目录
    } diff --git a/public/react/src/modules/courses/boards/TopicDetail.js b/public/react/src/modules/courses/boards/TopicDetail.js index 8ecc85565..d42b68c17 100644 --- a/public/react/src/modules/courses/boards/TopicDetail.js +++ b/public/react/src/modules/courses/boards/TopicDetail.js @@ -526,8 +526,10 @@ class TopicDetail extends Component { const isAdmin = this.props.isAdmin() // TODO 图片上传地址 const courseId=this.props.match.params.coursesId; - const boardId = this.props.match.params.boardId - const isCourseEnd = this.props.isCourseEnd() + const boardId = this.props.match.params.boardId; + const isCourseEnd = this.props.isCourseEnd(); + + document.title=this.props.coursedata&&this.props.coursedata.name; return (
    {/* fl with100 */} :"" + } + { + this.props.OneSelftype===true? +
    + + + { this.props.usingCheckBeforePost ? + +

    + 发布设置均可修改, + + 点击修改 + +

    +

    + 此设置将对所有分班生效 +

    +
    : + +

    + {this.props.Topval} + {this.props.Topvalright} +

    +

    + {this.props.Botvalleft===undefined?"":"{this.props.Botvalleft}"} + {this.props.Botval} +

    +
    } + + + {this.props.starttime===undefined|| + this.props.starttime===""?"" + :

    + + 发布时间: + {this.props.starttime} + {this.props.modaltype===undefined||this.props.modaltype===2? + {/*{this.props.endtime}*/} + 截止时间: + + {this.state.endtimetype===true?

    {this.state.endtimetypevalue}
    :""} + :""} +

    } + {/* usingCheckBeforePost 为true的时候 全选所有分班 */} + + + {this.props.modaltype===undefined||this.props.modaltype===2 + || this.props.usingCheckBeforePost ?"":
    +
  • + 分班名称 + + 截止时间 +
  • +
    } + {this.props.modaltype===undefined||this.props.modaltype===2 + || this.props.usingCheckBeforePost ?"":
      + + { + { + course_groups.map((item,key)=>{ + + return( +
      +
    • + + {item.name} + + +
    • + +
      + ) + }) + } +
      } + +
    + } + + + +
    +
    :""} +
    + ) + } +} +export default OneSelfOrderModal; \ No newline at end of file diff --git a/public/react/src/modules/courses/coursesPublic/SelectResource.js b/public/react/src/modules/courses/coursesPublic/SelectResource.js index c323d1bae..0e76059c8 100644 --- a/public/react/src/modules/courses/coursesPublic/SelectResource.js +++ b/public/react/src/modules/courses/coursesPublic/SelectResource.js @@ -1,17 +1,34 @@ import React,{ Component } from "react"; -import { Modal,Checkbox,Select,Input,Spin,Icon} from "antd"; +import { Modal,Checkbox,Select,Input,Spin,Icon,Radio,DatePicker} from "antd"; +import locale from 'antd/lib/date-picker/locale/zh_CN'; import axios from'axios'; +import {handleDateString} from 'educoder'; import NoneData from "../coursesPublic/NoneData"; import Modals from '../../modals/Modals'; - +import moment from 'moment'; const Option = Select.Option; const Search = Input.Search; - +const dateFormat ="YYYY-MM-DD HH:mm" function formatDate(date) { var dateee = new Date(date).toJSON(); return new Date(+new Date(dateee) + 8 * 3600 * 1000).toISOString().replace(/T/g, ' ').replace(/\.[\d]{3}Z/, '') } - +function range(start, end) { + const result = []; + for (let i = start; i < end; i++) { + result.push(i); + } + return result; +} +function disabledDateTime() { + return { + disabledMinutes: () => range(1, 30).concat(range(31, 60)), + // disabledSeconds: () => range(1,60) + } +} +function disabledDate(current) { + return current && current < moment().endOf('day').subtract(1, 'days'); +} class Selectresource extends Component{ constructor(props){ super(props); @@ -23,7 +40,9 @@ class Selectresource extends Component{ Resourcelist:undefined, hometypepvisible:true, getallfiles:false, - searchtype:'getallfiles' + searchtype:'getallfiles', + Radiovalue:0, + datatime:undefined } } componentDidMount() { @@ -32,11 +51,7 @@ class Selectresource extends Component{ componentDidUpdate = (prevProps) => { - let {getallfiles}=this.state; - - if ( prevProps.visible != this.props.visible ) { - } } @@ -197,7 +212,7 @@ class Selectresource extends Component{ savecouseShixunModal=()=>{ - let {patheditarry}=this.state; + let {patheditarry,datatime,Radiovalue}=this.state; let {coursesId,attachmentId}=this.props; let url="/files/import.json"; @@ -212,19 +227,28 @@ class Selectresource extends Component{ }) } + if(this.state.Radiovalue===1){ + if(datatime===undefined||datatime===null||datatime=== ""){ + this.setState({ + Radiovaluetype:true + }) + return + }else{ + this.setState({ + Radiovaluetype:false + }) + } + } + axios.post(url, { course_id:coursesId, attachment_ids:patheditarry, course_second_category_id:this.props.coursesidtype===undefined||this.props.coursesidtype==="node"?0:attachmentId, + delay_publish:Radiovalue, + publish_time:Radiovalue===1?datatime:undefined } ).then((response) => { if(response.data.status===0){ - // this.setState({ - // Modalstype:true, - // Modalstopval:response.data.message, - // ModalSave:this.ModalCancelModalCancel, - // loadtype:true - // }) this.ModalCancelModalCancel(); this.props.updataleftNavfun(); this.props.showNotification("选用资源成功"); @@ -236,15 +260,33 @@ class Selectresource extends Component{ } - selectCloseList=(value)=>{ + RadioonChange=(e)=>{ + if(e.target.value===0){ + this.setState({ + datatime:undefined + }) + } this.setState({ - category_id:value + Radiovalue: e.target.value, + }); + } + + onChangeTimepublish= (date, dateString) => { + + this.setState({ + datatime:handleDateString(dateString), }) + } render(){ - let {Searchvalue,type,category_id,Resourcelist,hometypepvisible,patheditarry}=this.state; - let {visible,shixunmodallist}=this.props; + let {Searchvalue,type,Resourcelist,hometypepvisible,patheditarry,datatime}=this.state; + let {visible}=this.props; const antIcon = ; + const radioStyle = { + display: 'block', + height: '30px', + lineHeight: '30px', + }; return(
    {/*提示*/} @@ -373,10 +415,36 @@ class Selectresource extends Component{ }
    - +
    + 发布设置: + + + 立即发布 + + + 延迟发布 + this.onChangeTimepublish(e,index,undefined,1)} + disabledTime={disabledDateTime} + disabledDate={disabledDate} + disabled={this.state.Radiovalue===1?false:true} + /> + + (按照设置的时间定时发布) + +
    {this.state.patheditarrytype===true?

    请选择资源

    :""} - + {this.state.Radiovaluetype===true?

    发布时间不能为空

    :""}
    取消 确定 diff --git a/public/react/src/modules/courses/coursesPublic/SelectSetting.js b/public/react/src/modules/courses/coursesPublic/SelectSetting.js index 37b22c205..ff5751cc6 100644 --- a/public/react/src/modules/courses/coursesPublic/SelectSetting.js +++ b/public/react/src/modules/courses/coursesPublic/SelectSetting.js @@ -1,5 +1,5 @@ import React,{ Component } from "react"; -import { Modal,Checkbox,Select,Input,Upload,Button,Icon,message,DatePicker,Tooltip} from "antd"; +import { Modal,Checkbox,Select,Input,Upload,Button,Icon,message,DatePicker,Tooltip,Radio} from "antd"; import axios from'axios'; import {getUrl,handleDateString,appendFileSizeToUploadFileAll} from 'educoder'; import locale from 'antd/lib/date-picker/locale/zh_CN'; @@ -36,9 +36,10 @@ class Selectsetting extends Component{ course_groups:undefined, attachment_histories:undefined, datatime:undefined, - unified_setting:true, fileList:[], - fileListtype:false + fileListtype:false, + is_public:false, + Radiovaluetype:false } } @@ -54,53 +55,13 @@ class Selectsetting extends Component{ }) .then((response) => { if(response.status===200){ - - let newcourse_groups=[]; - let list =response.data.course_groups; - - // let list=[ - // { - // "course_group_id": 820, - // "course_group_name": "示例A班", - // "course_group_publish_time": "2019-04-18T17:00:00.000+08:00" - // }, - // { - // "course_group_id": 821, - // "course_group_name": "示例B班", - // "course_group_publish_time": "2019-04-19T19:00:00.000+08:00" - // }, - // { - // "course_group_id": 822, - // "course_group_name": "示例C班", - // "course_group_publish_time": "2019-04-10T19:00:00.000+08:00" - // } - // ] - - if(list.length!=0){ - list.forEach((item,key)=>{ - newcourse_groups.push ({ - course_group_id:item.course_group_id, - course_group_name:item.course_group_id, - publish_time:moment(item.course_group_publish_time).format(dateFormat) - }) - }) - }else{ - newcourse_groups.push ({ - course_group_id:undefined, - course_group_name:undefined, - publish_time:"" - }) - } - this.setState({ datalist:response.data, description: response.data.description, - is_public: response.data.is_public, - unified_setting: response.data.unified_setting, + is_public:response.data.is_public, datatime:response.data.publish_time, - // is_public:response.data.course_groups, + Radiovalue:response.data.delay_publish==false?0:1, //attachment_histories:response.data.attachment_histories - course_groups:newcourse_groups }) } @@ -110,23 +71,6 @@ class Selectsetting extends Component{ }); - let coursesId=this.props.match.params.coursesId; - if(this.props.isAdmin()){ - let url = `/courses/${coursesId}/all_course_groups.json` - - axios.get(url, { - }) - .then((response) => { - this.setState({ - course_groupss: response.data.course_groups, - }) - }) - .catch(function (error) { - console.log(error); - }); - } - - } @@ -145,21 +89,6 @@ class Selectsetting extends Component{ this.getalldata() } - } - onChangepublics=(e)=>{ - console.log(e.target.checked) - this.setState({ - is_public:e.target.checked - }) - - } - - onChangesettings=(e)=>{ - console.log(e.target.checked) - this.setState({ - unified_setting:e.target.checked - }) - } settextarea=(e)=>{ @@ -180,13 +109,26 @@ class Selectsetting extends Component{ } savecouseShixunModal=()=>{ - let {fileList,is_public,unified_setting,description,datatime,course_groups}=this.state; + let {fileList,is_public,description,datatime,Radiovalue}=this.state; let newfileList=[]; for(var list of fileList){ newfileList.push(list.response.id) } + if(this.state.Radiovalue===1){ + if(datatime===undefined||datatime===null||datatime=== ""){ + this.setState({ + Radiovaluetype:true + }) + return + }else{ + this.setState({ + Radiovaluetype:false + }) + } + } + if(description===undefined||description===null){ }else if(description.length>100){ @@ -196,29 +138,6 @@ class Selectsetting extends Component{ return } - // course_groups.forEach((item,key)=>{ - // if(item.course_group_id===undefined||item.publish_time===undefined){ - // this.setState({ - // course_group_publish_timestype:true - // }) - // return - // } - // }) - - // if(unified_setting===false){ - // - // course_groups.forEach((item,key)=>{ - // if(item.course_group_id===undefined){ - // this.setState({ - // course_group_idtypes:true - // }) - // return - // } - // }) - // - // } - - let coursesId=this.props.match.params.coursesId; let attachmentId=this.props.attachmentId; let url="/files/"+this.props.discussMessageid+".json"; @@ -226,14 +145,12 @@ class Selectsetting extends Component{ axios.put(url,{ course_id:coursesId, new_attachment_id:newfileList.length===0?undefined:newfileList, - course_second_category_id:this.props.coursesidtype===undefined||this.props.coursesidtype==="node"?0:attachmentId, + course_second_category_id:this.props.coursesidtype===undefined||this.props.coursesidtype==="node"?0:attachmentId, is_public:is_public, - is_unified_setting:unified_setting, - publish_time:unified_setting===true?datatime===undefined?moment(new Date()).format('YYYY-MM-DD HH'):datatime:undefined, + publish_time:Radiovalue===0?undefined:datatime===undefined?moment(new Date(),dateFormat):datatime, description:description, - course_group_publish_times:unified_setting===false?course_groups:undefined + delay_publish:Radiovalue }).then((result)=>{ - if(result.data.status===0){ this.props.setupdate(attachmentId) this.props.showNotification("设置资源成功"); @@ -244,7 +161,6 @@ class Selectsetting extends Component{ } onChangeTimepublish= (date, dateString) => { - // console.log('startValue', dateString); this.setState({ datatime:handleDateString(dateString), }) @@ -268,31 +184,6 @@ class Selectsetting extends Component{ } } - // onAttachmentRemove = (file) => { - // // confirm({ - // // title: '确定要删除这个附件吗?', - // // okText: '确定', - // // cancelText: '取消', - // // // content: 'Some descriptions', - // // onOk: () => { - // // this.deleteAttachment(file) - // // }, - // // onCancel() { - // // console.log('Cancel'); - // // }, - // // }); - // // return false; - // - // // this.setState({ - // // Modalstype:true, - // // Modalstopval:'确定要删除这个附件吗?', - // // ModalSave: ()=>this.deleteAttachment(file), - // // ModalCancel:this.cancelAttachment - // // }) - // // return false; - // - // this.deleteAttachment(file); - // } onAttachmentRemove = (file) => { @@ -309,14 +200,7 @@ class Selectsetting extends Component{ fileListtype:false, fileList:[] }) - // this.setState((state) => { - // const index = state.fileList.indexOf(file); - // const newFileList = state.fileList.slice(); - // newFileList.splice(index, 1); - // return { - // fileList: newFileList, - // }; - // }); + } } }) @@ -332,63 +216,28 @@ class Selectsetting extends Component{ fileList:[] }) } - // const url = `/attachments/${file.response ? file.response.id : file.uid}.json` - } - onChangeTimepublishs= (date, dateString,key) => { - let {course_groups}=this.state; - let newgroup_publish=course_groups; - for(var i=0; i{ this.setState({ - course_groups:newgroup_publish, + is_public:e.target.checked }) } - - - selectassigngroups=(e,index,key)=>{ - let {course_groups}=this.state; - let newgroup_publish=course_groups; - for(var i=0; i{ + if(e.target.value===0){ + this.setState({ + datatime:undefined + }) } this.setState({ - course_groups:newgroup_publish, - }) - } - deletegrouppublish=(key)=>{ - let newlist=this.state.course_groups; - newlist.splice(key,1); - this.setState({ - course_groups:newlist - }) - } - - addgrouppublish=()=>{ - let newlist=this.state.course_groups; - newlist.push( { - course_group_id : undefined, - publish_time :"" - // moment(new Date()).format('YYYY-MM-DD HH:mm') - }) - this.setState({ - course_groups:newlist - }) + Radiovalue: e.target.value, + }); } render(){ - let {is_public,unified_setting,course_groups,datatime,description,datalist,course_group_publish_timestype}=this.state; + let {datatime,description,datalist}=this.state; const uploadProps = { width: 600, - // https://github.com/ant-design/ant-design/issues/15505 - // showUploadList={false},然后外部拿到 fileList 数组自行渲染列表。 - // showUploadList: false, action: `${getUrl()}/api/attachments.json`, onChange: this.handleChange, onRemove: this.onAttachmentRemove, @@ -401,9 +250,13 @@ class Selectsetting extends Component{ return isLt150M; }, }; + const radioStyle = { + display: 'block', + height: '30px', + lineHeight: '30px', + }; - - // console.log(this.props.has_course_groups) + console.log(this.state.Radiovalue) return(
      -
    • 资源名称
    • +
    • 资源名称
    • 下载
    • -
    • 引用
    • + {/*
    • 引用
    • */}
    • 版本号
    @@ -490,7 +343,7 @@ class Selectsetting extends Component{ `}
    -
  • +
  • {datalist&&datalist.title} {datalist&&datalist.attachment_histories.length===0?"":当前版本}
  • @@ -505,13 +358,13 @@ class Selectsetting extends Component{ {datalist&&datalist.attachment_histories.map((item,key)=>{ return(
    -
  • +
  • {item.title} {/*当前版本*/}
  • {item.downloads_count}
  • -
  • {item.quotes}
  • + {/*
  • {item.quotes}
  • */}
  • {moment(item.created_on).format('YYYY-MM-DD HH:mm')==="Invalid date"?"":moment(item.created_on).format('YYYY-MM-DD HH:mm')}
  • @@ -607,61 +460,15 @@ class Selectsetting extends Component{

    - {/**/} - {/*{this.state.fileList.length===0?"":this.state.fileList.map((item,key)=>{*/} - {/*return(*/} - {/*

    */} - {/**/} - {/**/} - {/**/} - {/**/} - {/*{item.name}*/} - {/**/} - {/**/} - {/*{item.response===undefined?"":isNaN(bytesToSize(item.filesize))?"123":bytesToSize(item.filesize)}*/} - {/**/} - {/*this.onAttachmentRemove(item.response===undefined?"":item.response.id&&item.response.id)}>*/} - {/*

    */} - {/*)*/} - {/*})}*/} - {this.state.newfileListtypes===true?

    请先上传资源

    :""} -

    +

    - - {/*

    */} - {/**/} - {/*勾选后所有用户可见,否则仅课堂成员可见*/} - {/**/} - {/*
    */} - {/*{this.props.has_course_groups&&this.props.has_course_groups===true?:""}*/} - {this.state.course_groupss&&this.state.course_groupss.length>0? - 统一设置(选中则所有分班使用相同的发布设置,否则各个单独设置) - :""} - - - - {/*this.props.has_course_groups&&this.props.has_course_groups===true?:""*/} -
    - {unified_setting===false? - this.state.course_groups&&this.state.course_groups.map((item,key)=>{ - return( -
    - - - - - - this.onChangeTimepublishs(e,index,key)} - // onChange={ this.onChangeTimepublish } - disabledTime={disabledDateTime} - disabledDate={disabledDate} - /> - - {key!=0?this.deletegrouppublish(key)}>:""} - {key===course_groups.length-1?:""} -
    - ) - }):""} -
    - + {this.props.course_is_public===true?
    + 公开:this.onChangepublic(e)}> + 选中,所有用户可见,否则课堂成员可见 + +
    :""}

    - {unified_setting===true? -

    - - - -

    :""} - {/*{this.state.course_group_idtypes===true?

    请选择分班

    :""}*/} - - {/*{course_group_publish_timestype===true?

    请填写完整

    :""}*/} + +
    + 发布设置: + this.RadioonChange(e)} value={this.state.Radiovalue} style={{'width': '460px'}}> + + 立即发布 + + + 延迟发布 + + + (按照设置的时间定时发布) + +
    + {this.state.descriptiontypes===true?

    描述不能超过最大限制:100个字符

    :""} + {this.state.Radiovaluetype===true?

    发布时间不能为空

    :""}
    diff --git a/public/react/src/modules/courses/coursesPublic/SendToFilesModal.js b/public/react/src/modules/courses/coursesPublic/SendToFilesModal.js index d14d5d267..c3f2db8c5 100644 --- a/public/react/src/modules/courses/coursesPublic/SendToFilesModal.js +++ b/public/react/src/modules/courses/coursesPublic/SendToFilesModal.js @@ -1,9 +1,11 @@ import React, { Component } from "react"; import { Modal, Checkbox, Input, Spin} from "antd"; -import axios from 'axios' +import axios from 'axios'; +import moment from 'moment'; import ModalWrapper from "../common/ModalWrapper"; import InfiniteScroll from 'react-infinite-scroller'; +const dateFormat ="YYYY-MM-DD HH:mm" const Search = Input.Search const pageCount = 15; class Sendtofilesmodal extends Component{ @@ -170,7 +172,12 @@ class Sendtofilesmodal extends Component{ bottom: 93px; width: 82%; text-align: center; - }`} + } + .ModalWrappertitle{ + background: #D0E8FC; + padding: 10px; + } + `}

    选择的{moduleName}发送到指定课堂

    @@ -183,7 +190,12 @@ class Sendtofilesmodal extends Component{ >
    - {/* https://github.com/CassetteRocks/react-infinite-scroller/issues/70 */} + +

    +

    课堂名称
    +
    创建时间
    +
    结束时间
    +

    - +
    {course.name}
    +
    {moment(course.created_at).format('YYYY-MM-DD')}
    +
    {course.end_date}

    ) }) } - {loading && hasMore && ( -
    - -
    - )} - {/* TODO */} - {/* { - !hasMore &&
    没有更多了。。
    - } */} +
    diff --git a/public/react/src/modules/courses/coursesPublic/sendResource.js b/public/react/src/modules/courses/coursesPublic/sendResource.js index fbc2ebeb2..48677a8e1 100644 --- a/public/react/src/modules/courses/coursesPublic/sendResource.js +++ b/public/react/src/modules/courses/coursesPublic/sendResource.js @@ -1,5 +1,5 @@ import React,{ Component } from "react"; -import { Modal,Checkbox,Upload,Button,Icon,message,DatePicker,Select,Tooltip} from "antd"; +import { Modal,Checkbox,Upload,Button,Icon,message,DatePicker,Select,Tooltip,Radio} from "antd"; import axios from 'axios'; import Modals from '../../modals/Modals'; import {getUrl,handleDateString,bytesToSize,appendFileSizeToUploadFileAll} from 'educoder'; @@ -40,7 +40,6 @@ class Sendresource extends Component{ ModalSave:"", fileListtype:false, loadtype:false, - is_unified_setting:true, is_public:false, datatime:undefined, // moment(new Date()).format('YYYY-MM-DD HH:mm:ss'), @@ -50,30 +49,15 @@ class Sendresource extends Component{ publish_time :"" }], course_groups:undefined, - course_groups_count:undefined + course_groups_count:undefined, + Radiovalue:0, + Radiovaluetype:false } } componentDidMount() { - let coursesId=this.props.match.params.coursesId; - if(this.props.isAdmin()){ - let url = `/courses/${coursesId}/all_course_groups.json` - - axios.get(url, { - }) - .then((response) => { - this.setState({ - course_groups: response.data.course_groups, - course_groups_count:response.data.course_groups_count - }) - }) - .catch(function (error) { - console.log(error); - }); - } - } //勾选实训 @@ -101,37 +85,6 @@ class Sendresource extends Component{ } } - // onAttachmentRemove = (file) => { - // - // this.setState({ - // fileListtype:false, - // }) - // // confirm({ - // // title: '确定要删除这个附件吗?', - // // okText: '确定', - // // cancelText: '取消', - // // // content: 'Some descriptions', - // // onOk: () => { - // // this.deleteAttachment(file) - // // }, - // // onCancel() { - // // console.log('Cancel'); - // // }, - // // }); - // // return false; - // - // // this.setState({ - // // Modalstype:true, - // // Modalstopval:'确定要删除这个附件吗?', - // // ModalSave: ()=>this.deleteAttachment(file), - // // ModalCancel:this.cancelAttachment - // // }) - // // return false; - // - // this.deleteAttachment(file); - // } - - onAttachmentRemove = (file) => { if(!file.percent || file.percent == 100){ const url = `/attachments/${file.response ? file.response.id : file.uid}.json` @@ -174,8 +127,7 @@ class Sendresource extends Component{ } Saves=()=>{ - let id=this.props.categoryid; - let {fileList,description,is_public,is_unified_setting,datatime,course_group_publish_times} =this.state; + let {fileList,description,is_public,datatime,Radiovalue} =this.state; let newfileList=[]; for(var list of fileList){ @@ -188,17 +140,19 @@ class Sendresource extends Component{ }) return } - // if(is_unified_setting===false){ - // course_group_publish_times.forEach((item,key)=>{ - // if(item.course_group_id===undefined||item.publish_time===undefined){ - // this.setState({ - // course_group_publish_timestype:true - // }) - // return - // } - // }) - // - // } + + if(this.state.Radiovalue===1){ + if(datatime===undefined||datatime===null||datatime=== ""){ + this.setState({ + Radiovaluetype:true + }) + return + }else{ + this.setState({ + Radiovaluetype:false + }) + } + } @@ -222,22 +176,14 @@ class Sendresource extends Component{ course_second_category_id:this.props.coursesidtype===undefined||this.props.coursesidtype==="node"?0:attachmentId, attachment_ids:newfileList, is_public:is_public, - is_unified_setting:is_unified_setting, - publish_time:is_unified_setting===true?datatime===undefined? moment(new Date()).format('YYYY-MM-DD HH:mm'):datatime:undefined, + publish_time:Radiovalue===1?datatime===undefined? undefined:datatime:undefined, description:description, - course_group_publish_times:is_unified_setting===false?course_group_publish_times:undefined + delay_publish:Radiovalue, }).then((result)=>{ if(result.data.status===0){ - // this.setState({ - // Modalstype:true, - // Modalstopval:result.data.message, - // ModalSave:this.ModalCancelModalCancel, - // loadtype:true - // }) this.ModalCancelModalCancel(); this.props.updataleftNavfun(); - // this.props.showNotification(result.data.message); this.props.showNotification("上传资源成功"); this.props.setupdate(this.props.attachmentId) } @@ -253,14 +199,6 @@ class Sendresource extends Component{ }) } - onChangesetting=(e)=>{ - - this.setState({ - is_unified_setting:e.target.checked - }) - - } - onChangepublic=(e)=>{ this.setState({ @@ -289,50 +227,20 @@ class Sendresource extends Component{ } - selectassigngroups=(e,index,key)=>{ - let {course_group_publish_times}=this.state; - let newgroup_publish=course_group_publish_times; - for(var i=0; i{ + if(e.target.value===0){ + this.setState({ + datatime:undefined + }) } this.setState({ - course_group_publish_times:newgroup_publish, - }) + Radiovalue: e.target.value, + }); } - - deletegrouppublish=(key)=>{ - let newlist=this.state.course_group_publish_times; - newlist.splice(key,1); - this.setState({ - course_group_publish_times:newlist - }) - } - - addgrouppublish=()=>{ - let newlist=this.state.course_group_publish_times; - newlist.push( { - course_group_id : undefined, - publish_time :undefined - }) - this.setState({ - course_group_publish_times:newlist - }) - } - render(){ - let {settextarea,newfileListtype,descriptiontype, - course_group_publish_timestype, - Modalstopval, - ModalCancel, - ModalSave, - loadtype, - is_unified_setting, + let { newfileListtype,descriptiontype, is_public, datatime, - course_group_publish_times, - course_groups }=this.state; const uploadProps = { @@ -350,7 +258,11 @@ class Sendresource extends Component{ return isLt150M; }, }; - + const radioStyle = { + display: 'block', + height: '30px', + lineHeight: '30px', + }; return(
    {/*提示*/} @@ -389,6 +301,7 @@ class Sendresource extends Component{ margin-right: 5px; } .ant-upload-list-item:hover .ant-upload-list-item-info{ + padding: 0 12px 0 0px; background-color:#fff; } .upload_1 .ant-upload-list { @@ -437,42 +350,12 @@ class Sendresource extends Component{ - (单个文件最大150M) + (单个文件最大150M) :""}

    - {/**/} - {/*{this.state.fileList.length===0?"":this.state.fileList.map((item,key)=>{*/} - {/*debugger*/} - {/*return(*/} - {/*

    */} - {/**/} - {/**/} - {/**/} - {/**/} - {/*{item.name}*/} - {/**/} - {/**/} - {/*{item.response===undefined?"":isNaN(bytesToSize(item.filesize))?"":bytesToSize(item.filesize)}*/} - {/**/} - {/*this.onAttachmentRemove(item.response===undefined?"":item.response.id&&item.response.id)}>*/} - {/*

    */} - {/*)*/} - {/*})}*/} + {newfileListtype===true&&this.state.fileListtype===false?

    请先上传资源

    :""} @@ -484,13 +367,12 @@ class Sendresource extends Component{ } `} - {/*
    */} - {/*勾选后所有用户可见,否则仅课堂成员可见*/} - {/**/} + {this.props.course_is_public===true?
    + 公开: + 选中,所有用户可见,否则课堂成员可见 + +
    :""} - {this.state.course_groups_count&&this.state.course_groups_count>0? - 统一设置(选中则所有分班使用相同的发布设置,否则各个单独设置) - :""} -
    - {is_unified_setting===false? - course_group_publish_times.map((item,key)=>{ - return( -
    - - - - this.onChangeTimepublish(e,index,key,2)} - // onChange={ this.onChangeTimepublish } - disabledTime={disabledDateTime} - disabledDate={disabledDate} - /> - {key!=0?this.deletegrouppublish(key)}>:""} - {key===course_group_publish_times.length-1&&key:""} -
    - ) - }) - - :""} -
    -

    - {is_unified_setting===true?

    - - this.onChangeTimepublish(e,index,undefined,1)} - disabledTime={disabledDateTime} - disabledDate={disabledDate} - /> - -

    :""} + +
    + 发布设置: + + + 立即发布 + + + 延迟发布 + this.onChangeTimepublish(e,index,undefined,1)} + disabledTime={disabledDateTime} + disabledDate={disabledDate} + disabled={this.state.Radiovalue===1?false:true} + /> + + (按照设置的时间定时发布) + +
    + {/*{course_group_publish_timestype===true?

    请填写完整

    :""}*/} {descriptiontype===true?

    请输入资源描述,最大限制100个字符

    :""} + {this.state.Radiovaluetype===true?

    发布时间不能为空

    :""}
    {this.props.Cancelname} this.Saves()}>{this.props.Savesname} diff --git a/public/react/src/modules/courses/css/Courses.css b/public/react/src/modules/courses/css/Courses.css index 12c4e8d3e..160104920 100644 --- a/public/react/src/modules/courses/css/Courses.css +++ b/public/react/src/modules/courses/css/Courses.css @@ -1701,4 +1701,47 @@ input.ant-input-number-input:focus { /*}*/ .yslinputcourput .ant-form-explain{ padding-left: 0px !important; +} +.wechatloginfont{ + font-size: 14px; + font-family: PingFangSC-Regular,PingFangSC; + font-weight: 400; + color: #555555; + line-height: 20px; + margin-top: 10px; +} + +.wechatdiv{ + margin-top: 40px !important; + width: 800px !important; +} + +.wechatContent{ + padding: 0px 50px; +} + +.wechatpass{ + width: 300px; + height: 46px; +} + +.wechatnewchat{ + width: 62px; + height: 62px; + background: rgba(255,170,170,1); + border-radius: 50%; + text-align: center; + line-height: 62px; + color: #fff; + margin: 0 auto; +} +.wechatweoldchat{ + width: 62px; + height: 62px; + background:rgba(164,211,255,1); + border-radius: 50%; + text-align: center; + line-height: 62px; + color: #fff; + margin: 0 auto; } \ No newline at end of file diff --git a/public/react/src/modules/courses/exercise/ExerciseNew.js b/public/react/src/modules/courses/exercise/ExerciseNew.js index 80f837686..0c2542569 100644 --- a/public/react/src/modules/courses/exercise/ExerciseNew.js +++ b/public/react/src/modules/courses/exercise/ExerciseNew.js @@ -57,8 +57,9 @@ class ExerciceNew extends Component{ const courseId=this.props.match.params.coursesId; - const isEdit = this.isEdit - + const isEdit = this.isEdit; + + document.title=this.props.coursedata&&this.props.coursedata.name; return(
    diff --git a/public/react/src/modules/courses/exercise/ExerciseReviewAndAnswer.js b/public/react/src/modules/courses/exercise/ExerciseReviewAndAnswer.js index 75da4f2fe..2eaf03b92 100644 --- a/public/react/src/modules/courses/exercise/ExerciseReviewAndAnswer.js +++ b/public/react/src/modules/courses/exercise/ExerciseReviewAndAnswer.js @@ -612,6 +612,7 @@ class ExerciseReviewAndAnswer extends Component{ let isStudent =this.props.isStudent(); const { current_user } = this.props // console.log(data&&data.exercise.user_name) + document.title=courseName&&courseName.name; return(
    diff --git a/public/react/src/modules/courses/exercise/Exercisesetting.js b/public/react/src/modules/courses/exercise/Exercisesetting.js index 7b3732c9f..42cafc2d6 100644 --- a/public/react/src/modules/courses/exercise/Exercisesetting.js +++ b/public/react/src/modules/courses/exercise/Exercisesetting.js @@ -350,6 +350,7 @@ class Exercisesetting extends Component{ this.commitSetting((result)=>{ + console.log(result) if(result.status==200){ this.props.showNotification(`${result.data.message}`); this.getSettingInfo(); @@ -369,6 +370,7 @@ class Exercisesetting extends Component{ } this.commitSetting((result)=>{ + console.log(result) if(result.status==200){ this.props.showNotification(`${result.data.message}`); this.cancelEdit(); @@ -702,7 +704,9 @@ class Exercisesetting extends Component{
    : div > .ant-spin .ant-spin-dot { top: 72%;} } + .ysltableows2 .ant-table-thead > tr > th, .ant-table-tbody > tr > td { + padding: 9px; + } + mysjysltable1 .ant-table-thead > tr > th, .ant-table-tbody > tr > td { + padding: 9px; + } `} -
    +
    {data === undefined ? "" : div > .ant-spin .ant-spin-dot { top: 72%;} } + .ysltableows2 .ant-table-thead > tr > th, .ant-table-tbody > tr > td { + padding: 9px; + } + mysjysltable2 .ant-table-thead > tr > th, .ant-table-tbody > tr > td { + padding: 9px; + } `} -
    +
    {datas === undefined ? "" :
    tr > td{ height: 58px; } - .ysltableows .ant-table-thead > tr > th, .ant-table-tbody > tr > td { + .ysltableows .ant-table-thead > tr > th, .ant-table-tbody > tr > td { + padding: 9px; + } + mysjysltable3 .ant-table-thead > tr > th, .ant-table-tbody > tr > td { padding: 9px; } ` @@ -2828,7 +2843,7 @@ class Studentshavecompletedthelist extends Component { {data === undefined ? "" :
    tr > th, .ant-table-tbody > tr > td { padding: 9px; } + mysjysltable4 .ant-table-thead > tr > th, .ant-table-tbody > tr > td { + padding: 9px; + } `}
    {datas === undefined ? "" :
    { - // console.log("Commonheadofthetestpaper"); + console.log("Commonheadofthetestpaper 试卷公用头部"); var exercise_id = this.props.match.params.Id; var url = `/exercises/${exercise_id}/common_header.json`; axios.get(url).then((response) => { @@ -249,6 +249,28 @@ class Testpapersettinghomepage extends Component{ // DownloadMessageval:undefined // }) // } + getsetdata =()=>{ + // console.log("Testpapersettinghomepage"); + // console.log("getsetdatassssss"); + let{tab}=this.state; + try { + if(tab[0]==="0"){ + this.child.Teacherliststudentlist(); + } + if(tab[0]==="1"){ + this.child.Teacherliststudentlist(); + } + if(tab[0]==="2"){ + this.child.Teacherliststudentlist(); + } + if(tab[0]==="3"){ + this.child.getSettingInfo(); + } + }catch (e) { + + } + + } bindRef = ref => { this.child = ref }; goback=()=>{ // let {datalist}=this.state; @@ -271,7 +293,7 @@ class Testpapersettinghomepage extends Component{ // TODO // console.log(Commonheadofthetestpaper.exercise_status); - + document.title=this.props.coursedata&&this.props.coursedata.name; return(
    {/* :"":""} {isAdmin === true? 编辑试卷:""} diff --git a/public/react/src/modules/courses/graduation/tasks/GraduationTaskDetail.js b/public/react/src/modules/courses/graduation/tasks/GraduationTaskDetail.js index b9830d1fc..e7924f469 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduationTaskDetail.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduationTaskDetail.js @@ -20,89 +20,89 @@ import Modals from '../../../modals/Modals'; //毕设描述 const GraduationTasksquestions= Loadable({ - loader: () => import('./GraduationTaskssettingquestions'), - loading: Loading, + loader: () => import('./GraduationTaskssettingquestions'), + loading: Loading, }) //毕设任务设置 const GraduationTaskssetting=Loadable({ - loader: () => import('./GraduationTaskssetting'), - loading: Loading, + loader: () => import('./GraduationTaskssetting'), + loading: Loading, }) //毕设任务列表 const GraduationTaskslist=Loadable({ - loader: () => import('./GraduationTaskssettinglist'), - loading: Loading, + loader: () => import('./GraduationTaskssettinglist'), + loading: Loading, }) class GraduationTaskDetail extends Component{ - constructor(props){ - super(props); - this.state={ - modalname:undefined, - visible:false, + constructor(props){ + super(props); + this.state={ + modalname:undefined, + visible:false, Topval:undefined, starttime:undefined, starttimes:undefined, typs:undefined, - endtime:undefined, - Cancelname:undefined, - Savesname:undefined, - Cancel:undefined, - Saves:undefined, - Topvalright:undefined, - Botvalleft:undefined, - course_groupslist:undefined, - course_groups:undefined, - questionslist:undefined, - tab:"list", - visibles:undefined, - Modalstype:undefined, - Modalstopval:undefined, - ModalCancel:undefined, - ModalSave:undefined, - acrossVisible:undefined - } - } - componentDidMount(){ - this.getdatas() - } - getdatas=()=>{ - const task_Id = this.props.match.params.task_Id; - let url="/graduation_tasks/"+task_Id+".json"; - - axios.get(url).then((result)=>{ - if(result.status===200){ - this.setState({ - questionslist:result.data - }) - - } - }).catch((error)=>{ - console.log(error) - }) - } - - - // 交叉评阅设置弹框 - openAcross=()=>{ - this.setState({ - acrossVisible:true - }) - } - closeAcross=()=>{ - this.setState({ - acrossVisible:false - }) + endtime:undefined, + Cancelname:undefined, + Savesname:undefined, + Cancel:undefined, + Saves:undefined, + Topvalright:undefined, + Botvalleft:undefined, + course_groupslist:undefined, + course_groups:undefined, + questionslist:undefined, + tab:"list", + visibles:undefined, + Modalstype:undefined, + Modalstopval:undefined, + ModalCancel:undefined, + ModalSave:undefined, + acrossVisible:undefined + } + } + componentDidMount(){ this.getdatas() - } + } + getdatas=()=>{ + const task_Id = this.props.match.params.task_Id; + let url="/graduation_tasks/"+task_Id+".json"; + axios.get(url).then((result)=>{ + if(result.status===200){ + this.setState({ + questionslist:result.data + }) + + } + }).catch((error)=>{ + console.log(error) + }) + } - //返回 - goback=()=>{ - // let courseId=this.props.match.params.coursesId; - // let category_id=this.props.match.params.category_id; - // window.location.href="/courses/"+courseId+"/graduation_tasks/"+category_id; + // 交叉评阅设置弹框 + openAcross=()=>{ + this.setState({ + acrossVisible:true + }) + } + closeAcross=()=>{ + this.setState({ + acrossVisible:false + }) + this.getdatas() + } + + + + //返回 + goback=()=>{ + // let courseId=this.props.match.params.coursesId; + // let category_id=this.props.match.params.category_id; + // window.location.href="/courses/"+courseId+"/graduation_tasks/"+category_id; // let courseId = this.props.match.params.coursesId; // if(courseId===undefined){ // this.props.history.push("/courses"); @@ -112,66 +112,66 @@ class GraduationTaskDetail extends Component{ // this.props.history.goBack() this.props.history.replace(`/courses/${this.state.questionslist.course_id}/graduation_tasks/${this.state.questionslist.graduation_id}`); - } - //立即发布 - publish=()=>{ - let starttime= this.props.getNowFormatDates(1,1); - let endtime=this.props.getNowFormatDates(2,1); - // this.homeworkstart() - this.setState({ - modalname:"立即发布", - visible:true, + } + //立即发布 + publish=()=>{ + let starttime= this.props.getNowFormatDates(1,1); + let endtime=this.props.getNowFormatDates(2,1); + // this.homeworkstart() + this.setState({ + modalname:"立即发布", + visible:true, Topval:"学生将立即收到毕设任务", - // Botvalleft:"点击修改", + // Botvalleft:"点击修改", // Botval:`本操作只对"未发布"的分班有效`, starttime:moment(moment(new Date())).format("YYYY-MM-DD HH:mm") , starttimes:this.props.getNowFormatDates(1), typs:"start", - endtime:endtime, - Cancelname:"暂不发布", - Savesname:"立即发布", - Cancel:this.cancelmodel, - Saves:this.homepublish, - }) - } - // 确定立即发布 - homepublish=(ids,endtime)=>{ - this.cancelmodel(); - let task_Id=this.props.match.params.task_Id; - const cid = this.props.match.params.coursesId; - // let url = `/courses/${cid}/graduation_tasks/publish_task.json`; - - let url="/courses/"+cid+"/graduation_tasks/publish_task.json" - axios.post(url,{ - task_ids:[task_Id], - group_ids: this.state.course_groupslist, + endtime:endtime, + Cancelname:"暂不发布", + Savesname:"立即发布", + Cancel:this.cancelmodel, + Saves:this.homepublish, + }) + } + // 确定立即发布 + homepublish=(ids,endtime)=>{ + this.cancelmodel(); + let task_Id=this.props.match.params.task_Id; + const cid = this.props.match.params.coursesId; + // let url = `/courses/${cid}/graduation_tasks/publish_task.json`; + + let url="/courses/"+cid+"/graduation_tasks/publish_task.json" + axios.post(url,{ + task_ids:[task_Id], + group_ids: this.state.course_groupslist, end_time:endtime, - }).then((response)=>{ - if (response.data.status == 0) { + }).then((response)=>{ + if (response.data.status == 0) { this.getdatas() - this.props.showNotification(response.data.message); - - this.setState({ - // Modalstopval:response.data.message, - // ModalSave:this.cancelmodel, - // Loadtype:true, - course_groupslist:[], - checkAllValue:false - }) - } - }).catch((error)=>{ - - }) - } - - // 刷新 - resetList=()=>{ - this.getdatas(); - this.child && this.child.searchValue(); - } - - // 立即截止 - end=()=>{ + this.props.showNotification(response.data.message); + + this.setState({ + // Modalstopval:response.data.message, + // ModalSave:this.cancelmodel, + // Loadtype:true, + course_groupslist:[], + checkAllValue:false + }) + } + }).catch((error)=>{ + + }) + } + + // 刷新 + resetList=()=>{ + this.getdatas(); + this.child && this.child.searchValue(); + } + + // 立即截止 + end=()=>{ // this.homeworkstart() this.setState({ modalname:"立即截止", @@ -185,74 +185,74 @@ class GraduationTaskDetail extends Component{ Saves:this.coursetaskend, typs:"end", }) - } - coursetaskend=()=>{ - const coursesId = this.props.match.params.coursesId; - const task_Id = this.props.match.params.task_Id; - - let url = `/courses/${coursesId}/graduation_tasks/end_task.json`; - axios.post(url,{ - task_ids:[task_Id], - group_ids: this.state.course_groupslist, - }).then((response)=>{ - if (response.data.status == 0) { - this.props.showNotification(response.data.message); - this.cancelmodel(); - this.getdatas(); - this.child && this.child.reInit(); - } - - }).catch((error)=>{ - - }) - } - // 取消 - cancelmodel=()=>{ - this.setState({ - Modalstype:false, - Loadtype:false, - visible:false, - Modulationtype:false, - Allocationtype:false, - Modalstopval:"", - ModalCancel:"", - ModalSave:"", - }) - } - - getcourse_groupslist=(id)=>{ - this.setState({ - course_groupslist:id - }) - } - - setTab = (tab) =>{ - this.setState({ - tab - }) - } - - // 关联项目 - AssociationItems=()=>{ + } + coursetaskend=()=>{ + const coursesId = this.props.match.params.coursesId; + const task_Id = this.props.match.params.task_Id; + + let url = `/courses/${coursesId}/graduation_tasks/end_task.json`; + axios.post(url,{ + task_ids:[task_Id], + group_ids: this.state.course_groupslist, + }).then((response)=>{ + if (response.data.status == 0) { + this.props.showNotification(response.data.message); + this.cancelmodel(); + this.getdatas(); + this.child && this.child.reInit(); + } + + }).catch((error)=>{ + + }) + } + // 取消 + cancelmodel=()=>{ + this.setState({ + Modalstype:false, + Loadtype:false, + visible:false, + Modulationtype:false, + Allocationtype:false, + Modalstopval:"", + ModalCancel:"", + ModalSave:"", + }) + } + + getcourse_groupslist=(id)=>{ + this.setState({ + course_groupslist:id + }) + } + + setTab = (tab) =>{ + this.setState({ + tab + }) + } + + // 关联项目 + AssociationItems=()=>{ this.setState({ visibles:true }) - } - Cancel=()=>{ + } + Cancel=()=>{ this.setState({ visibles:false }) - } - // 取消关联 - cannelAssociation=()=>{ + } + // 取消关联 + cannelAssociation=()=>{ this.setState({ Modalstype:true, Modalstopval:"确定要取消该项目关联?", ModalCancel:this.cannerassocition, ModalSave:this.savetassociton }) - } - savetassociton=()=>{ + } + savetassociton=()=>{ this.cannerassocition(); let {questionslist}=this.state; let url = "/graduation_tasks/"+questionslist.task_id+"/graduation_works/cancel_relate_project.json"; @@ -266,7 +266,7 @@ class GraduationTaskDetail extends Component{ }) } - cannerassocition=()=>{ + cannerassocition=()=>{ this.setState({ Modalstype:false, Modalstopval:"", @@ -275,10 +275,10 @@ class GraduationTaskDetail extends Component{ loadtype:false, visibles:false }) - } - // 补交附件 - handaccessory=()=>{ - // let {taskslistdata}=this.state; + } + // 补交附件 + handaccessory=()=>{ + // let {taskslistdata}=this.state; // let courseId=this.props.match.params.coursesId; // // let url="/courses/"+courseId+"/graduation_tasks/"+taskslistdata.work_id+"/appraise" @@ -292,129 +292,131 @@ class GraduationTaskDetail extends Component{ this.setState({ avisible:false }) - } - - - bindRef = ref => { this.child = ref } ; - render(){ - - let courseId=this.props.match.params.coursesId; - let category_id=this.props.match.params.category_id; - let task_Id=this.props.match.params.task_Id; - let { - questionslist , - tab , - visibles , - Modalstype, - Modalstopval, - ModalCancel, - ModalSave, - acrossVisible - } = this.state - - const commom = { - setTab:this.setTab, - getdatas:this.getdatas - } - return( -
    - { - questionslist && -
    - this.getcourse_groupslist(id)} - /> - {/*关联项目*/} - {visibles===true? - this.Cancel()} - taskid={ questionslist && questionslist.task_id } - funlist={this.resetList} - /> - :""} - - {this.state.avisible===true?:""} - {/*提示*/} - - - { - acrossVisible && - - } - -

    - {questionslist.course_name} - > - {questionslist.graduation_name} - > - 任务详情 -

    -
    -

    - {questionslist.task_name} -

    - - 返回 -
    -
    -
    - - 任务列表 - 毕设描述 - 设置 - - {/*导出成绩*/} - {/*{this.props.isAdmin()?导出成绩:""}*/} - {/*{this.props.isAdmin()?导出作品附件:""}*/} - - - {this.props.isAdmin()?
  • - 导出 - -
  • :""} - {questionslist.work_status===undefined||questionslist.work_status===null||questionslist.work_status.length===0?"":questionslist.work_status.map((item,key)=>{ - return( - + + {this.props.isAdmin()?
  • + 导出 + +
  • :""} + {questionslist.work_status===undefined||questionslist.work_status===null||questionslist.work_status.length===0?"":questionslist.work_status.map((item,key)=>{ + return( + {item==="提交作品"?提交作品:""} - {item==="补交作品"?补交作品:""} - {item==="修改作品"?修改作品:""} - {item==="查看作品"?查看作品 :""} - {item==="创建项目"?创建项目:""} - {item==="关联项目"?关联项目:""} - {item==="取消关联"?取消关联:""} - {item==="补交附件"?补交附件:""} + {item==="补交作品"?补交作品:""} + {item==="修改作品"?修改作品:""} + {item==="查看作品"?查看作品 :""} + {item==="创建项目"?创建项目:""} + {item==="关联项目"?关联项目:""} + {item==="取消关联"?取消关联:""} + {item==="补交附件"?补交附件:""} - ) - })} - - {/*项目在线质量检测*/} - { this.props.isAdmin() ? questionslist.status===1 ? { this.end()} }>立即截止 : "" : "" } - { this.props.isAdmin() ? questionslist.status===0 ? { this.publish()} }>立即发布 : "" : "" } - { this.props.isAdmin() && questionslist.cross_comment ? 交叉评阅设置 : "" } - { this.props.isAdmin() ? 编辑任务 : "" } -
    -
    - - - () - } - > - - () - } - > - - () - }> - - -
    - } - -
    - ) - } + ) + })} + + {/*项目在线质量检测*/} + { this.props.isAdmin() ? questionslist.status===1 ? { this.end()} }>立即截止 : "" : "" } + { this.props.isAdmin() ? questionslist.status===0 ? { this.publish()} }>立即发布 : "" : "" } + { this.props.isAdmin() && questionslist.cross_comment ? 交叉评阅设置 : "" } + { this.props.isAdmin() ? 编辑任务 : "" } +
    + + + + () + } + > + + () + } + > + + () + }> + + + + } + + + ) + } } // CNotificationHOC() ( SnackbarHOC() ( TPMIndexHOC)) export default (GraduationTaskDetail) ; \ No newline at end of file diff --git a/public/react/src/modules/courses/graduation/tasks/GraduationTasksSubmitedit.js b/public/react/src/modules/courses/graduation/tasks/GraduationTasksSubmitedit.js index 02e7177fa..bf371baab 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduationTasksSubmitedit.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduationTasksSubmitedit.js @@ -537,7 +537,7 @@ class GraduationTasksSubmitedit extends Component{ }, }; - + document.title=workslist&&workslist.course_name; return( diff --git a/public/react/src/modules/courses/graduation/tasks/GraduationTasksSubmitnew.js b/public/react/src/modules/courses/graduation/tasks/GraduationTasksSubmitnew.js index 698ab5c97..140d743b9 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduationTasksSubmitnew.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduationTasksSubmitnew.js @@ -560,10 +560,10 @@ render(){ }, }; - console.log(this.props) - + // console.log(this.props) + document.title=workslist&&workslist.course_name; return( diff --git a/public/react/src/modules/courses/graduation/tasks/GraduationTasksappraise.js b/public/react/src/modules/courses/graduation/tasks/GraduationTasksappraise.js index f0bead58f..2f9b28ef5 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduationTasksappraise.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduationTasksappraise.js @@ -146,6 +146,8 @@ class GraduationTasksappraise extends Component{ let graduation_id=datalist===undefined?"":datalist.graduation_id; let task_id=datalist===undefined?"":datalist.task_id; // console.log(datalist); + + document.title=datalist&&datalist.course_name; return( diff --git a/public/react/src/modules/courses/graduation/tasks/GraduationTasksedit.js b/public/react/src/modules/courses/graduation/tasks/GraduationTasksedit.js index 962edcde5..8b480258d 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduationTasksedit.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduationTasksedit.js @@ -328,7 +328,7 @@ class GraduationTasksedit extends Component{ }; - + document.title=this.props.current_user&&this.props.current_user.course_name; return( diff --git a/public/react/src/modules/courses/graduation/tasks/GraduationTasksnew.js b/public/react/src/modules/courses/graduation/tasks/GraduationTasksnew.js index 84b9b096b..5358bfe9e 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduationTasksnew.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduationTasksnew.js @@ -313,6 +313,7 @@ class GraduationTasksnew extends Component { }; // this.ifHasAnchorJustScorll(); // console.log(this.props.current_user.course_name) + document.title=this.props.current_user&&this.props.current_user.course_name; return ( diff --git a/public/react/src/modules/courses/graduation/tasks/index.js b/public/react/src/modules/courses/graduation/tasks/index.js index 9dac05a36..0660d9c2f 100644 --- a/public/react/src/modules/courses/graduation/tasks/index.js +++ b/public/react/src/modules/courses/graduation/tasks/index.js @@ -473,7 +473,7 @@ class GraduationTasks extends Component{ checkAllValue:false }) this.publishcanner(); - debugger + let {search,page,order} = this.state this.fetchAll(search,page,order); } diff --git a/public/react/src/modules/courses/graduation/topics/GraduateTopicDetail.js b/public/react/src/modules/courses/graduation/topics/GraduateTopicDetail.js index 65b093d2b..b4bcaf0fa 100644 --- a/public/react/src/modules/courses/graduation/topics/GraduateTopicDetail.js +++ b/public/react/src/modules/courses/graduation/topics/GraduateTopicDetail.js @@ -100,7 +100,7 @@ class GraduateTopicDetail extends Component{ let {course_id,graduation_topic_id}=this.props.match.params; const isStudent =this.props.isStudent(); const isAdmin =this.props.isAdmin(); - + document.title=tableData && tableData.course_name; return(
    diff --git a/public/react/src/modules/courses/graduation/topics/GraduateTopicNew.js b/public/react/src/modules/courses/graduation/topics/GraduateTopicNew.js index ba2ab53d9..b086efeda 100644 --- a/public/react/src/modules/courses/graduation/topics/GraduateTopicNew.js +++ b/public/react/src/modules/courses/graduation/topics/GraduateTopicNew.js @@ -323,6 +323,7 @@ class GraduateTopicNew extends Component{ }; // console.log("dfsf"); // console.log(this.props); + document.title=course_name===undefined?"":course_name; return(
    + { isAdmin && +
  • + 导出 + +
  • + } + + } + secondRowLeft={ + total_count ? : '' + } + onPressEnter={onPressEnter} + > + + {!!none_group_member_count &&
    + 未分班: + {none_group_member_count}个学生 + + {props.history.push(`/courses/${courseId}/course_groups/0`)}}>查看 +
    } + + + {course_groups && !!course_groups.length ? +
    + + + +
    : + } +
    + + ) +} +export default CourseGroupList \ No newline at end of file diff --git a/public/react/src/modules/courses/members/CourseGroupListTable.js b/public/react/src/modules/courses/members/CourseGroupListTable.js new file mode 100644 index 000000000..656ae67bc --- /dev/null +++ b/public/react/src/modules/courses/members/CourseGroupListTable.js @@ -0,0 +1,234 @@ +import React, { useState, useEffect } from 'react' + +import { Input,Checkbox,Table, Pagination, Modal,Menu ,Spin, Tooltip , Badge, Popconfirm } from "antd"; +import axios from 'axios' + +import { WordsBtn, trigger, on, off, getUrl, downloadFile , sortDirections } from 'educoder' +import ClipboardJS from 'clipboard' + +/** + 角色数组, CREATOR: 创建者, PROFESSOR: 教师, ASSISTANT_PROFESSOR: 助教, STUDENT: 学生 + course_members_count: 0 + id: 2441 + invite_code: "WUNX9K" + member_manager: "全部教师" + name: "e'e'e" +*/ + +const clipboardMap = {} +function CourseGroupListTable(props) { + const [serachValue, setSerachValue] = useState('') + + const courseId = props.match.params.coursesId + + useEffect(() => { + const course_groups = props.course_groups + if (!course_groups) { + return; + } + course_groups.forEach((record) => { + const id = record.id + let _clipboard = new ClipboardJS(`.copyBtn_${id}`); + _clipboard.on('success', (e) => { + props.showNotification('复制成功') + }); + clipboardMap[id] = _clipboard + }) + return () => { + course_groups.forEach((record) => { + const id = record.id + + if (clipboardMap[id]) { + clipboardMap[id].destroy(); + clipboardMap[id] = null; + } + }) + } + }, [props.course_groups]) + function buildColumns() { + const columns=[{ + title: '序号', + dataIndex: 'id', + key: 'id', + align:'center', + width:"5%", + className:"color-grey-6", + render: (id, record, index) => { + return index + 1 + } + }, + { + title: '分班名称', + dataIndex: 'name', + key: 'name', + align:'center', + width:"25%", + className:"color-grey-6", + render: (name, record, index) => { + return 11 ? name : ''} onClick={() => onGoDetail(record)} style={''} + className="overflowHidden1" style2={{maxWidth: '180px', verticalAlign: 'bottom'}}> + {name} + } + }, + + { + title: '学生成员', + dataIndex: 'course_members_count', + key: 'course_members_count', + align:'center', + width:"8%", + className:"color-grey-6", + render: (course_members_count, record, index) => { + return course_members_count + } + } + ]; + if (!isNotMember) { + columns.push({ + title: '管理教师', + dataIndex: 'member_manager', + key: 'member_manager', + align:'center', + width:"27%", + className:"color-grey-6", + render: (member_manager, record, index) => { + return {record.subStringOfMember_manager || member_manager} + } + }) + const aCol = (isAdmin ? { + title: '邀请码', + dataIndex: 'invite_code', + key: 'invite_code', + align:'center', + width:"10%", + className:"color-grey-6", + render: (invite_code, record, index) => { + return invite_code + } + } : { + title: '你当前所在分班', + dataIndex: 'group', + key: 'group', + align:'center', + width:"20%", + className:"color-grey-6", + render: (invite_code, record, index) => { + return props.current_group_id == record.id && + } + }) + columns.push( aCol ); + } + + columns.push({ + title: '操作', + dataIndex: 'setting', + key: 'setting', + align:'center', + width:"25%", + className:"color-grey-6", + render: (none, record, index) => { + return + {!isCourseEnd && isAdmin && onDelete(record)} style={'grey'}>删除分班} + {isAdmin && 复制邀请码 } + {isStudent && addToDir(record)} style={''}>加入分班} + onGoDetail(record)} style={''}>查看 + + } + }) + + return columns + } + const doAddToDir = async (record) => { + const courseId = props.match.params.coursesId + const url = `/courses/${courseId}/join_course_group.json` + const course_group_id = record.id + + const response = await axios.post(url, { + course_group_id + }) + if (response && response.data.status == 0) { + props.showNotification(`已加入分班:${record.name}`) + props.updataleftNavfun() + props.onOperationSuccess && props.onOperationSuccess() + } + } + const addToDir = (record) => { + props.confirm({ + + content: `是否确认加入分班: ${record.name}?`, + + okText: '确认', + cancelText: '取消', + + onOk: () => { + doAddToDir(record) + }, + onCancel() { + console.log('Cancel'); + }, + }); + } + + function onDelete(record) { + props.confirm({ + content:
    +
    该分班的学生将被移动到“未分班”
    +
    是否确认删除?
    +
    , + onOk: () => { + // const cid = this.props.match.params.coursesId + + const url = `/course_groups/${record.id}.json` + axios.delete(url) + .then((response) => { + if (response.data.status == 0) { + props.showNotification('删除成功') + props.onOperationSuccess && props.onOperationSuccess() + // props.history.push(response.data.right_url) + } + }) + .catch(function (error) { + console.log(error); + }); + } + }) + } + function onGoDetail(record) { + props.history.push(`/courses/${courseId}/course_groups/${record.id}`) + } + const isAdmin = props.isAdmin(); + const isSuperAdmin = props.isSuperAdmin(); + const isStudent = props.isStudent() + const isNotMember = props.isNotMember() + + + const isParent = true; + const isCourseEnd= props.isCourseEnd(); + + const course_groups = props.course_groups + const columns = buildColumns() + const dataSource = course_groups.map(item => { + return { + ...item, + subStringOfMember_manager : (item.member_manager && item.member_manager.length > 92) + ? item.member_manager.substring(0, 92) + '...' : null + } + }) + return ( + + + {/* onChange={onTableChange} */} +
    + + + ) +} +export default CourseGroupListTable \ No newline at end of file diff --git a/public/react/src/modules/courses/members/studentsList.css b/public/react/src/modules/courses/members/studentsList.css index ebab316a0..797305629 100644 --- a/public/react/src/modules/courses/members/studentsList.css +++ b/public/react/src/modules/courses/members/studentsList.css @@ -1,3 +1,4 @@ -.stu_table .ant-table-thead > tr > th, .stu_table .ant-table-tbody > tr > td { +.stu_table .ant-table-thead > tr > th, .stu_table .ant-table-tbody > tr > td, +.courseGroupList .ant-table-thead > tr > th, .courseGroupList .ant-table-tbody > tr > td { padding: 14px 6px; } \ No newline at end of file diff --git a/public/react/src/modules/courses/members/studentsList.js b/public/react/src/modules/courses/members/studentsList.js index 3a5a55b71..8a223ce91 100644 --- a/public/react/src/modules/courses/members/studentsList.js +++ b/public/react/src/modules/courses/members/studentsList.js @@ -107,7 +107,7 @@ const buildColumns = (that,isParent) => { } ]; if (course_groups && course_groups.length) { - columns.push({ + this.isStudentPage && columns.push({ title: '分班', dataIndex: 'course_group_name', key: 'course_group_name', @@ -130,7 +130,7 @@ const buildColumns = (that,isParent) => { } const isAdmin = that.props.isAdmin() if (isAdmin) { - columns.unshift({ + !that.isStudentPage && columns.unshift({ title: '', dataIndex: 'check', key: 'check', @@ -148,8 +148,9 @@ const buildColumns = (that,isParent) => { render: (text, record) => { return ( - that.onDelete(record)} style={'grey'}>删除学生 - that.onDelete(record)} style={'grey'}>删除学生 + {record.member_roles && record.member_roles.length && { showNotification={that.props.showNotification} getUserId={that.props.isUserid} fetchUser={that.props.fetchUser} - > + >} ) }, @@ -319,6 +320,9 @@ class studentsList extends Component{ isAdmin && on('updateNavSuccess', this.updateNavSuccess) } componentWillUnmount() { + if (this.clipboard) { + this.clipboard.destroy() + } const isAdmin = this.props.isAdmin() if (isAdmin) { off('addStudentSuccess', this.addStudentSuccessListener) @@ -330,6 +334,7 @@ class studentsList extends Component{ } updateNavSuccess = () => { this.fetchCourseGroups() + this.fetchAll() } addStudentSuccessListener=(e, data)=>{ @@ -418,12 +423,14 @@ class studentsList extends Component{ invite_code: result.data.invite_code, isSpin:false }, () => { - if (!this.clipboard) { - const clipboard = new ClipboardJS('.copybtn'); - clipboard.on('success', (e) => { - this.props.showNotification('复制成功') - }); - this.clipboard = clipboard + if (course_group_id) { + if (!this.clipboard) { + const clipboard = new ClipboardJS('.copybtn'); + clipboard.on('success', (e) => { + this.props.showNotification('复制成功') + }); + this.clipboard = clipboard + } } }) } @@ -547,7 +554,7 @@ class studentsList extends Component{ addDir = () => { trigger('groupAdd', this.props.coursesids) } - addToDir = async () => { + doAddToDir = async () => { const courseId = this.props.match.params.coursesId const url = `/courses/${courseId}/join_course_group.json` const course_group_id = this.props.match.params.course_group_id @@ -556,11 +563,27 @@ class studentsList extends Component{ course_group_id }) if (response && response.data.status == 0) { - this.props.showNotification('加入成功') + this.props.showNotification(`已加入分班:${this.state.course_group_name}`) this.props.updataleftNavfun() this.fetchAll() } } + addToDir = (record) => { + this.props.confirm({ + + content: `是否确认加入分班: ${this.state.course_group_name}?`, + + okText: '确认', + cancelText: '取消', + + onOk: () => { + this.doAddToDir() + }, + onCancel() { + console.log('Cancel'); + }, + }); + } renameDir = () => { const course_group_id = this.props.match.params.course_group_id trigger('groupRename', { id: parseInt(course_group_id), name: this.state.course_group_name}) @@ -572,15 +595,15 @@ class studentsList extends Component{
    是否确认删除?
    , onOk: () => { - // const cid = this.props.match.params.coursesId const course_group_id = this.props.match.params.course_group_id + const courseId = this.props.match.params.coursesId const url = `/course_groups/${course_group_id}.json` axios.delete(url) .then((response) => { if (response.data.status == 0) { this.props.showNotification('删除成功') - this.props.history.push(response.data.right_url) + this.props.history.push(`/courses/${courseId}/course_groups`) } }) .catch(function (error) { @@ -666,11 +689,14 @@ class studentsList extends Component{ if (this.props.match.path.endsWith('students')) { } else if (course_group_id) { - pageType = TYPE_COURSE_GOURP_PARENT - } else { pageType = TYPE_COURSE_GOURP_CHILD + } else { + pageType = TYPE_COURSE_GOURP_PARENT } - + // 本页面有2个状态,学生列表、具体分班 + const isStudentPage = pageType == TYPE_STUDENTS + this.isStudentPage = isStudentPage + const isGroupChildPage = pageType == TYPE_COURSE_GOURP_CHILD return( @@ -683,7 +709,12 @@ class studentsList extends Component{ - {course_group_name || '未分班'} + + + { this.props.history.push(`/courses/${courseId}/course_groups`)}} + style={{color: '#212121', verticalAlign: 'initial', marginRight: '14px' }} + > + {course_group_name || '未分班'} {isAdmin && invite_code && 邀请码: @@ -708,23 +739,24 @@ class studentsList extends Component{ searchPlaceholder={ '请输入姓名、学号进行搜索' } firstRowRight={ - { + {/* { // pageType !== TYPE_STUDENTS && - isSuperAdmin && + !isStudentPage && isSuperAdmin && this.refs['createGroupByImportModal'].setVisible(true)}>导入创建分班 - } + } */} + { - // pageType !== TYPE_STUDENTS && - !isCourseEnd && isAdmin && isParent && this.addDir()}>添加分班 } + !isStudentPage && isAdmin && !isParent && course_group_id != 0 && this.deleteDir()}>删除分班 } { - isStudent && !isParent && course_group_id != 0 && this.addToDir()}>加入分班 } + !isStudentPage && isAdmin && !isParent && course_group_id != 0 && this.renameDir()}>分班重命名 } { - isAdmin && !isParent && course_group_id != 0 && this.deleteDir()}>删除分班 } + !isStudentPage && !isCourseEnd && isAdmin && this.addDir()}>新建分班 } + { - isAdmin && !isParent && course_group_id != 0 && this.renameDir()}>分班重命名 } + !isStudentPage && isStudent && !isParent && course_group_id != 0 && this.addToDir()}>加入分班 } { rules && rules.length > 0 && rules.map((rule,r)=>{ @@ -383,28 +389,29 @@ class PollDetailTabForthRules extends Component{ `.ant-select{ min-width:200px, min-heigth:200px - }` + } + ` } - +

    { rule.class_flag && rule.class_flag!=""?{rule.class_flag}:"" @@ -413,7 +420,9 @@ class PollDetailTabForthRules extends Component{

    - + diff --git a/public/react/src/modules/courses/poll/PollInfo.js b/public/react/src/modules/courses/poll/PollInfo.js index bb019c4a4..b7d0a59dd 100644 --- a/public/react/src/modules/courses/poll/PollInfo.js +++ b/public/react/src/modules/courses/poll/PollInfo.js @@ -301,6 +301,7 @@ class PollInfo extends Component{ const { current_user } = this.props let isAdmin=this.props.isAdmin(); let isStudent=this.props.isStudent(); + document.title=courseName&&courseName; return(
    {/*

    */} diff --git a/public/react/src/modules/courses/poll/PollNew.js b/public/react/src/modules/courses/poll/PollNew.js index 5aa7f8f72..10a9b00c7 100644 --- a/public/react/src/modules/courses/poll/PollNew.js +++ b/public/react/src/modules/courses/poll/PollNew.js @@ -2765,6 +2765,7 @@ class PollNew extends Component { // console.log(this.state.projects===undefined?"":this.state.projects.poll_questions) var displaymysave = (mysave === true) ? "" : "display:none;"; + document.title=this.props.coursedata&&this.props.coursedata.name; return (
    {/*提示*/} diff --git a/public/react/src/modules/courses/poll/pollPublicBtn/ImmediatelyPublish.js b/public/react/src/modules/courses/poll/pollPublicBtn/ImmediatelyPublish.js index c7585a390..9644acfde 100644 --- a/public/react/src/modules/courses/poll/pollPublicBtn/ImmediatelyPublish.js +++ b/public/react/src/modules/courses/poll/pollPublicBtn/ImmediatelyPublish.js @@ -89,6 +89,7 @@ class Immediatelypublish extends Component{ Cancel:this.homeworkhide, Saves:this.homeworkstartend, }) + } }).catch((error) => { console.log(error) @@ -135,7 +136,8 @@ class Immediatelypublish extends Component{ } - } + } + } //取消提示弹框 @@ -189,7 +191,18 @@ class Immediatelypublish extends Component{ this.homeworkhide(); // 调用父级公共头部的接口刷新 - this.props.action() + try { + this.props.action(); + }catch (e) { + + } + // 调用父级刷新数据的接口刷新 + try { + this.props.getsetdata() + }catch (e) { + + } + } }).catch((error)=>{ console.log(error); @@ -274,7 +287,7 @@ class Immediatelypublish extends Component{ modalSave={this.modalCancel} > - 立即发布 + this.homeworkstart()}>立即发布 ) } diff --git a/public/react/src/modules/courses/publicNav/listNav.js b/public/react/src/modules/courses/publicNav/listNav.js index dba39b37c..c980e693f 100644 --- a/public/react/src/modules/courses/publicNav/listNav.js +++ b/public/react/src/modules/courses/publicNav/listNav.js @@ -74,7 +74,7 @@ class ListNav extends Component{

    资源列表

  • - 添加目录 + 新建目录 导入资源 上传资源
  • diff --git a/public/react/src/modules/courses/shixunHomework/CommitSummary.js b/public/react/src/modules/courses/shixunHomework/CommitSummary.js index 129e020e9..5d48f11d9 100644 --- a/public/react/src/modules/courses/shixunHomework/CommitSummary.js +++ b/public/react/src/modules/courses/shixunHomework/CommitSummary.js @@ -121,6 +121,7 @@ class CommitSummary extends Component{ const {getFieldDecorator} = this.props.form; let {contents,data}=this.state; // console.log(this.props); + document.title=data === undefined ? "" :data.course_name===undefined?"": data.course_name; return (
    diff --git a/public/react/src/modules/courses/shixunHomework/Listofworksstudentone.js b/public/react/src/modules/courses/shixunHomework/Listofworksstudentone.js index 5eed392d5..03f0dea64 100644 --- a/public/react/src/modules/courses/shixunHomework/Listofworksstudentone.js +++ b/public/react/src/modules/courses/shixunHomework/Listofworksstudentone.js @@ -80,6 +80,7 @@ class Listofworksstudentone extends Component { teacherdata: undefined, task_status: [], visibles: false, + starttimesend:undefined, course_group_info: [], styletable: { "display": "none" @@ -459,7 +460,7 @@ class Listofworksstudentone extends Component { ), }, ], - orders: "", + orders: "update_time", columnsstu2: [ { title: '序号', @@ -2238,9 +2239,9 @@ class Listofworksstudentone extends Component { var homeworkid = this.props.match.params.homeworkid; let urll = `/homework_commons/${homeworkid}/works_list.json?`; var order = "asc"; - // if (ordervlue === "update_time") { - // order = "desc"; - // } + if (ordervlue === "update_time") { + order = "desc"; + } var checkedValuesines = checkedValuesine; var checkedValuesineinfos = checkedValuesineinfo; var searchtexts = searchtext @@ -2652,15 +2653,15 @@ class Listofworksstudentone extends Component { } //排序 funordert = (e) => { - // if (e === "update_time") { - // // 时间 - // // 时间排序是从小到大 - // this.setState({ - // orders: "update_time", - // loadingstate: true, - // }) - // this.Startsortingt("update_time", this.state.course_groupyslstwo, this.state.checkedValuesineinfo, this.state.searchtext, this.state.page, this.state.limit); - // } + if (e === "update_time") { + // 时间 + // 时间排序是从小到大 + this.setState({ + orders: "update_time", + loadingstate: true, + }) + this.Startsortingt("update_time", this.state.course_groupyslstwo, this.state.checkedValuesineinfo, this.state.searchtext, this.state.page, this.state.limit); + } if (e === "work_score") { // 成绩 @@ -2789,6 +2790,7 @@ class Listofworksstudentone extends Component { axios.get(url).then((response) => { if (response.status === 200) { + const dataformat = 'YYYY-MM-DD HH:mm'; let starttime = this.props.getNowFormatDates(1); let endtime = this.props.getNowFormatDates(2); this.setState({ @@ -2801,6 +2803,7 @@ class Listofworksstudentone extends Component { starttime: "发布时间:" + moment(moment(new Date())).format("YYYY-MM-DD HH:mm"), endtime: "截止时间:" + endtime, starttimes:starttime, + starttimesend:response.data.end_time===undefined||response.data.end_time===null||response.data.end_time===""?undefined:response.data.end_time, typs:"start", Cancelname: "暂不发布", Savesname: "立即发布", @@ -2949,6 +2952,7 @@ class Listofworksstudentone extends Component { course_groupyslstwo: undefined, typs:undefined, starttimes:undefined, + starttimesend:undefined, }) } @@ -3170,6 +3174,7 @@ class Listofworksstudentone extends Component { course_groups={this.state.course_groups} getcourse_groupslist={(id) => this.getcourse_groupslist(id)} starttimes={this.state.starttimes} + starttimesend={this.state.starttimesend} typs={this.state.typs} /> { @@ -3357,10 +3362,10 @@ class Listofworksstudentone extends Component {
    • - {orders === "work_score" ? "成绩" : orders === "student_id" ? "学号" : ""}排序 + {orders === "update_time" ? "时间" :orders === "work_score" ? "成绩" : orders === "student_id" ? "学号" : ""}排序 diff --git a/public/react/src/modules/courses/shixunHomework/ShixunHomeworkPage.js b/public/react/src/modules/courses/shixunHomework/ShixunHomeworkPage.js index 9b0353b9e..0983e0fa6 100644 --- a/public/react/src/modules/courses/shixunHomework/ShixunHomeworkPage.js +++ b/public/react/src/modules/courses/shixunHomework/ShixunHomeworkPage.js @@ -61,9 +61,9 @@ class ShixunHomeworkPage extends Component { } Getdataback = (jobsettingsdata, teacherdata) => { - // console.log("56"); - // console.log(jobsettingsdata); - // console.log(teacherdata); + console.log("ShixunHomeworkPage56"); + console.log(jobsettingsdata); + console.log(teacherdata); this.setState({ jobsettingsdatapage: jobsettingsdata.data.message===undefined?jobsettingsdata:undefined, @@ -182,6 +182,7 @@ class ShixunHomeworkPage extends Component { const isAdmin = this.props.isAdmin(); // console.log(119) // console.log(jobsettingsdatapage); + document.title=jobsettingsdatapage === undefined ? "" : jobsettingsdatapage.data.course_name; return (
      { if(response.status===200){ + const dataformat = 'YYYY-MM-DD HH:mm'; let starttime= this.props.getNowFormatDates(1); let endtime=this.props.getNowFormatDates(2); this.setState({ @@ -432,6 +434,7 @@ class ShixunStudentWork extends Component { Saves:this.homeworkstartend, course_groups:response.data.course_groups, starttimes:starttime, + starttimesend:response.data.end_time===undefined||response.data.end_time===null||response.data.end_time===""?undefined:response.data.end_time, typs:"start", }) } @@ -754,6 +757,7 @@ class ShixunStudentWork extends Component { course_groups={this.state.course_groups} getcourse_groupslist={(id)=>this.getcourse_groupslist(id)} starttimes={this.state.starttimes} + starttimesend={this.state.starttimesend} typs={this.state.typs} />
      diff --git a/public/react/src/modules/courses/shixunHomework/ShixunWorkDetails.js b/public/react/src/modules/courses/shixunHomework/ShixunWorkDetails.js index 8254b148e..7cdab81a6 100644 --- a/public/react/src/modules/courses/shixunHomework/ShixunWorkDetails.js +++ b/public/react/src/modules/courses/shixunHomework/ShixunWorkDetails.js @@ -95,6 +95,7 @@ class ShixunWorkDetails extends Component { } render() { let{data}=this.state; + document.title=data&&data.course_name; return (
      diff --git a/public/react/src/modules/courses/shixunHomework/ShixunWorkReport.js b/public/react/src/modules/courses/shixunHomework/ShixunWorkReport.js index 2667f1dd9..88682c5a6 100644 --- a/public/react/src/modules/courses/shixunHomework/ShixunWorkReport.js +++ b/public/react/src/modules/courses/shixunHomework/ShixunWorkReport.js @@ -310,7 +310,7 @@ class ShixunWorkReport extends Component { // let showAppraiseModals=this.props&&this.props.isAdminOrTeacher()===true?work_comment===null||work_comment===undefined?false:true:work_comment===null||work_comment===undefined?false:true; let showAppraiseModals=work_comment===null||work_comment===undefined?false:true; - + document.title=data&&data.course_name; return ( data===undefined?"": diff --git a/public/react/src/modules/courses/shixunHomework/ShixunhomeWorkItem.js b/public/react/src/modules/courses/shixunHomework/ShixunhomeWorkItem.js index 88d143011..4a985a2b6 100644 --- a/public/react/src/modules/courses/shixunHomework/ShixunhomeWorkItem.js +++ b/public/react/src/modules/courses/shixunHomework/ShixunhomeWorkItem.js @@ -304,8 +304,8 @@ class ShixunhomeWorkItem extends Component{
      + {this.props.isAdmin?this.stopPro(event)} className={this.props.isAdminOrCreator()?"homepagePostSetting homepagePostSettingname":"homepagePostSetting homepagePostSettingbox"} style={{"right":"-2px","top":"6px","display":"block"}}> + 实训详情 + {this.props.isAdminOrCreator()?this.editname(discussMessage.name,discussMessage.homework_id,event)} className={"btn colorblue ml20 font-16"}>重命名:""} + {/* 设置*/} + 设置 + :""} + + + {this.props.isStudent===true?this.props.course_identity===5? + + {startbtn===false? + (discussMessage.task_operation[0] == '继续挑战' || discussMessage.task_operation[0] == '查看实战' ? + + {discussMessage.task_operation[0]} + + : + this.taskoperationId(discussMessage.task_operation[1])}> + {discussMessage.task_operation[0]} + ):开启中} + :"":"" + }
      -

      - +

      + {/* {discussMessage.author.name} */} { discussMessage.author && {discussMessage.author} } {discussMessage.commit_count===undefined?"":已开始做题 {discussMessage.commit_count}人} @@ -381,7 +414,7 @@ class ShixunhomeWorkItem extends Component{ { discussMessage && discussMessage.upper_category_name && 22 }> - { {discussMessage.upper_category_name}} + {

      所属目录:{discussMessage.upper_category_name}
      } } @@ -396,39 +429,6 @@ class ShixunhomeWorkItem extends Component{

      - - {this.props.isAdmin?
      this.stopPro(event)} className={this.props.isAdminOrCreator()?"homepagePostSetting homepagePostSettingname":"homepagePostSetting homepagePostSettingbox"} style={{"right":"-2px","top":"46px","display":"block"}}> - 实训详情 - {this.props.isAdminOrCreator()?this.editname(discussMessage.name,discussMessage.homework_id,event)} className={"btn colorblue ml20 font-16"}>重命名:""} - {/* 设置*/} - 设置 -
      :""} - - - {this.props.isStudent===true?this.props.course_identity===5? - - {startbtn===false? - (discussMessage.task_operation[0] == '继续挑战' || discussMessage.task_operation[0] == '查看实战' ? - - {discussMessage.task_operation[0]} - - : - this.taskoperationId(discussMessage.task_operation[1])}> - {discussMessage.task_operation[0]} - ):开启中} - :"":"" - }
      diff --git a/public/react/src/modules/courses/shixunHomework/Trainingjobsetting.js b/public/react/src/modules/courses/shixunHomework/Trainingjobsetting.js index da1408d4a..2556a910b 100644 --- a/public/react/src/modules/courses/shixunHomework/Trainingjobsetting.js +++ b/public/react/src/modules/courses/shixunHomework/Trainingjobsetting.js @@ -120,7 +120,7 @@ class Trainingjobsetting extends Component { showmodel:false, code_review:false, testscripttiptype:false, - + starttimesend:undefined, end_timebool:false, late_timesbool:false, work_efficiencys:false, @@ -1016,14 +1016,14 @@ class Trainingjobsetting extends Component { this.setState({ completionefficiencyscore: e.target.checked, work_efficiencys:e.target.checked, - latedeductiontwo: 0, + latedeductiontwo: 20, }) //均分比例 if(this.state.proportion==="均分比例"){ - this.Equalproportion(0); + this.Equalproportion(20); }else if(this.state.proportion==="经验值比例"){ - this.Empiricalvalueratio(0); + this.Empiricalvalueratio(20); } @@ -1525,6 +1525,7 @@ class Trainingjobsetting extends Component { axios.get(url).then((response) => { if (response.status === 200) { + const dataformat = 'YYYY-MM-DD HH:mm'; let starttime = this.props.getNowFormatDates(1); let endtime = this.props.getNowFormatDates(2); this.setState({ @@ -1536,7 +1537,8 @@ class Trainingjobsetting extends Component { Botval:`本操作只对"未发布"的分班有效`, starttime: "发布时间:" + moment(moment(new Date())).format("YYYY-MM-DD HH:mm"), starttimes:starttime, - typs:"start", + starttimesend:response.data.end_time===undefined||response.data.end_time===null||response.data.end_time===""?undefined:response.data.end_time, + typs:"start", endtime: "截止时间:" + endtime, Cancelname: "暂不发布", Savesname: "立即发布", @@ -1668,6 +1670,7 @@ class Trainingjobsetting extends Component { addnametab: undefined, typs:undefined, starttimes:undefined, + starttimesend:undefined, }) } cancelBox=()=>{ @@ -1688,6 +1691,7 @@ class Trainingjobsetting extends Component { modalSave: this.cancelBox }) } else { + var releasetime =true; var deadline = true; var endtime =true; @@ -1721,7 +1725,7 @@ class Trainingjobsetting extends Component { flagPageEditstwo:releasetime, flagPageEditsthrees:deadline, flagPageEditsfor:endtime, - completionefficiencyscore:true, + completionefficiencyscore:false, work_efficiencys:this.state.work_efficiencys, unifiedsetting:this.state.unifiedsetting, latedeductiontwo:this.state.latedeductiontwo, @@ -1837,7 +1841,7 @@ class Trainingjobsetting extends Component { flagPageEditstwo:releasetime, flagPageEditsthrees:deadline, flagPageEditsfor:endtime, - completionefficiencyscore:false, + completionefficiencyscore:datas.data.work_efficiency===true?true:false, work_efficiencys:datas.data.work_efficiency, unifiedsetting:datas.data.unified_setting, latedeductiontwo:datas.data.eff_score, @@ -2077,7 +2081,7 @@ class Trainingjobsetting extends Component { // console.log(this.props.isAdmin()) // console.log(this.state.code_review===false) // console.log("引入的分值"); - console.log(this.state.work_efficiencys); + // console.log(this.state.work_efficiencys); @@ -2120,7 +2124,8 @@ class Trainingjobsetting extends Component { course_groups={this.state.course_groups} getcourse_groupslist={(id) => this.getcourse_groupslist(id)} starttimes={this.state.starttimes} - typs={this.state.typs} + starttimesend={this.state.starttimesend} + typs={this.state.typs} /> { if (response.status === 200) { + const dataformat = 'YYYY-MM-DD HH:mm'; let starttime = this.props.getNowFormatDates(1); let endtime = this.props.getNowFormatDates(2); this.setState({ @@ -173,6 +175,7 @@ class Workquestionandanswer extends Component { Saves: this.homeworkstartend, course_groups: response.data.course_groups, starttimes: starttime, + starttimesend:response.data.end_time===undefined||response.data.end_time===null||response.data.end_time===""?undefined:response.data.end_time, typs: "start", }) } @@ -441,6 +444,7 @@ class Workquestionandanswer extends Component { course_groups={this.state.course_groups} getcourse_groupslist={(id) => this.getcourse_groupslist(id)} starttimes={this.state.starttimes} + starttimesend={this.state.starttimesend} typs={this.state.typs} />
      diff --git a/public/react/src/modules/courses/shixunHomework/shixunHomework.js b/public/react/src/modules/courses/shixunHomework/shixunHomework.js index 8e68a7398..415b283f6 100644 --- a/public/react/src/modules/courses/shixunHomework/shixunHomework.js +++ b/public/react/src/modules/courses/shixunHomework/shixunHomework.js @@ -4,6 +4,7 @@ import { WordsBtn,on, off, trigger } from 'educoder'; import {BrowserRouter as Router,Route,Switch,Link} from 'react-router-dom'; import axios from'axios'; import HomeworkModal from "../coursesPublic/HomeworkModal"; +import OneSelfOrderModal from "../coursesPublic/OneSelfOrderModal"; import ShixunModal from "../coursesPublic/ShixunModal"; import PathModal from "../coursesPublic/PathModal"; import NewShixunModel from '../coursesPublic/NewShixunModel'; @@ -132,10 +133,16 @@ class ShixunHomework extends Component{ category:id } }).then((result)=>{ - this.setState({ - isSpin:false, - datas:result.data, - }) + if(result!=undefined){ + this.setState({ + isSpin:false, + datas:result.data, + }) + }else{ + this.setState({ + isSpin:false, + }) + } }).catch((error)=>{ console.log(error); }) @@ -187,19 +194,18 @@ class ShixunHomework extends Component{ category: category_id===undefined?undefined:category_id } }).then((result)=>{ - if(result.status===200){ - // if(checkedtype===true&&page>1){ - // for(var value of result.data.homeworks){ - // checkBoxValues.push(value.homework_id) - // } - // } - this.setState({ - datas:result.data, - isSpin:false - }) - - - } + if(result!=undefined){ + if(result.status===200){ + this.setState({ + datas:result.data, + isSpin:false + }) + } + }else{ + this.setState({ + isSpin:false + }) + } }).catch((error)=>{ console.log(error); }) @@ -227,10 +233,11 @@ class ShixunHomework extends Component{ addnametab:undefined, typs:undefined, starttimes:undefined, + OneSelftype:false }) + this.cancelmodel() + this.homeworkupdatalist(Coursename,page,order); this.props.updataleftNavfun() - this.homeworkupdatalist(Coursename,page,order); - this.cancelmodel() } @@ -272,6 +279,48 @@ class ShixunHomework extends Component{ }); } + + + //立即发布 + homeworkOneSelfstart=()=>{ + let selectnum= this.testonSelect(); + if(selectnum===true){ + this.noSelect(); + return + } + let coursesId=this.props.match.params.coursesId; + let url="/courses/"+coursesId+"/all_course_groups.json"; + + axios.get(url).then((response) => { + + if(response.status===200){ + let starttime= this.props.getNowFormatDates(1); + let endtime=this.props.getNowFormatDates(2); + this.setState({ + modalname:"立即发布", + modaltype:response.data.course_groups===null||response.data.course_groups.length===0?2:1, + OneSelftype:true, + typs:"start", + Topval:"学生将立即收到作业", + // Botvalleft:"暂不发布", + Botval:`本操作只对"未发布"的分班有效`, + starttime:"发布时间:"+moment(moment(new Date())).format("YYYY-MM-DD HH:mm"), + starttimes:starttime, + endtime:"截止时间:"+endtime, + Cancelname:"暂不发布", + Savesname:"立即发布", + Cancel:this.homeworkhide, + Saves:this.homeworkstartend, + course_groups:response.data.course_groups, + }) + } + }).catch((error) => { + console.log(error) + }); + + } + + cancelmodels=()=>{ this.setState({ Modalstype:false, @@ -316,10 +365,12 @@ class ShixunHomework extends Component{ }) } - this.props.showNotification(result.data.message) + + this.homeworkupdatalist(Coursename,page,order); + this.cancelmodel() + this.props.showNotification(result.data.message) this.props.updataleftNavfun() - this.homeworkupdatalist(Coursename,page,order); - this.cancelmodel() + } }).catch((error)=>{ console.log(error); @@ -414,11 +465,11 @@ class ShixunHomework extends Component{ Loadtype:false, course_groups:[] }) - + this.homeworkupdatalist(Coursename,page,order); + this.cancelmodel() this.props.showNotification(response.data.message) this.props.updataleftNavfun() - this.homeworkupdatalist(Coursename,page,order); - this.cancelmodel() + } }) .catch(function (error) { @@ -722,8 +773,8 @@ class ShixunHomework extends Component{ checkedtype:false, antIcon:false }) + this.homeworkupdatalist(Coursename,page,order); this.props.showNotification(response.data.message) - this.homeworkupdatalist(Coursename,page,order); this.props.updataleftNavfun() }else{ this.setState({ @@ -782,6 +833,7 @@ class ShixunHomework extends Component{ this.setState({ Modalstype:false, + OneSelftype:false, Loadtype:false, visible:false, Modalstopval:"", @@ -834,9 +886,10 @@ class ShixunHomework extends Component{ Loadtype:false, checkBoxValues:[] }) + this.homeworkupdatalist(Coursename,page,order); this.props.showNotification(response.data.message) - this.homeworkupdatalist(Coursename,page,order); + } }) .catch(function (error) { @@ -886,9 +939,10 @@ class ShixunHomework extends Component{ checkBoxValues:[], checkAllValue:false }) + this.homeworkupdatalist(Coursename,page,order); this.props.showNotification('已完成') this.props.updataleftNavfun() - this.homeworkupdatalist(Coursename,page,order); + } }) } @@ -1022,7 +1076,7 @@ class ShixunHomework extends Component{ loadtype={this.state.Loadtype} antIcon={this.state.antIcon} />:""} - {/*立即发布*/} + {/*批量立即发布*/} {visible===true?this.getcourse_groupslist(id)} />:""} - + {/*{单个立即发布}*/} + {/*this.getcourse_groupslist(id)}*/} + {/*/>*/} {shixunmodal===true||shixunpath===true? + }

      - {datas&&datas.category_name===undefined||datas&&datas.category_name===null?datas&&datas.main_category_name:datas&&datas.category_name+" 作业列表"} + + {datas&&datas.category_name===undefined||datas&&datas.category_name===null?datas&&datas.main_category_name: + {datas&&datas.category_name} + 作业列表 + } +

    • {datas===undefined?"":datas.homeworks && datas.homeworks.length>1?this.props.isAdminOrCreator()===true?datas&&datas.category_name===undefined||datas&&datas.category_name===null? @@ -1082,7 +1184,7 @@ class ShixunHomework extends Component{ {this.props.isAdmin()===true?datas&&datas.category_name===undefined||datas&&datas.category_name===null? - this.addDir()} className={"mr30 font-16"}>添加目录 + this.addDir()} className={"mr30 font-16"}>新建目录 {/*this.editname(datas&&datas.main_category_name)} className={"mr30"}>目录重命名*/} : this.editDir(datas&&datas.category_name)} className={"mr30 font-16"}>目录重命名:""} @@ -1128,7 +1230,9 @@ class ShixunHomework extends Component{ 已选 {checkBoxValues&&checkBoxValues.length} 个 (不支持跨页勾选)
    • 删除
    • -
    • 立即发布
    • + {/*{checkBoxValues&&checkBoxValues.length>1?
    • 立即发布
    • */} + {/*:
    • 单个立即发布
    • }*/} +
    • 立即发布
    • {/*onClick={this.homeworkstart}*/}
    • 立即截止
    • @@ -1180,7 +1284,7 @@ class ShixunHomework extends Component{ {this.props.isAdmin()?datas&&datas.category_name===undefined||datas&&datas.category_name===null?

      - this.addDir()}>添加目录... + this.addDir()}>新建目录...

      :"":""} diff --git a/public/react/src/modules/forums/MemoDetail.js b/public/react/src/modules/forums/MemoDetail.js index d3007c433..cc206713b 100644 --- a/public/react/src/modules/forums/MemoDetail.js +++ b/public/react/src/modules/forums/MemoDetail.js @@ -27,6 +27,7 @@ import { Tooltip } from 'antd' // import CBreadcrumb from '../courses/common/CBreadcrumb' import { typeNameMap2 } from './MemoNew' +import CaseDetail from "../moop_cases/CaseDetail"; const $ = window.$ function urlStringify(params) { let noParams = true; @@ -673,7 +674,7 @@ class MemoDetail extends Component { const { match, history } = this.props const { memo, recommend_shixun, current_user,author_info } = this.props; const { comments, hasMoreComments, goldRewardDialogOpen } = this.state; - + document.title = memo&&memo.subject!=undefined?memo&&memo.subject:"交流问答"; if (!memo || this.state.memoLoading) { return
      } diff --git a/public/react/src/modules/forums/MemoNew.js b/public/react/src/modules/forums/MemoNew.js index 962e74f22..fbbd88044 100644 --- a/public/react/src/modules/forums/MemoNew.js +++ b/public/react/src/modules/forums/MemoNew.js @@ -18,6 +18,7 @@ import 'antd/lib/select/style/index.css' import TPMMDEditor from '../tpm/challengesnew/TPMMDEditor' import { getUrl, getUploadActionUrl, appendFileSizeToUploadFileAll, appendFileSizeToUploadFile } from 'educoder' +import CaseDetail from "../moop_cases/CaseDetail"; const Option = Select.Option; const $ = window.$; @@ -316,7 +317,8 @@ class MemoNew extends Component { const repertoires = []; const repertoiresTagMap = {} if ( data.tag_list ) { - // data.tag_list.forEach((item, index)=>{ + document.title = "交流问答"; + // data.tag_list.forEach((item, index)=>{ // const tagArray = []; // item.tag.forEach( (tag, index) => { // tagArray.push(tag.name) @@ -362,6 +364,8 @@ class MemoNew extends Component { const tag_list = response.data.tag_list if (tag_list) { // this.setState({...response.data}) + + document.title = response.data.subject; const { content, forum_id, id, repertoire_name, subject, current_user, tag_list, attachments_url, memo_tags, attachments } = response.data; this.initMD(content); diff --git a/public/react/src/modules/forums/MemoTechShare.js b/public/react/src/modules/forums/MemoTechShare.js index de6ba074c..d32bd2e2f 100644 --- a/public/react/src/modules/forums/MemoTechShare.js +++ b/public/react/src/modules/forums/MemoTechShare.js @@ -1,116 +1,116 @@ -import React, { Component } from 'react'; -import { Redirect } from 'react-router'; - -import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom"; - -import PropTypes from 'prop-types'; - -import classNames from 'classnames' - -import Pagination from 'rc-pagination'; - -import { postPaginationHOC } from './PostPaginationHOC' - -import PostItem from './PostItem' - -import ForumsNavTab from './ForumsNavTab' - -// import queryString from 'query-string' -import { queryString } from 'educoder' - -import MemoList from './MemoList' - - -class MemoTechShare extends Component { - constructor(props) { - super(props) - - this.handleLocationChange = this.handleLocationChange.bind(this); - - this.state = { - - } - } - - onPaginationChange(pageNum, pageSize) { - this.props.onPaginationChange(pageNum, pageSize) - } - - componentDidMount() { - // this.handleLocationChange(this.props.history.location); - // this.unlisten = this.props.history.listen(this.handleLocationChange); - } - - componentWillUnmount() { - // this.unlisten(); - } - componentDidUpdate(prevProps) { - if(this.props.match.params.memoType !== prevProps.match.params.memoType) { - // do something - console.log(`memoType changed`) - this.props.fetchMemos(); - } - } - - componentWillReceiveProps(newProps, newContext) { - if (newProps.match.url === this.props.match.url) { - const oldParsed = queryString.parse(this.props.location.search); - const newParsed = queryString.parse(newProps.location.search); - if (!newParsed.page && oldParsed.page || - (oldParsed.order && newParsed.order && oldParsed.order != newParsed.order)) { - this.props.fetchMemos(); - } - console.log('componentWillReceiveProps...') - } - } - - handleLocationChange(location) { - console.log(`- - - location: '${location.pathname}'`); - if (location.pathname) { - if (location.pathname.indexOf('/forums/categories/all') != -1 - && this.props.location.search && this.props.location.search.indexOf('order=') != -1 - && location.search.indexOf('order=') != -1) { - const oldParsed = queryString.parse(this.props.location.search); - const newParsed = queryString.parse(location.search); - if (oldParsed.order != newParsed.order) { // 只有在热门和最新间跳转时,才需要处理 - this.props.fetchMemos(); - } - } - } - } - - renderMemoList() { - - - // const { memo_list, user } = this.props; - // if (!memo_list) { - // return '' - // } - // return memo_list.map( (item, index) => { - - // return ( - // this.setTop(memo)} - // setDown={(memo)=>this.setDown(memo)} memo={item} - // > - // ) - // }) - return this.props.renderMemoList(); - } - - render() { - const { match, history, currentPage, memo_count ,memo_list } = this.props - - return ( - - - this.renderMemoList()} - onPaginationChange={ (pageNum, pageSize) => this.props.onPaginationChange(pageNum, pageSize) } - > - - - ); - } -} - -export default postPaginationHOC() ( MemoTechShare ); +import React, { Component } from 'react'; +import { Redirect } from 'react-router'; + +import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom"; + +import PropTypes from 'prop-types'; + +import classNames from 'classnames' + +import Pagination from 'rc-pagination'; + +import { postPaginationHOC } from './PostPaginationHOC' + +import PostItem from './PostItem' + +import ForumsNavTab from './ForumsNavTab' + +// import queryString from 'query-string' +import { queryString } from 'educoder' + +import MemoList from './MemoList' + + +class MemoTechShare extends Component { + constructor(props) { + super(props) + + this.handleLocationChange = this.handleLocationChange.bind(this); + + this.state = { + + } + } + + onPaginationChange(pageNum, pageSize) { + this.props.onPaginationChange(pageNum, pageSize) + } + + componentDidMount() { + // this.handleLocationChange(this.props.history.location); + // this.unlisten = this.props.history.listen(this.handleLocationChange); + } + + componentWillUnmount() { + // this.unlisten(); + } + componentDidUpdate(prevProps) { + if(this.props.match.params.memoType !== prevProps.match.params.memoType) { + // do something + console.log(`memoType changed`) + this.props.fetchMemos(); + } + } + + componentWillReceiveProps(newProps, newContext) { + if (newProps.match.url === this.props.match.url) { + const oldParsed = queryString.parse(this.props.location.search); + const newParsed = queryString.parse(newProps.location.search); + if (!newParsed.page && oldParsed.page || + (oldParsed.order && newParsed.order && oldParsed.order != newParsed.order)) { + this.props.fetchMemos(); + } + // console.log('componentWillReceiveProps...') + } + } + + handleLocationChange(location) { + console.log(`- - - location: '${location.pathname}'`); + if (location.pathname) { + if (location.pathname.indexOf('/forums/categories/all') != -1 + && this.props.location.search && this.props.location.search.indexOf('order=') != -1 + && location.search.indexOf('order=') != -1) { + const oldParsed = queryString.parse(this.props.location.search); + const newParsed = queryString.parse(location.search); + if (oldParsed.order != newParsed.order) { // 只有在热门和最新间跳转时,才需要处理 + this.props.fetchMemos(); + } + } + } + } + + renderMemoList() { + + + // const { memo_list, user } = this.props; + // if (!memo_list) { + // return '' + // } + // return memo_list.map( (item, index) => { + + // return ( + // this.setTop(memo)} + // setDown={(memo)=>this.setDown(memo)} memo={item} + // > + // ) + // }) + return this.props.renderMemoList(); + } + + render() { + const { match, history, currentPage, memo_count ,memo_list } = this.props + + return ( + + + this.renderMemoList()} + onPaginationChange={ (pageNum, pageSize) => this.props.onPaginationChange(pageNum, pageSize) } + > + + + ); + } +} + +export default postPaginationHOC() ( MemoTechShare ); diff --git a/public/react/src/modules/login/EducoderInteresse.js b/public/react/src/modules/login/EducoderInteresse.js index c69b2195d..75f2c7059 100644 --- a/public/react/src/modules/login/EducoderInteresse.js +++ b/public/react/src/modules/login/EducoderInteresse.js @@ -20,10 +20,8 @@ var newContainer={ top: "0px", bottom: "0px", minHeight: "100%", - overflow:"hidden", - - } +//兴趣页面 class EducoderInteresse extends Component { constructor(props) { super(props); diff --git a/public/react/src/modules/login/EducoderLogin.js b/public/react/src/modules/login/EducoderLogin.js index eed3a9add..680c4bbc7 100644 --- a/public/react/src/modules/login/EducoderLogin.js +++ b/public/react/src/modules/login/EducoderLogin.js @@ -19,6 +19,8 @@ import { notification } from "antd"; import {Link, Switch, Route, Redirect} from 'react-router-dom'; +import { SnackbarHOC,getImageUrl } from 'educoder'; +import { TPMIndexHOC } from '../tpm/TPMIndexHOC'; import '../courses/css/members.css'; import "../courses/common/formCommon.css" import '../courses/css/Courses.css'; @@ -60,7 +62,6 @@ var newContainer={ top: "0px", bottom: "0px", minHeight: "100%", - overflow:"hidden", paddingTop: "40px", } @@ -109,7 +110,8 @@ class EducoderLogin extends Component { } componentDidMount() { - + // console.log("EducoderLogin"); + // console.log(this.props); } Setlogins=(i)=>{ @@ -138,6 +140,9 @@ class EducoderLogin extends Component { render() { let {showbool,loginstatus,logini} = this.state; + console.log("EducoderLogingetHelmetapi"); + console.log(this.props); + // console.log(this.props.mygetHelmetapi); return (
      @@ -149,7 +154,13 @@ class EducoderLogin extends Component { "width": "100%" }}>
      - this.gohome()} src={educodernet}/> + { + this.props.mygetHelmetapi===undefined||this.props.mygetHelmetapi.login_logo_url===null|| this.props.mygetHelmetapi.login_logo_url===undefined? + this.gohome()} src={educodernet}/> + : + this.gohome()} src={getImageUrl(this.props.mygetHelmetapi.login_logo_url)}/> + } +
      @@ -197,8 +208,7 @@ class EducoderLogin extends Component { } } - -export default EducoderLogin; +export default EducoderLogin ; // showbool === 2 ? //
      { + var userAgentInfo = navigator.userAgent; + var Agents = ["Android", "iPhone", + "SymbianOS", "Windows Phone", + "iPad", "iPod"]; + var flag = true; + for (var v = 0; v < Agents.length; v++) { + if (userAgentInfo.indexOf(Agents[v]) > 0) { + flag = false; + break; + } + } + return flag; + } componentDidMount() { + let flag = this.IsPC(); //true为PC端,false为手机端 + this.setState({ + isphone:flag + }) if(this.props.isRender!=undefined){ this.setState({ @@ -506,14 +524,24 @@ class LoginDialog extends Component { getloginurl=(url)=>{ window.location.href = url; }; + openweixinlogin=()=>{ + this.setState({ + weixinlogin:true + }) + } + hideweixinlogin=()=>{ + this.setState({ + weixinlogin:false + }) + } render() { let{open,login,speedy,loginValue,regular,isGoing,isGoingValue,disabled,bottonclass,Phonenumberisnotco, - dialogBox,shortcutnum,disabledType,gaincode,authCodeType,authCodeclass, isRender}=this.state; + dialogBox,shortcutnum,disabledType,gaincode,authCodeType,authCodeclass, isRender,weixinlogin}=this.state; if (isRender === undefined) { isRender = false } - + // console.log(this.props) return ( {this.setNotcompleteds()}} /> + + {this.state.isphone===false?:""} {isRender===true?
      -
      {this.handleDialogClose()}}> +
      {this.handleDialogClose()}}>
      -
        + {weixinlogin===true?"":
        • {this.enter(0)}}>登录
        • {/*
        • {this.register(0)}}>快捷登录
        • */} -
        +
      }
      -
      + {weixinlogin===true?"":
      @@ -611,12 +652,26 @@ class LoginDialog extends Component {

      - {/*

      */} - - {/*———————— 快速登录 ————————*/} - - {/*

      */} - + {this.state.isphone===true?

      + + ———————— 快速登录 ———————— +

      +

      :""} + + } + {weixinlogin===true?:""} + {weixinlogin===true?

      + this.hideweixinlogin()}>返回账号登录 +

      :""}
      {/*快捷登录*/} diff --git a/public/react/src/modules/login/Otherlogin.js b/public/react/src/modules/login/Otherlogin.js new file mode 100644 index 000000000..73f0c6dc6 --- /dev/null +++ b/public/react/src/modules/login/Otherlogin.js @@ -0,0 +1,303 @@ +import React, {Component} from "react"; +import { + Form, + Select, + Input, + Button, + Checkbox, + Upload, + Icon, + message, + Modal, + Table, + Divider, + InputNumber, + Tag, + DatePicker, + Radio, + Tooltip, + notification, + Layout, + Spin +} from "antd"; +import axios from 'axios'; +import { getImageUrl } from 'educoder' +import {Link, Switch, Route, Redirect} from 'react-router-dom'; +import '../courses/css/members.css'; +import "../courses/common/formCommon.css" +import '../courses/css/Courses.css'; +import beijintulogontwo from '../../../src/images/login/beijintulogontwo.png'; +import educodernet from '../../../src/images/login/educodernet.png'; +const { Header, Footer, Sider, Content } = Layout; +//educoder登入页面 +var sectionStyle = { + "height": "100%", + "width": "100%", + "min-width": "1000px", +// makesure here is String确保这里是一个字符串,以下是es6写法 + + +}; +var imgback = { + " background-size":"cover", +"background-repeat":"no-repeat", + backgroundImage: `url(${beijintulogontwo})`, +} +var imgmian ={ + width: "100%", + background: `url(${beijintulogontwo})`, + position: "relative", + +} + +var newContainer={ + // background: `url(${beijintulogontwo})`, + backgroundPosition: "center" , + backgroundRepeat: "no-repeat", + backgroundAttachment: "fixed", + backgroundSize: "100% 100%", + height:" 100%", + width:" 100%", + position: "absolute", + top: "0px", + bottom: "0px", + minHeight: "100%", + paddingTop: "40px", + +} +class Otherlogin extends Component { + constructor(props) { + super(props); + this.state={ + login:undefined, + password:undefined, + data:undefined, + logintypes:undefined, + spinnings:true + } + + } + + + componentDidMount() { + + let url = `/users/get_user_info.json` + axios.get(url).then((result)=> { + console.log(result); + if(result){ + this.setState({ + data:result.data, + spinnings:false + }) + } + }).catch((error)=>{ + this.setState({ + spinnings:false + }) + }) + + + } + + + loginInputonChange=(e)=>{ + if(e.target.value===undefined||e.target.value===""||e.target.value===null){ + + }else{ + if(this.state.logintypes==="username"){ + this.setState({ + logintypes:undefined + }) + } + } + + this.setState({ + login:e.target.value, + }) + } + passwordonChange=(e)=>{ + if(e.target.value===undefined||e.target.value===""||e.target.value===null){ + + }else{ + if(this.state.logintypes==="password"){ + this.setState({ + logintypes:undefined + }) + } + } + + this.setState({ + password:e.target.value, + }) + } + postwechatlogin=(type,username,password)=>{ + + if(type===false){ + if(username===undefined||username===""||username===null){ + this.setState({ + logintypes:"username" + }) + return + } + if(password===undefined||password===""||password===null){ + this.setState({ + logintypes:"password" + }) + return + } + } + let url = "/bind_user.json"; + axios.post(url, { + type: 'wechat', + not_bind:type, + username:username, + password:password + }).then((response) => { + if(response.data.status===0){ + window.location.href="/" + } + }).catch((error) => { + console.log(error) + }); + } + render() { + let {data,logintypes,spinnings} = this.state; + + console.log(logintypes) + return ( +
      + + + +
      +
      +
      + +
      + {data===undefined?"":data.image_url===undefined||data.image_url===null||data.image_url===""?"":} +
      +
      + 为了更好的为您服务,请关联一个EduCoder账号 +
      +
      + +
      + +

      + + +

      + 新用户 +
      + + +
      欢迎来到EduCoder,新用户登录EduCoder可以到“账号管理-安全设置”中绑定手机/邮箱,以后可以用绑定的手机/邮箱,设置的密码登录EduCoder了。
      + 立即体验表示您已经同意我们的 服务协议条款 +
      + +
      +
      + +

      + +

      + + +

      + 老用户 +
      + + +
      已有EduCoder账号,可以输入您的账号和密码,将您的微信账号与EduCoder账号进行绑定。
      + + + + + + + {this.state.logintypes==="username"?请填写账号:this.state.logintypes==="password"?请填写密码:""} +
      + +
      +
      + +

      +
      + +
      +
      +
      © 2019 EduCoder湘ICP备17009477号Trustie   &   IntelliDE inside.
      +
      +
      +
      +
      + ) + } + +} + +export default Otherlogin; diff --git a/public/react/src/modules/login/Otherloginstart.js b/public/react/src/modules/login/Otherloginstart.js new file mode 100644 index 000000000..9b38ea2b9 --- /dev/null +++ b/public/react/src/modules/login/Otherloginstart.js @@ -0,0 +1,52 @@ +import React, { Component } from 'react'; + +import { BrowserRouter as Router, Route, Link } from "react-router-dom"; + +import { Spin } from 'antd'; +import axios from 'axios'; +class Otherloginstart extends Component { + + componentDidMount() { + let query=this.props.location.search; + const type = query.split('?code='); + const types = type[1].split('&state='); + let codeurl = `/auth/wechat/callback.json` + axios.get(codeurl,{params:{ + code:types[0] + }}).then((result)=> { + if(result){ + if(result.data.status===0){ + if(result.data.new_user===true){ + window.location.href="/otherlogin" + }else{ + // this.getinfo() + window.location.href="/" + } + } + } + }).catch((error)=>{ + + }) + + } + + render() { + // Loading + return ( +
      + + +
      + ); + } +} + +export default Otherloginstart; \ No newline at end of file diff --git a/public/react/src/modules/modals/SendTopics.js b/public/react/src/modules/modals/SendTopics.js index 265bcc7d7..94f134f3f 100644 --- a/public/react/src/modules/modals/SendTopics.js +++ b/public/react/src/modules/modals/SendTopics.js @@ -10,7 +10,8 @@ class SendTopics extends Component{ search:null, Radiolist:undefined, showcheck:false, - smallisSpin:false + smallisSpin:false, + yslbanksMenu:undefined } } @@ -18,8 +19,13 @@ class SendTopics extends Component{ componentDidMount(){ - let{search}=this.state; - this.onupdatalist(search) + // console.log("SendTopicssssssssssss"); + // console.log(this.props); + let{search}=this.state; + this.onupdatalist(search) + this.setState({ + yslbanksMenu:this.props.banksMenu, + }) } onupdatalist=(search)=>{ @@ -49,6 +55,8 @@ class SendTopics extends Component{ onChange=(e)=>{ + console.log("SendTopics"); + console.log(e); this.setState({ Radiolist:e.target.value }) @@ -78,9 +86,60 @@ class SendTopics extends Component{ smallisSpin:false }) if(result.data.status===0){ - this.props.showNotification(result.data.message) - this.props.topicscancelmodel() - this.props.updataslist() + this.props.showNotification(result.data.message); + this.props.topicscancelmodel(); + // result.data.task_ids; + + try { + this.props.updataslist() + }catch (e) { + + } +debugger + if(this.props.mysendall===true){ + //详情页面跳过来的 + try { + var rurls=""; + if(this.state.yslbanksMenu.category==="normal"){ + //普通作业 + rurls=`/courses/${this.state.Radiolist}/common_homeworks/${result.data.task_ids}/setting`; + }else if(this.state.yslbanksMenu.category==="group"){ + //分组作业 + rurls=`/courses/${this.state.Radiolist}/group_homeworks/${result.data.task_ids}/setting`; + }else if(this.state.yslbanksMenu.category==="exercise"){ + // 试卷 + rurls=`/courses/${this.state.Radiolist}/exercises/${result.data.task_ids}/student_exercise_list?tab=3`; + }else if(this.state.yslbanksMenu.category==="poll") { + //问卷 + rurls=`/courses/${this.state.Radiolist}/polls/${result.data.task_ids}/detail?tab=3` + } + window.open(rurls,'_blank'); + }catch (e) { + + } + }else{ + //外部多个列表页跳过来的 + debugger + try { + var rurls=""; + if(this.props.category==="normal"){ + //普通作业 + rurls=`/courses/${this.state.Radiolist}/common_homeworks/${result.data.category_id}`; + }else if(this.props.category==="group"){ + //分组作业 + rurls=`/courses/${this.state.Radiolist}/group_homeworks/${result.data.category_id}`; + }else if(this.props.category==="exercise"){ + // 试卷 + rurls=`/courses/${this.state.Radiolist}/exercises/${result.data.category_id}`; + }else if(this.props.category==="poll") { + //问卷 + rurls=`/courses/${this.state.Radiolist}/polls/${result.data.category_id}` + } + window.open(rurls,'_blank'); + }catch (e) { + console.log(e); + } + } }else{ this.props.showNotification(result.data.message) } diff --git a/public/react/src/modules/moop_cases/CaseDetail.js b/public/react/src/modules/moop_cases/CaseDetail.js index e99f6bab0..20e57f3e9 100644 --- a/public/react/src/modules/moop_cases/CaseDetail.js +++ b/public/react/src/modules/moop_cases/CaseDetail.js @@ -65,6 +65,7 @@ class CaseDetail extends Component{ modalsTopval, modalsBottomval, } = this.state; + document.title = CaseDetail&&CaseDetail.title!=undefined?CaseDetail&&CaseDetail.title:"教学案例"; return(
      { diff --git a/public/react/src/modules/moop_cases/CaseList.js b/public/react/src/modules/moop_cases/CaseList.js index 626b06eb8..b4fdfddd0 100644 --- a/public/react/src/modules/moop_cases/CaseList.js +++ b/public/react/src/modules/moop_cases/CaseList.js @@ -31,6 +31,7 @@ class CaseList extends Component{ } componentDidMount = () =>{ + window.document.title = '教学案例' let { type , search , page , pageSize } = this.state; this.InitList(type,search,page,pageSize); } diff --git a/public/react/src/modules/moop_cases/CaseNew.js b/public/react/src/modules/moop_cases/CaseNew.js index 925536a1a..ce322252a 100644 --- a/public/react/src/modules/moop_cases/CaseNew.js +++ b/public/react/src/modules/moop_cases/CaseNew.js @@ -130,9 +130,12 @@ class CaseNew extends Component{ // 编辑时加载数据 componentDidMount=()=>{ + if(this.props.match.params.caseID){ this.InitEditData(); - } + }else{ + window.document.title = '教学案例' + } let url=`/library_tags.json`; axios.get(url).then((result) => { console.log(result) diff --git a/public/react/src/modules/moop_cases/index.js b/public/react/src/modules/moop_cases/index.js index 7134b66bf..8ac4aa33f 100644 --- a/public/react/src/modules/moop_cases/index.js +++ b/public/react/src/modules/moop_cases/index.js @@ -47,7 +47,7 @@ class Index extends Component{ } } componentDidMount(){ - window.document.title = '教学案例' + } // 获取案例详情 getDetail = (caseID) =>{ @@ -64,6 +64,7 @@ class Index extends Component{ tags:result.data.tags, attachments:result.data.attachments }) + window.document.title = result.data.title; } }).catch((error)=>{ console.log(error); diff --git a/public/react/src/modules/paths/PathDetail/DetailCards.js b/public/react/src/modules/paths/PathDetail/DetailCards.js index 2c4020d9a..6bc972a03 100644 --- a/public/react/src/modules/paths/PathDetail/DetailCards.js +++ b/public/react/src/modules/paths/PathDetail/DetailCards.js @@ -199,12 +199,13 @@ class DetailCards extends Component{ this.props.showLoginDialog() return } - // if(this.props.checkIfProfileCompleted()===false){ - // this.setState({ - // AccountProfiletype:true - // }) - // return - // } + + if(this.props.checkIfProfileCompleted()===false){ + this.props.showProfileCompleteDialog() + return + } + + // if(this.props.checkIfProfessionalCertification()===false){ // this.props.showProfileCompleteDialog() // return diff --git a/public/react/src/modules/paths/PathDetail/DetailTop.js b/public/react/src/modules/paths/PathDetail/DetailTop.js index bf8c46e8f..06fbf82cd 100644 --- a/public/react/src/modules/paths/PathDetail/DetailTop.js +++ b/public/react/src/modules/paths/PathDetail/DetailTop.js @@ -248,16 +248,10 @@ class DetailTop extends Component{ this.props.showLoginDialog() return } - // if(this.props.checkIfProfileCompleted()===false){ - // this.setState({ - // AccountProfiletype:true - // }) - // return - // } - // if(this.props.checkIfProfessionalCertification()===false){ - // this.props.showProfileCompleteDialog() - // return - // } + if(this.props.checkIfProfileCompleted()===false){ + this.props.showProfileCompleteDialog() + return + } this.setState({ @@ -272,16 +266,10 @@ class DetailTop extends Component{ this.props.showLoginDialog() return } - // if(this.props.checkIfProfileCompleted()===false){ - // this.setState({ - // AccountProfiletype:true - // }) - // return - // } - // if(this.props.checkIfProfessionalCertification()===false){ - // this.props.showProfileCompleteDialog() - // return - // } + if(this.props.checkIfProfileCompleted()===false){ + this.props.showProfileCompleteDialog() + return + } this.setState({ Modalstype:true, diff --git a/public/react/src/modules/paths/PathDetail/PathDetailIndex.js b/public/react/src/modules/paths/PathDetail/PathDetailIndex.js index 25437c09e..f66539c99 100644 --- a/public/react/src/modules/paths/PathDetail/PathDetailIndex.js +++ b/public/react/src/modules/paths/PathDetail/PathDetailIndex.js @@ -227,6 +227,8 @@ class PathDetailIndex extends Component{ pathtopskey:key===undefined?1:key, // items: getItems(result.data.members.length), }) + + document.title=result.data.name; } }).catch((error)=>{ diff --git a/public/react/src/modules/paths/ShixunPathSearch.js b/public/react/src/modules/paths/ShixunPathSearch.js index 8323cd607..7f052c166 100644 --- a/public/react/src/modules/paths/ShixunPathSearch.js +++ b/public/react/src/modules/paths/ShixunPathSearch.js @@ -64,6 +64,7 @@ class ShixunPathSearch extends Component{ componentDidMount(){ + document.title="实践课程"; const upsystem=`/users/system_update.json`; axios.get(upsystem).then((response)=>{ let updata=response.data; diff --git a/public/react/src/modules/tpm/NewFooter.js b/public/react/src/modules/tpm/NewFooter.js index be1a1ed29..5d2403a04 100644 --- a/public/react/src/modules/tpm/NewFooter.js +++ b/public/react/src/modules/tpm/NewFooter.js @@ -39,16 +39,23 @@ class NewFooter extends Component {
    -

    - © 2019 EduCoder - 湘ICP备17009477号 - - 湘公网安备43019002000962号 - - Trustie   &   IntelliDE inside. + © 2019 EduCoder + 湘ICP备17009477号 + + 湘公网安备43019002000962号 + + Trustie   &   IntelliDE inside. 版权所有 湖南智擎科技有限公司 -

    +

    + : +
    + + } +
    diff --git a/public/react/src/modules/tpm/NewHeader.js b/public/react/src/modules/tpm/NewHeader.js index de8fade26..29b6baa04 100644 --- a/public/react/src/modules/tpm/NewHeader.js +++ b/public/react/src/modules/tpm/NewHeader.js @@ -65,13 +65,26 @@ class NewHeader extends Component { showTrial:false, setevaluatinghides:false, occupation:0, - mydisplay:false + mydisplay:false, + headtypesonClickbool:false, + headtypess:"/", + mygetHelmetapi2:undefined, } - // console.log("176") + console.log("176") // console.log(props); + // console.log("NewHeader1234567890"); + // console.log(this.props); } - + componentDidUpdate = (prevProps) => { + // console.log("componentDidMount2"); + // console.log(this.state.mygetHelmetapi2); + if(this.state.mygetHelmetapi2===undefined){ + this.getAppdata(); + } + } componentDidMount() { + console.log("componentDidMount1"); + this.getAppdata(); window._header_componentHandler = this; //下拉框的显示隐藏 @@ -633,11 +646,80 @@ submittojoinclass=(value)=>{ this.setState({ AccountProfiletype:false }) + }; + headtypesonClick=(url,bool)=>{ + this.setState({ + headtypess:url, + headtypesonClickbool:bool, + }) } + getAppdata=()=>{ + // console.log("开始刷新数据了") + let url = "/setting.json"; + axios.get(url).then((response) => { + // console.log("axios.get"); + // console.log(response); + + if(response){ + if(response.data){ + this.setState({ + mygetHelmetapi2:response.data.setting + }); + document.title = response.data.setting.name; + var link = document.createElement('link'), + oldLink = document.getElementById('dynamic-favicon'); + link.id = 'dynamic-favicon'; + link.rel = 'shortcut icon'; + link.href = '/'+response.data.setting.tab_logo_url; + if (oldLink) { + document.head.removeChild(oldLink); + } + document.head.appendChild(link); + }else { + document.title = "EduCoder"; + var link = document.createElement('link'), + oldLink = document.getElementById('dynamic-favicon'); + link.id = 'dynamic-favicon'; + link.rel = 'shortcut icon'; + link.href = "/react/build/./favicon.ico"; + if (oldLink) { + document.head.removeChild(oldLink); + } + document.head.appendChild(link); + } + }else{ + document.title = "EduCoder"; + var link = document.createElement('link'), + oldLink = document.getElementById('dynamic-favicon'); + link.id = 'dynamic-favicon'; + link.rel = 'shortcut icon'; + link.href = "/react/build/./favicon.ico"; + if (oldLink) { + document.head.removeChild(oldLink); + } + document.head.appendChild(link); + } + + }).catch((error) => { + console.log("开始刷新定制数据了但报错了"); + console.log(error); + + document.title = "EduCoder"; + var link = document.createElement('link'), + oldLink = document.getElementById('dynamic-favicon'); + link.id = 'dynamic-favicon'; + link.rel = 'shortcut icon'; + link.href = "/react/build/./favicon.ico"; + if (oldLink) { + document.head.removeChild(oldLink); + } + document.head.appendChild(link); + }); + }; render() { const isLogin = true; // 这里不会出现未登录的情况,服务端在服务端路由时发现如果是未登录,则跳转到登录页了。 - const {match ,} = this.props; + const {match,} = this.props; let {Addcoursestypes, tojoinitemtype, @@ -655,35 +737,127 @@ submittojoinclass=(value)=>{ user, isRender, showSearchOpentype, + headtypesonClickbool, + headtypess, + mygetHelmetapi2, }=this.state; /* 用户名称 用户头像url */ - let activeIndex = false; - let activeForums = false; - let activeShixuns = false; - let activePaths = false; - let coursestype=false; + let activeIndex = false; + let activeForums = false; + let activeShixuns = false; + let activePaths = false; + let coursestype=false; let activePackages=false; let activeMoopCases=false; - if (match.path === '/forums') { - activeForums = true; - } else if (match.path.startsWith('/shixuns')) { - activeShixuns = true; - }else if (match.path.startsWith('/paths')) { - activePaths = true; - } else if (match.path.startsWith('/courses')) { - coursestype = true; - }else if (match.path.startsWith('/crowdsourcing')) { + if (match.path === '/forums') { + activeForums = true; + } else if (match.path.startsWith('/shixuns')) { + activeShixuns = true; + }else if (match.path.startsWith('/paths')) { + activePaths = true; + } else if (match.path.startsWith('/courses')) { + coursestype = true; + }else if (match.path.startsWith('/crowdsourcing')) { activePackages = true; - }else if(match.path.startsWith('/moop_cases')){ - activeMoopCases = true; - }else { - activeIndex = true; - } + }else if(match.path.startsWith('/moop_cases')){ + activeMoopCases = true; + }else { + activeIndex = true; + } + let headtypes='/'; + + // console.log("mygetHelmetapi2"); + // console.log(mygetHelmetapi2); + if(mygetHelmetapi2){ + if(mygetHelmetapi2.navbar){ + if(mygetHelmetapi2.navbar.length>0){ + // console.log("mygetHelmetapi2.navbar.length>0====-=-=--=-=-=-="); + // + // console.log(match.path); + if(match.path==='/'){ + if(headtypesonClickbool===false){ + headtypes=undefined; + }else{ + headtypes=headtypess; + } + + }else { + for(var i=0;i @@ -699,9 +873,14 @@ submittojoinclass=(value)=>{ {...this.props} {...this.state} />:""} - - 高校智能化教学与实训平台 - + this.headtypesonClick("/",false)} className={"fl mr30 ml25 mt10"}> + { + mygetHelmetapi2===undefined||mygetHelmetapi2.nav_logo_url===null||mygetHelmetapi2.nav_logo_url===undefined? + 高校智能化教学与实训平台 + : + 高校智能化教学与实训平台 + } + -
    - {/*<%= link_to image_tag("/images/educoder/logo.png", alt:"高校智能化教学与实训平台", className:"logoimg"), home_path %>*/} + { + mygetHelmetapi2!==undefined&&mygetHelmetapi2.navbar!==null&&mygetHelmetapi2.navbar!==undefined&&mygetHelmetapi2.navbar.length>0? +
    +
      + {/*
    • 首页
    • */} + {/*
    • 实训路径
    • */} + { + mygetHelmetapi2.navbar && mygetHelmetapi2.navbar.map((item,key)=>{ + // console.log("headtypes"); + // console.log(headtypes);hidden + var str=new RegExp("http"); + var strbool=false; + //test方法返回值为(true或者false) + if(item.link){ + if(str.test(item.link)===true){ + strbool=true + }else{ + strbool=false + } + } + // console.log(item.hidden); + return( +
    • this.headtypesonClick(item.link,true)} className={`${headtypes===undefined?'pr':headtypes===item.link?'pr active':'pr'}`} style={item.hidden==false?{display: 'block'}:{display: 'none'}}> + { + strbool===true? + {item.name} + : + {item.name} + } +
    • + ) + }) + } + {/*
    • */} + {/* 实践课程*/} + {/*
    • */} + + {/*
    • 课堂
    • */} + {/*
    • */} + {/* /!*课堂*!/*/} + {/* 翻转课堂*/} + {/*
    • */} + + {/*
    • */} + {/* 实训项目*/} + {/* */} + {/* */} + {/*
    • */} + + + {/*
    • 教学案例
    • */} + {/*
    • */} + {/* 在线竞赛*/} + {/* */} + {/*
    • */} + {/*
    • 教学案例
    • */} + {/*
    • */} + {/*众包创新*/} + {/*
    • */} + {/*
    • 交流问答
    • */} + {/*工程认证*/} + + + + +
    • 0 ? 'block' : 'none'}}> + 职业路径 +
      0 ? 'block' : 'none'}}> +
        + {this.props.Headertop === undefined ? "" : this.props.Headertop.career_url.map((item, key) => { + return( +
      • {item.name}
      • + ) + }) + } +
      +
      +
    • +
    +
    + // :mygetHelmetapi2===undefined||mygetHelmetapi2.navbar===null||mygetHelmetapi2.navbar===undefined||mygetHelmetapi2.navbar.length===0? + //
    + // + //
      + // {/*
    • 首页
    • */} + // + // {/*
    • 实训路径
    • */} + //
    • + // 实践课程 + //
    • + // + // {/*
    • 课堂
    • */} + //
    • + // {/*课堂*/} + // 翻转课堂 + //
    • + // + //
    • + // 实训项目 + // {/**/} + // {/**/} + //
    • + // + //
    • 0 ? 'block' : 'none'}}> + // 职业路径 + //
      0 ? 'block' : 'none'}}> + //
        + // {this.props.Headertop === undefined ? "" : this.props.Headertop.career_url.map((item, key) => { + // return( + //
      • {item.name}
      • + // ) + // }) + // } + //
      + //
      + //
    • + // + // {/*
    • 教学案例
    • */} + //
    • + // 在线竞赛 + // {/**/} + //
    • + //
    • 教学案例
    • + // {/*
    • */} + // {/*众包创新*/} + // {/*
    • */} + //
    • 交流问答
    • + //
    • 工程认证
    • + //
    + //
    + : +
    + +
      + {/*
    • 首页
    • */} + + {/*
    • 实训路径
    • */} +
    • + 实践课程 +
    • + + {/*
    • 课堂
    • */} +
    • + {/*课堂*/} + 翻转课堂 +
    • + +
    • + 实训项目 + {/**/} + {/**/} +
    • + +
    • 0 ? 'block' : 'none'}}> + 职业路径 +
      0 ? 'block' : 'none'}}> +
        + {this.props.Headertop === undefined ? "" : this.props.Headertop.career_url.map((item, key) => { + return( +
      • {item.name}
      • + ) + }) + } +
      +
      +
    • + + {/*
    • 教学案例
    • */} +
    • + 在线竞赛 + {/**/} +
    • +
    • 教学案例
    • + {/*
    • */} + {/*众包创新*/} + {/*
    • */} +
    • 交流问答
    • +
    • 工程认证
    • +
    +
    + } -
    -
      - {/*
    • 首页
    • */} - {/*
    • 实训路径
    • */} -
    • - 实践课程 -
    • - {/*
    • 课堂
    • */} -
    • - {/*课堂*/} - 翻转课堂 -
    • -
    • - 实训项目 - - -
    • - -
    • 0 ? 'block' : 'none'}}> - 职业路径 -
      0 ? 'block' : 'none'}}> -
        - {this.props.Headertop === undefined ? "" : this.props.Headertop.career_url.map((item, key) => { - return( -
      • {item.name}
      • - ) - }) - } -
      -
      -
    • - - {/*
    • 教学案例
    • */} -
    • - 在线竞赛 - -
    • -
    • 教学案例
    • - {/*
    • */} - {/*众包创新*/} - {/*
    • */} -
    • 交流问答
    • -
    • 工程认证
    • -
    - - -
    -
    - + {weixinlogin===false? 登录 注册 - + :""} - { - parseInt(tab[0])==0 && + { + weixinlogin===false&&parseInt(tab[0])==0 &&