diff --git a/app/assets/javascripts/admins/upgrade_notices/index.js b/app/assets/javascripts/admins/upgrade_notices/index.js new file mode 100644 index 000000000..5ad9c7ce1 --- /dev/null +++ b/app/assets/javascripts/admins/upgrade_notices/index.js @@ -0,0 +1,82 @@ +$(document).on('turbolinks:load', function() { + if ($('body.admins-upgrade-notices-index-page').length > 0) { + window.upgradeNoticeForm = function(clazz) { + var $modal = $('.modal.admin-' + clazz + '-upgrade-notice-modal'); + var $form = $modal.find('form.admin-' + clazz + '-upgrade-notice-form'); + + $form.validate({ + errorElement: 'span', + errorClass: 'danger text-danger', + rules: { + 'upgrade_notice[title]': { + required: true + }, + 'upgrade_notice[content]': { + required: true + }, + 'upgrade_notice[start_at]': { + required: true + }, + 'upgrade_notice[end_at]': { + required: true + } + } + }); + + $modal.on('click', '.submit-btn', function() { + $form.find('.error').html(''); + console.log('url', $form.data('url'), $form) + + if ($form.valid()) { + var url = $form.attr('action'); + var newDate = new Date(); + var begin_time = Date.parse($('.' + clazz +'_start_at').val()); + var end_time = Date.parse($('.' + clazz +'_end_at').val()); + if (begin_time < newDate) { + $('.' + clazz +'_end_at').addClass('danger text-danger'); + $form.find('.error').html('开始时间应大于当前时间'); + return false + } else if (end_time < newDate) { + $form.find('.error').html('结束时间应大于当前时间'); + $('.' + clazz +'_end_at').addClass('danger text-danger'); + return false + } else if (end_time < begin_time) { + $form.find('.error').html('结束时间应大于开始时间'); + $('.' + clazz +'_end_at').addClass('danger text-danger'); + return false + } + + $.ajax({ + method: clazz == 'create' ? 'POST' : 'PUT', + dataType: 'json', + url: url, + data: $form.serialize(), + success: function() { + $.notify({ message: '创建成功' }); + $modal.modal('hide'); + + setTimeout(function() { + window.location.reload(); + }, 500); + }, + error: function(res) { + var data = res.responseJSON; + $form.find('.error').html(data.message); + } + }); + } + }); + } + + var timeOptions = { + autoclose: 1, + language: 'zh-CN', + format: 'yyyy-mm-dd hh:ii', + minuteStep: 10 + }; + + $(".create_start_at").datetimepicker(timeOptions) + $(".create_end_at").datetimepicker(timeOptions) + upgradeNoticeForm("create"); + } +}); \ No newline at end of file diff --git a/app/controllers/admins/upgrade_notices_controller.rb b/app/controllers/admins/upgrade_notices_controller.rb new file mode 100644 index 000000000..053a72106 --- /dev/null +++ b/app/controllers/admins/upgrade_notices_controller.rb @@ -0,0 +1,54 @@ +class Admins::UpgradeNoticesController < Admins::BaseController + + def index + params[:sort_by] ||= 'created_at' + params[:sort_direction] ||= 'desc' + + @upgrade_notice = UpgradeNotice.new( + content: '为了给大家提供更优质的体验,平台将于2018年5月22日00:00开始对系统进行升级。升级期间实训和基于项目的分组作业将暂停服务。 + 系统拟于2018年5月22日10:00恢复服务。请大家知悉,并提前做好教学安排。 + 带来不便,敬请谅解。', + title: 'educoder系统升级暂停服务通知') + + @upgrade_notices = UpgradeNotice.order("created_at #{params[:sort_direction]}") + @upgrade_notices = paginate @upgrade_notices + end + + def create + upgrade_notice = UpgradeNotice.new(upgrade_notice_params) + if upgrade_notice.save + render_ok + else + render_error upgrade_notice.error.full_messages.join(",") + end + end + + def destroy + check_upgrade_notice + @upgrade_notice.destroy + end + + def edit + check_upgrade_notice + end + + def update + check_upgrade_notice + if @upgrade_notice.update(upgrade_notice_params) + render_ok + else + render_error @upgrade_notice.error.full_messages.join(",") + end + end + + + private + + def upgrade_notice_params + params.require(:upgrade_notice).permit(:title, :content, :start_at, :end_at) + end + + def check_upgrade_notice + @upgrade_notice = UpgradeNotice.find(params[:id]) + end +end diff --git a/app/jobs/statistic_studentwork_job.rb b/app/jobs/statistic_studentwork_job.rb new file mode 100644 index 000000000..039ba7810 --- /dev/null +++ b/app/jobs/statistic_studentwork_job.rb @@ -0,0 +1,18 @@ +class StatisticStudentworkJob < ApplicationJob + queue_as :default + + def perform(*args) + School.find_in_batches(batch_size: 50) do |school| + Parallel.each_with_index(school, in_processes: 5) do |s| + student_work = StudentWork.find_by_sql("SELECT count(*) AS count + FROM student_works + JOIN user_extensions AS u ON u.user_id = student_works.user_id AND u.school_id = #{s.id}") + + report = SchoolReport.find_or_initialize_by(school_id: s.id) + report.school_name = s.name + report.student_work_count = student_work.first['count'] + report.save + end + end + end +end diff --git a/app/models/upgrade_notice.rb b/app/models/upgrade_notice.rb new file mode 100644 index 000000000..b975c0864 --- /dev/null +++ b/app/models/upgrade_notice.rb @@ -0,0 +1,2 @@ +class UpgradeNotice < ApplicationRecord +end diff --git a/app/services/admins/school_base_statistic_service.rb b/app/services/admins/school_base_statistic_service.rb index 6f3895c4c..1bbc13c7c 100644 --- a/app/services/admins/school_base_statistic_service.rb +++ b/app/services/admins/school_base_statistic_service.rb @@ -4,7 +4,7 @@ class Admins::SchoolBaseStatisticService < ApplicationService attr_reader :params sort_columns :student_count, :teacher_count, :course_count, :course_group_count, - :attachment_count, :video_count, :normal_work_count, :shixun_work_count, :evaluate_count, + :attachment_count, :video_count, :normal_work_count, :shixun_work_count, :shixun_evaluate_count, :student_work_count, :exercise_count, default_direction: :desc def initialize(params) @@ -32,25 +32,23 @@ class Admins::SchoolBaseStatisticService < ApplicationService def package_other_data(schools) ids = schools.map(&:id) - student_count = CourseMember.course_students.joins(course: :school).group(:school_id).where("role= 'STUDENT' AND courses.is_delete = false AND schools.id in (?)", ids).count("distinct user_id") + student_count = UserExtension.where(school_id: ids, identity: :student).group(:school_id).count teachers = UserExtension.where(school_id: ids, identity: :teacher).group(:school_id) teacher_count = teachers.count courses = Course.where(is_delete: 0, school_id: ids).group(:school_id) course_count= courses.count course_group_count = courses.joins(:course_groups).count attachment_count = courses.joins(:attachments).count - video_count = teachers.joins(user: :videos).where("videos.delete_state IS NOT NULL").count + video_count = teachers.joins(user: :videos).where("videos.delete_state IS NULL").count - homeworks = HomeworkCommon.joins(:course).where(courses: { school_id: ids }).where("courses.is_delete = false") + homeworks = HomeworkCommon.joins("JOIN user_extensions ON homework_commons.user_id = user_extensions.user_id").where(user_extensions: {school_id: ids}) shixun_work_count = homeworks.where(homework_type: 4).group(:school_id).count normal_work_count = homeworks.where(homework_type: 1).group(:school_id).count - student_work_count = homeworks.joins(:student_works).group(:school_id).count - evaluate_count = EvaluateRecord.unscoped.joins('JOIN homework_commons_shixuns hcs ON hcs.shixun_id = evaluate_records.shixun_id - JOIN homework_commons hc ON hcs.homework_common_id = hc.id AND hc.homework_type = 4 - JOIN course_members ON course_members.user_id = evaluate_records.user_id - JOIN courses ON course_members.course_id = courses.id AND hc.course_id = courses.id') - .where(courses: { school_id: ids }) - .group(:school_id).count + + reports = SchoolReport.where(school_id: ids) + evaluate_count = reports.each_with_object({}) { |report, obj| obj[report.school_id] = report.shixun_evaluate_count } + student_work_count = reports.each_with_object({}) { |report, obj| obj[report.school_id] = report.student_work_count } + exercise_count = Exercise.joins(:course).where(courses: { school_id: ids }).group(:school_id).count schools.map do |school| @@ -66,7 +64,7 @@ class Admins::SchoolBaseStatisticService < ApplicationService normal_work_count: normal_work_count[school.id], shixun_work_count: shixun_work_count[school.id], student_work_count: student_work_count[school.id], - evaluate_count: evaluate_count[school.id], + shixun_evaluate_count: evaluate_count[school.id], exercise_count: exercise_count[school.id] } end @@ -79,18 +77,17 @@ class Admins::SchoolBaseStatisticService < ApplicationService case sort_by_column.to_s when 'teacher_count' then schools.joins('LEFT JOIN user_extensions ue ON ue.school_id = schools.id AND ue.identity = 0') - .select("#{base_query_column}, COUNT(*) teacher_count") + .select("#{base_query_column}, COUNT(ue.id) teacher_count") when 'student_count' then - schools.joins("LEFT JOIN courses ue ON ue.school_id = schools.id AND ue.is_delete = FALSE - LEFT JOIN course_members ON course_members.course_id = ue.id AND course_members.role = 'STUDENT'") - .select("#{base_query_column}, COUNT(distinct user_id) student_count") + schools.joins('LEFT JOIN user_extensions ue ON ue.school_id = schools.id AND ue.identity = 1') + .select("#{base_query_column}, COUNT(*) student_count") when 'course_count' then - schools.joins('LEFT JOIN courses ON courses.school_id = schools.id AND courses.is_delete = false') - .select("#{base_query_column}, COUNT(*) course_count") + schools.joins('LEFT JOIN courses ON courses.school_id = schools.id AND courses.is_delete = 0') + .select("#{base_query_column}, COUNT(courses.id) course_count") when 'course_group_count' then - schools.joins("LEFT JOIN courses ON courses.school_id = schools.id AND courses.is_delete = false + schools.joins("LEFT JOIN courses ON courses.school_id = schools.id AND courses.is_delete = 0 LEFT JOIN course_groups ON course_groups.course_id = courses.id") - .select("#{base_query_column}, COUNT(*) course_group_count") + .select("#{base_query_column}, COUNT(course_groups.id) course_group_count") when 'attachment_count' then schools.joins("LEFT JOIN courses cs ON cs.school_id = schools.id AND cs.is_delete = 0 LEFT JOIN attachments ON attachments.container_type ='Course' AND attachments.container_id = cs.id") @@ -100,30 +97,23 @@ class Admins::SchoolBaseStatisticService < ApplicationService LEFT JOIN videos ON videos.user_id = ue.user_id AND videos.delete_state IS NOT NULL") .select("#{base_query_column}, COUNT(*) video_count") when 'normal_work_count' then - schools.joins("LEFT JOIN courses ON courses.school_id = schools.id - LEFT JOIN homework_commons ON homework_commons.course_id = courses.id AND homework_commons.homework_type = 0") + schools.joins("LEFT JOIN user_extensions ON user_extensions.school_id = schools.id + LEFT JOIN homework_commons ON homework_commons.user_id = user_extensions.user_id AND homework_commons.homework_type = 0") .select("#{base_query_column}, COUNT(*) normal_work_count") when 'shixun_work_count' then - schools.joins("LEFT JOIN courses ON courses.school_id = schools.id - LEFT JOIN homework_commons ON homework_commons.course_id = courses.id AND homework_commons.homework_type = 4") + schools.joins("LEFT JOIN user_extensions ON user_extensions.school_id = schools.id + LEFT JOIN homework_commons ON homework_commons.user_id = user_extensions.user_id AND homework_commons.homework_type = 4") .select("#{base_query_column}, COUNT(*) shixun_work_count") when 'student_work_count' then - schools.joins("LEFT JOIN courses ON courses.school_id = schools.id - LEFT JOIN homework_commons ON homework_commons.course_id = courses.id - LEFT JOIN student_works ON student_works.homework_common_id = homework_commons.id") - .select("#{base_query_column}, COUNT(*) student_work_count") - when 'evaluate_count' then - schools.joins(' - LEFT JOIN courses ON courses.school_id = schools.id AND courses.is_delete = false - LEFT JOIN course_members ON course_members.course_id = courses.id - LEFT JOIN evaluate_records ON course_members.user_id = evaluate_records.user_id - LEFT JOIN homework_commons_shixuns hcs ON hcs.shixun_id = evaluate_records.shixun_id - LEFT JOIN homework_commons hc ON hcs.homework_common_id = hc.id AND hc.homework_type = 4') - .select("#{base_query_column}, COUNT(*) evaluate_count") + schools.joins("LEFT JOIN school_reports ON school_reports.school_id = schools.id") + .select("#{base_query_column}, SUM(student_work_count) AS student_work_count") + when 'shixun_evaluate_count' then + schools.joins('LEFT JOIN school_reports ON school_reports.school_id = schools.id') + .select("#{base_query_column}, SUM(shixun_evaluate_count) AS shixun_evaluate_count") when 'exercise_count' then schools.joins('LEFT JOIN courses cs ON cs.school_id = schools.id AND cs.is_delete = 0 LEFT JOIN exercises ON exercises.course_id = cs.id') - .select("#{base_query_column}, COUNT(*) exercise_count") + .select("#{base_query_column}, COUNT(exercises.id) exercise_count") end end diff --git a/app/views/admins/school_base_statistics/_list.html.erb b/app/views/admins/school_base_statistics/_list.html.erb index aab91f5c7..c1d8fbee0 100644 --- a/app/views/admins/school_base_statistics/_list.html.erb +++ b/app/views/admins/school_base_statistics/_list.html.erb @@ -12,7 +12,7 @@ <%= sort_tag('普通作业', name: 'normal_work_count', path: admins_school_base_statistics_path) %> <%= sort_tag('实训作业', name: 'shixun_work_count', path: admins_school_base_statistics_path) %> <%= sort_tag('作业文件', name: 'student_work_count', path: admins_school_base_statistics_path) %> - <%= sort_tag('评测次数', name: 'evaluate_count', path: admins_school_base_statistics_path) %> + <%= sort_tag('评测次数', name: 'shixun_evaluate_count', path: admins_school_base_statistics_path) %> <%= sort_tag('在线试卷', name: 'exercise_count', path: admins_school_base_statistics_path) %> @@ -34,7 +34,7 @@ <%= statistic[:normal_work_count].to_i %> <%= statistic[:shixun_work_count].to_i %> <%= statistic[:student_work_count].to_i %> - <%= statistic[:evaluate_count].to_i %> + <%= statistic[:shixun_evaluate_count].to_i %> <%= statistic[:exercise_count].to_i %> diff --git a/app/views/admins/shared/_sidebar.html.erb b/app/views/admins/shared/_sidebar.html.erb index d77e4ed4e..6c8a3938a 100644 --- a/app/views/admins/shared/_sidebar.html.erb +++ b/app/views/admins/shared/_sidebar.html.erb @@ -86,7 +86,8 @@
  • <%= sidebar_item_group('#comments-submenu', '消息', icon: 'comments') do %>
  • <%= sidebar_item(admins_shixun_feedback_messages_path, '实训反馈', icon: 'comment', controller: 'admins-shixun_feedback_messages') %>
  • - <% end %> +
  • <%= sidebar_item(admins_upgrade_notices_path, '系统升级提醒', icon: 'envelope-open', controller: 'admins-upgrade_notices') %>
  • + <% end %>
  • diff --git a/app/views/admins/upgrade_notices/destroy.js.erb b/app/views/admins/upgrade_notices/destroy.js.erb new file mode 100644 index 000000000..4fc764c72 --- /dev/null +++ b/app/views/admins/upgrade_notices/destroy.js.erb @@ -0,0 +1,2 @@ +$.notify({ message: '删除成功' }); +$(".upgrade-notice-item-<%= @upgrade_notice.id %>").remove(); \ No newline at end of file diff --git a/app/views/admins/upgrade_notices/edit.js.erb b/app/views/admins/upgrade_notices/edit.js.erb new file mode 100644 index 000000000..fe92e77fa --- /dev/null +++ b/app/views/admins/upgrade_notices/edit.js.erb @@ -0,0 +1,14 @@ +$('.admin-modal-container').html("<%= j( render partial: 'admins/upgrade_notices/shared/edit_upgrade_notice_modal', locals: { upgrade_notice: @upgrade_notice } ) %>"); +$('.modal.admin-edit-upgrade-notice-modal').modal('show'); + +var timeOptions = { + autoclose: 1, + language: 'zh-CN', + format: 'yyyy-mm-dd hh:ii', + minuteStep: 10 +}; + +$(".edit_start_at").datetimepicker(timeOptions) +$(".edit_end_at").datetimepicker(timeOptions) + +upgradeNoticeForm("edit"); \ No newline at end of file diff --git a/app/views/admins/upgrade_notices/index.html.erb b/app/views/admins/upgrade_notices/index.html.erb new file mode 100644 index 000000000..55c30d981 --- /dev/null +++ b/app/views/admins/upgrade_notices/index.html.erb @@ -0,0 +1,15 @@ +<% define_admin_breadcrumbs do %> + <% add_admin_breadcrumb('系统升级提醒', admins_upgrade_notices_path) %> +<% end %> + +
    +
    + <%= javascript_void_link '新增', class: 'btn btn-primary', data: { toggle: 'modal', target: '.admin-create-upgrade-notice-modal' } %> +
    +
    + +
    + <%= render(partial: 'admins/upgrade_notices/shared/list') %> +
    + +<%= render partial: 'admins/upgrade_notices/shared/create_upgrade_notice_modal', locals: {upgrade_notice: @upgrade_notice} %> diff --git a/app/views/admins/upgrade_notices/index.js.erb b/app/views/admins/upgrade_notices/index.js.erb new file mode 100644 index 000000000..00da94961 --- /dev/null +++ b/app/views/admins/upgrade_notices/index.js.erb @@ -0,0 +1 @@ +$(".admin-upgrade-notices-list-container").html("<%= j render partial: "admins/upgrade_notices/shared/list",locals: {upgrade_notices: @upgrade_notices} %>") \ No newline at end of file diff --git a/app/views/admins/upgrade_notices/shared/_create_upgrade_notice_modal.html.erb b/app/views/admins/upgrade_notices/shared/_create_upgrade_notice_modal.html.erb new file mode 100644 index 000000000..332acbd2e --- /dev/null +++ b/app/views/admins/upgrade_notices/shared/_create_upgrade_notice_modal.html.erb @@ -0,0 +1,26 @@ + \ No newline at end of file diff --git a/app/views/admins/upgrade_notices/shared/_edit_upgrade_notice_modal.html.erb b/app/views/admins/upgrade_notices/shared/_edit_upgrade_notice_modal.html.erb new file mode 100644 index 000000000..f8d8e3aee --- /dev/null +++ b/app/views/admins/upgrade_notices/shared/_edit_upgrade_notice_modal.html.erb @@ -0,0 +1,25 @@ + diff --git a/app/views/admins/upgrade_notices/shared/_list.html.erb b/app/views/admins/upgrade_notices/shared/_list.html.erb new file mode 100644 index 000000000..79a872432 --- /dev/null +++ b/app/views/admins/upgrade_notices/shared/_list.html.erb @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + <% if @upgrade_notices.present? %> + <% @upgrade_notices.each_with_index do |notice, index| %> + + + + + + + + + + + <% end %> + <% else %> + <%= render 'admins/shared/no_data_for_table' %> + <% end %> + +
    序号标题详情开始时间结束时间<%= sort_tag('创建时间', name: 'created_at', path: admins_upgrade_notices_path) %>更新时间操作
    <%= index + 1 %> + <%= notice.title %> + + <%= notice.content %> + + <%= notice.start_at.to_s %> + + <%= notice.end_at.to_s %> + + <%= notice.created_at.to_s %> + + <%= notice.updated_at.to_s %> + + <%= link_to '编辑', edit_admins_upgrade_notice_path(notice), remote: true, class: 'edit-action' %> + <%= delete_link '删除', admins_upgrade_notice_path(notice, element: ".upgrade-notice-item-#{notice.id}"), class: 'delete-upgrade-notice-action' %> +
    + +<%= render partial: 'admins/shared/paginate', locals: { objects: @upgrade_notices } %> \ No newline at end of file diff --git a/app/views/homework_commons/publish_groups.json.jbuilder b/app/views/homework_commons/publish_groups.json.jbuilder index b77d14fe7..b0ba5b2d3 100644 --- a/app/views/homework_commons/publish_groups.json.jbuilder +++ b/app/views/homework_commons/publish_groups.json.jbuilder @@ -1,7 +1,7 @@ json.course_groups @course_groups do |group| json.id group.id json.name group.name - json.end_time @group_settings.select{|group_setting| group_setting.course_group_id == group.id}.first&.end_time + json.end_time @homework.unified_setting ? @homework.end_time : @group_settings.select{|group_setting| group_setting.course_group_id == group.id}.first&.end_time end json.end_time @homework.end_time json.late_time @homework.late_time \ No newline at end of file diff --git a/config/initializers/time_format.rb b/config/initializers/time_format.rb new file mode 100644 index 000000000..98a4c48bc --- /dev/null +++ b/config/initializers/time_format.rb @@ -0,0 +1,28 @@ +Time::DATE_FORMATS[:db2] = '%Y-%m-%d %H:%M:%S' + +Time::DATE_FORMATS[:default] = ->(time){ + Time.zone = 'Beijing' + t = Time.zone.at time + t.strftime '%Y-%m-%d %H:%M:%S' +} + +Time::DATE_FORMATS[:sh] = ->(time){ + t = Time.zone.at time + t.strftime '%y-%m-%d %H:%M:%S' +} + +Time::DATE_FORMATS[:date] = ->(time){ + t = Time.zone.at time + t.strftime '%Y-%m-%d' +} + +Time::DATE_FORMATS[:h] = ->(time){ + t = Time.zone.at time + t.strftime '%H:%M' +} + +Time::DATE_FORMATS[:datetime] = '%Y-%m-%d %H:%M' + +Date::DATE_FORMATS[:date] = ->(date){ + date.strftime '%Y-%m-%d' +} diff --git a/config/routes.rb b/config/routes.rb index 9a471fb7f..2f0fc57c7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -11,7 +11,7 @@ Rails.application.routes.draw do get 'auth/cas/callback', to: 'oauth/cas#create' get 'ecloud/ecloud_login', to: 'ecloud#ecloud_login_callback' - + resources :edu_settings @@ -31,6 +31,7 @@ Rails.application.routes.draw do resources :watch_video_histories, only: [:create] + resources :jupyters do collection do get :save_with_tpi @@ -1136,6 +1137,7 @@ Rails.application.routes.draw do namespace :admins do get '/', to: 'dashboards#index' + resources :upgrade_notices resources :major_informations, only: [:index] resources :ec_templates, only: [:index, :destroy] do collection do diff --git a/db/migrate/20200214070108_create_upgrade_notices.rb b/db/migrate/20200214070108_create_upgrade_notices.rb new file mode 100644 index 000000000..d887bf4da --- /dev/null +++ b/db/migrate/20200214070108_create_upgrade_notices.rb @@ -0,0 +1,12 @@ +class CreateUpgradeNotices < ActiveRecord::Migration[5.2] + def change + create_table :upgrade_notices do |t| + t.string :title + t.text :content + t.datetime :start_at + t.datetime :end_at + + t.timestamps + end + end +end diff --git a/db/migrate/20200325091127_add_statistic_to_school_report.rb b/db/migrate/20200325091127_add_statistic_to_school_report.rb new file mode 100644 index 000000000..e2b7a9311 --- /dev/null +++ b/db/migrate/20200325091127_add_statistic_to_school_report.rb @@ -0,0 +1,5 @@ +class AddStatisticToSchoolReport < ActiveRecord::Migration[5.2] + def change + add_column :school_reports, :student_work_count, :integer, default: 0 + end +end diff --git a/lib/tasks/sync_student_work.rake b/lib/tasks/sync_student_work.rake new file mode 100644 index 000000000..f38fa1beb --- /dev/null +++ b/lib/tasks/sync_student_work.rake @@ -0,0 +1,7 @@ +desc "同步学院或者单位学生作业数" + +namespace :sync_student_work do + task outpus_count: :environment do + StatisticStudentworkJob.perform_later + end +end \ No newline at end of file diff --git a/public/react/src/modules/courses/Video/Video.js b/public/react/src/modules/courses/Video/Video.js index 14e69cfbb..aa70220c9 100644 --- a/public/react/src/modules/courses/Video/Video.js +++ b/public/react/src/modules/courses/Video/Video.js @@ -14,6 +14,7 @@ import './video.css'; import '../../user/usersInfo/video/InfosVideo.css' import axios from 'axios'; import { logWatchHistory } from "../../../services/video-service"; +import { Base64 } from 'js-base64'; const DEFAULT_VIDEO_WIDTH_IN_MD = "90%" // 400 const DEFAULT_VIDEO_HEIGHT_IN_MD = "55%" // 400 @@ -33,7 +34,8 @@ class Video extends Component { visible: false, moveVisible: false, - moveVideoId: undefined + moveVideoId: undefined, + videourl:null } } @@ -64,6 +66,7 @@ class Video extends Component { if (!_clipboard) { _clipboard = new ClipboardJS('.copybtn'); _clipboard.on('success', (e) => { + this.props.showNotification('复制成功'); }); } @@ -110,6 +113,7 @@ class Video extends Component { videoVisible: flag }) if (flag === false) { + if (_clipboard) { this.setState({ videoId: undefined @@ -119,8 +123,12 @@ class Video extends Component { } } else { setTimeout(() => { + this.setState({ + videourl:'12321' + }) if (!_clipboard) { _clipboard = new ClipboardJS('.copybtn'); + _clipboard.on('success', (e) => { this.props.showNotification('复制成功'); }); @@ -131,7 +139,7 @@ class Video extends Component { } getCopyText = (file_url, cover_url) => { - return `` + return `` } // 删除事件 @@ -228,9 +236,9 @@ class Video extends Component { className="showVideoModal" width={800 - 1} > - {videoId && } + {videoId && } -
    +
    diff --git a/public/react/src/modules/courses/busyWork/PublishRightnow.js b/public/react/src/modules/courses/busyWork/PublishRightnow.js index 54e87a4c5..7afdfac5e 100644 --- a/public/react/src/modules/courses/busyWork/PublishRightnow.js +++ b/public/react/src/modules/courses/busyWork/PublishRightnow.js @@ -190,12 +190,13 @@ class PublishRightnow extends Component{ this.setState({ visible : false }) return; } - this.showDialog(response.data.course_groups) + this.setState({ course_groups: response.data.course_groups, starttimesend:response.data.end_time===undefined||response.data.end_time===null||response.data.end_time===""?undefined:response.data.end_time, starttimeslate_time:response.data.late_time===undefined||response.data.late_time===null||response.data.late_time===""?undefined:response.data.late_time, }) + this.showDialog(response.data.course_groups) }) .catch(function (error) { console.log(error); diff --git a/public/react/src/modules/courses/coursesDetail/CoursesBanner.js b/public/react/src/modules/courses/coursesDetail/CoursesBanner.js index 2bf7fb988..f63818ffd 100644 --- a/public/react/src/modules/courses/coursesDetail/CoursesBanner.js +++ b/public/react/src/modules/courses/coursesDetail/CoursesBanner.js @@ -404,7 +404,7 @@ class CoursesBanner extends Component { exitclass=()=>{ this.setState({ modalsType: true, - modalsTopval: "退出后您将不再是本课堂的成员,作品将全部被删除,", + modalsTopval: "退出后您将不再是本课题的成员,作品将全部被删除,", modalsBottomval:"确定要退出该课堂吗?", metype:6 }) @@ -601,33 +601,33 @@ class CoursesBanner extends Component {
    - +
    - - 头像 - - - -
    -

    {coursedata.teacher_school}

    -
    - -
    + + 头像 + + + +
    +

    {coursedata.teacher_school}

    +
    + +
    {/*
    {coursedata.teacher_users.length===0?'': 协作老师: {coursedata.teacher_users.map((iem,idx)=>{ return( - {idx<3?iem:''} {coursedata.teacher_users.length>3&&idx===2?'...':''} + {idx<3?iem:''} {coursedata.teacher_users.length>3&&idx===2?'...':''} ) }) } @@ -636,7 +636,7 @@ class CoursesBanner extends Component {
    */}
    - + {/*{excellent===false?*/} {/* :*/} @@ -665,6 +665,10 @@ class CoursesBanner extends Component { {/*}*/}
    + {this.props.isStudent()?this.props.current_user&&this.props.current_user.course_is_end===true?"": this.exitclass()} + > 永久退出课堂 :""} + {coursedata.switch_to_student === true ? 由教师/助教身份切换至学生
    可进行提交作品、答题等操作 @@ -723,9 +727,7 @@ class CoursesBanner extends Component { ) : ""} - {this.props.isStudent()?this.props.current_user&&this.props.current_user.course_is_end===true?"": this.exitclass()} - > 永久退出课堂 :""} +
    @@ -766,12 +768,12 @@ background:rgba(204,204,204,0.2) !important; placement="topLeft" title={
     																			 {coursedata.teacher_applies_count===undefined?"":coursedata.teacher_applies_count>0?
    -																				 新收到{coursedata.teacher_applies_count}条加入课堂的申请
    -																					 this.setHistoryFun("/classrooms/"+this.props.match.params.coursesId+"/teachers?tab=2")}>
    +																				 您有{coursedata.teacher_applies_count}条新的加入申请
    +																					 this.setHistoryFun("/classrooms/"+this.props.match.params.coursesId+"/teachers?tab=2")}>
     																			 
    -																			 去审批
    +																			 待审批
     																		 :""}
    }> this.setHistoryFun("/classrooms/"+this.props.match.params.coursesId+"/teachers")}> 教师 diff --git a/public/react/src/modules/courses/coursesPublic/OneSelfOrderModal.js b/public/react/src/modules/courses/coursesPublic/OneSelfOrderModal.js index 56eaab65a..8cdeb3a36 100644 --- a/public/react/src/modules/courses/coursesPublic/OneSelfOrderModal.js +++ b/public/react/src/modules/courses/coursesPublic/OneSelfOrderModal.js @@ -51,18 +51,14 @@ class OneSelfOrderModal extends Component{ let course_groups = this.props.course_groups; course_groups.map((item, key) => { + if (item.end_time === null) { // if(this.props.starttimesend===undefined){ // item.end_time = moment(moment(handleDateString(this.props.staytime)).add(1, 'week')).format("YYYY-MM-DD HH:mm"); // }else{ // item.end_time = moment(handleDateString(this.props.starttimesend)).format("YYYY-MM-DD HH:mm"); // } - if(this.props.starttimesend){ - item.end_time = moment(moment(handleDateString(this.props.starttimesend))).format("YYYY-MM-DD HH:mm"); - }else{ - item.end_time = moment(moment(handleDateString(this.props.staytime)).add(1, 'week')).format("YYYY-MM-DD HH:mm"); - } - + item.end_time = moment(moment(handleDateString(this.props.staytime)).add(1, 'week')).format("YYYY-MM-DD HH:mm"); newarr.push(item) } else { newarr.push(item) @@ -78,7 +74,7 @@ class OneSelfOrderModal extends Component{ if(this.props.starttimes===undefined||this.props.starttimes===""||this.props.starttimes===null){ if(this.props.starttimesend===undefined){ this.setState({ - endtime:moment(moment(handleDateString(this.props.staytime)).add(1, 'week')).format("YYYY-MM-DD HH:mm") + endtime:moment(moment(handleDateString(this.props.starttimes)).add(1, 'week')).format("YYYY-MM-DD HH:mm") }) }else{ this.setState({ @@ -89,7 +85,7 @@ class OneSelfOrderModal extends Component{ }else{ if(this.props.starttimesend===undefined){ this.setState({ - endtime:moment(moment(handleDateString(this.props.staytime)).add(1, 'week')).format("YYYY-MM-DD HH:mm") + endtime:moment(moment(handleDateString(this.props.starttimes)).add(1, 'week')).format("YYYY-MM-DD HH:mm") }) }else{ this.setState({ @@ -108,11 +104,7 @@ class OneSelfOrderModal extends Component{ course_groups.map((item,key)=>{ if(item.end_time===null){ // item.end_time = moment(moment(handleDateString(this.props.staytime)).add(1, 'week')).format("YYYY-MM-DD HH:mm"); - if(this.props.starttimesend){ - item.end_time = moment(moment(handleDateString(this.props.starttimesend))).format("YYYY-MM-DD HH:mm"); - }else{ - item.end_time = moment(moment(handleDateString(this.props.staytime)).add(1, 'week')).format("YYYY-MM-DD HH:mm"); - } + item.end_time = moment(moment(handleDateString(this.props.staytime)).add(1, 'week')).format("YYYY-MM-DD HH:mm"); newarr.push(item) }else{ newarr.push(item) @@ -131,7 +123,7 @@ class OneSelfOrderModal extends Component{ if(this.props.starttimes===undefined||this.props.starttimes===""||this.props.starttimes===null){ if(this.props.starttimesend===undefined){ this.setState({ - endtime:moment(moment(handleDateString(this.props.staytime)).add(1, 'week')).format("YYYY-MM-DD HH:mm") + endtime:moment(moment(handleDateString(this.props.starttimes)).add(1, 'week')).format("YYYY-MM-DD HH:mm") }) }else{ this.setState({ @@ -142,7 +134,7 @@ class OneSelfOrderModal extends Component{ }else{ if(this.props.starttimesend===undefined){ this.setState({ - endtime:moment(moment(handleDateString(this.props.staytime)).add(1, 'week')).format("YYYY-MM-DD HH:mm") + endtime:moment(moment(handleDateString(this.props.starttimes)).add(1, 'week')).format("YYYY-MM-DD HH:mm") }) }else{ this.setState({ diff --git a/public/react/src/modules/courses/poll/PollDetailTabFirst.js b/public/react/src/modules/courses/poll/PollDetailTabFirst.js index 2da0924ed..4f625b856 100644 --- a/public/react/src/modules/courses/poll/PollDetailTabFirst.js +++ b/public/react/src/modules/courses/poll/PollDetailTabFirst.js @@ -60,8 +60,11 @@ class PollDetailTabFirst extends Component{ }) } searchInfo=()=>{ - let {order, search, commit_status, poll_group_id, page, order_type} = this.state - this.getTableList(order, search, commit_status, poll_group_id, page, order_type); + let {order, search, commit_status, poll_group_id, page, order_type} = this.state; + this.setState({ + page:1 + }) + this.getTableList(order, search, commit_status, poll_group_id, 1, order_type); } // 获取接口数据 diff --git a/public/react/src/modules/courses/poll/pollPublicBtn/ImmediatelyPublish.js b/public/react/src/modules/courses/poll/pollPublicBtn/ImmediatelyPublish.js index 933ca1996..bbc617026 100644 --- a/public/react/src/modules/courses/poll/pollPublicBtn/ImmediatelyPublish.js +++ b/public/react/src/modules/courses/poll/pollPublicBtn/ImmediatelyPublish.js @@ -57,11 +57,12 @@ class Immediatelypublish extends Component{ if(this.props.Exercisetype==="exercise"){ let url=`/exercises/${this.props.match.params.Id}/publish_groups.json`; axios.get(url).then((response) => { - if(response.status===200){ + if (response.data) { + let starttimesend=response.data.end_time === undefined || response.data.end_time === null || response.data.end_time === "" ? undefined : response.data.end_time; + this.setState({ modalname:"立即发布", modaltype:response.data.course_groups===null||response.data.course_groups.length===0?2:1, - OneSelftype:true, Topval:this.props.Exercisetype==="exercise"?"学生将立即收到试卷":"学生将立即收到问卷", // Botvalleft:"暂不发布", Botval:this.props.single ? "":this.props.Exercisetype==="exercise"?`本操作只对"未发布"的试卷有效`:`本操作只对"未发布"的问卷有效`, @@ -73,8 +74,9 @@ class Immediatelypublish extends Component{ Cancel:this.homeworkhide, Saves:this.homeworkstartend, course_groups:response.data.course_groups, - starttimesend:response.data.end_time===undefined||response.data.end_time===null||response.data.end_time===""?undefined:response.data.end_time, + starttimesend:starttimesend, immediatelyopen:response.data.course_groups===null||response.data.course_groups.length===0?false:true, + OneSelftype:true, }) } @@ -84,12 +86,12 @@ class Immediatelypublish extends Component{ }else{ let url=`/polls/${this.props.match.params.pollId}/publish_groups.json`; axios.get(url).then((response) => { - if(response){ + if (response.data) { + let starttimesend=response.data.end_time === undefined || response.data.end_time === null || response.data.end_time === "" ? undefined : response.data.end_time; this.setState({ modalname:"立即发布", modaltype:response.data.course_groups===null||response.data.course_groups.length===0?2:1, - OneSelftype:true, Topval:this.props.Exercisetype==="exercise"?"学生将立即收到试卷":"学生将立即收到问卷", // Botvalleft:"暂不发布", Botval:this.props.single ? "":this.props.Exercisetype==="exercise"?`本操作只对"未发布"的试卷有效`:`本操作只对"未发布"的问卷有效`, @@ -101,8 +103,9 @@ class Immediatelypublish extends Component{ Cancel:this.homeworkhide, Saves:this.homeworkstartend, course_groups:response.data.course_groups, - starttimesend:response.data.end_time===undefined||response.data.end_time===null||response.data.end_time===""?undefined:response.data.end_time, + starttimesend:starttimesend, immediatelyopen:response.data.course_groups===null||response.data.course_groups.length===0?false:true, + OneSelftype:true, }) } }).catch((error) => { diff --git a/public/react/src/modules/courses/shixunHomework/ShixunStudentWork.js b/public/react/src/modules/courses/shixunHomework/ShixunStudentWork.js index 7bb53750a..c5792bc29 100644 --- a/public/react/src/modules/courses/shixunHomework/ShixunStudentWork.js +++ b/public/react/src/modules/courses/shixunHomework/ShixunStudentWork.js @@ -383,14 +383,15 @@ class ShixunStudentWork extends Component { axios.get(url).then((response) => { - if(response.status===200){ + if (response.data) { const dataformat = 'YYYY-MM-DD HH:mm'; let starttime= this.props.getNowFormatDates(1); let endtime=this.props.getNowFormatDates(2); + let starttimesend=response.data.end_time === undefined || response.data.end_time === null || response.data.end_time === "" ? undefined : response.data.end_time; + this.setState({ modalname:"立即发布", modaltype:response.data.course_groups===null||response.data.course_groups.length===0?2:1, - OneSelftype:true, Topval:"学生将立即收到作业", // Botvalleft:"暂不发布", Botval:`本操作只对"未发布"的作业有效`, @@ -402,8 +403,9 @@ 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, + starttimesend:starttimesend, typs:"start", + OneSelftype:true, }) } }).catch((error) => { diff --git a/public/react/src/modules/courses/shixunHomework/Trainingjobsetting.js b/public/react/src/modules/courses/shixunHomework/Trainingjobsetting.js index 64a956d28..26abca297 100644 --- a/public/react/src/modules/courses/shixunHomework/Trainingjobsetting.js +++ b/public/react/src/modules/courses/shixunHomework/Trainingjobsetting.js @@ -1813,20 +1813,21 @@ class Trainingjobsetting extends Component { axios.get(url).then((response) => { - if (response.status === 200) { + if (response.data) { const dataformat = 'YYYY-MM-DD HH:mm'; let starttime = this.props.getNowFormatDates(1); let endtime = this.props.getNowFormatDates(2); + let starttimesend=response.data.end_time === undefined || response.data.end_time === null || response.data.end_time === "" ? undefined : response.data.end_time; + this.setState({ modalname: "立即发布", modaltype: response.data.course_groups === null || response.data.course_groups.length === 0 ? 2 : 1, - OneSelftype: true, Topval: "学生将立即收到作业", // Botvalleft:"暂不发布", Botval: `本操作只对"未发布"的作业有效`, starttime: "发布时间:" + moment(moment(new Date())).format("YYYY-MM-DD HH:mm"), starttimes: starttime, - starttimesend: response.data.end_time === undefined || response.data.end_time === null || response.data.end_time === "" ? undefined : response.data.end_time, + starttimesend:starttimesend, typs: "start", endtime: "截止时间:" + endtime, Cancelname: "暂不发布", @@ -1836,6 +1837,7 @@ class Trainingjobsetting extends Component { course_groups:response.data.course_groups, immediatelyopen:true, modallate_time:response.data.late_time, + OneSelftype: true, }) } }).catch((error) => { diff --git a/public/react/src/modules/courses/shixunHomework/Workquestionandanswer.js b/public/react/src/modules/courses/shixunHomework/Workquestionandanswer.js index 06fe12965..b3ab36973 100644 --- a/public/react/src/modules/courses/shixunHomework/Workquestionandanswer.js +++ b/public/react/src/modules/courses/shixunHomework/Workquestionandanswer.js @@ -159,14 +159,15 @@ class Workquestionandanswer extends Component { axios.get(url).then((response) => { - if (response.status === 200) { + if (response.data) { const dataformat = 'YYYY-MM-DD HH:mm'; let starttime = this.props.getNowFormatDates(1); let endtime = this.props.getNowFormatDates(2); + let starttimesend=response.data.end_time === undefined || response.data.end_time === null || response.data.end_time === "" ? undefined : response.data.end_time; + this.setState({ modalname: "立即发布", modaltype: response.data.course_groups === null || response.data.course_groups.length === 0 ? 2 : 1, - OneSelftype: true, Topval: "学生将立即收到作业", // Botvalleft:"暂不发布", Botval: `本操作只对"未发布"的作业有效`, @@ -178,8 +179,9 @@ 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, + starttimesend:starttimesend, typs: "start", + OneSelftype: true, }) } }).catch((error) => { diff --git a/public/react/src/modules/paths/ShixunPathCard.js b/public/react/src/modules/paths/ShixunPathCard.js index 66f236692..5afceaf30 100644 --- a/public/react/src/modules/paths/ShixunPathCard.js +++ b/public/react/src/modules/paths/ShixunPathCard.js @@ -43,7 +43,7 @@ class ShixunPathCard extends Component{

    非试用内容,需要授权

    */} - + {/*target="_blank"*/} 详情图片 @@ -80,7 +80,7 @@ class ShixunPathCard extends Component{ ) } - + ) } diff --git a/public/react/src/modules/paths/statics/index.js b/public/react/src/modules/paths/statics/index.js index 5988f113d..55e391478 100644 --- a/public/react/src/modules/paths/statics/index.js +++ b/public/react/src/modules/paths/statics/index.js @@ -212,8 +212,8 @@ const App = (props) => { sorter: (a, b) => a.cost_time - b.cost_time } ]; - - + + useEffect(() => { changeParams({ page: 1, @@ -307,7 +307,7 @@ const App = (props) => { fetchData={handleFetchData} /> - + { fetchData={handleFetchData} /> - + { other_info, total, } - + }; const mapDispatchToProps = (dispatch) => ({