diff --git a/.gitignore b/.gitignore index 349c0cdc1..544539736 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ # Ignore bundler config. /.bundle /bundle +/node_modules # Ignore lock config file *.lock @@ -46,6 +47,8 @@ /public/h5build /public/npm-debug.log +/dist + # avatars /public/images/avatars diff --git a/app/controllers/attendances_controller.rb b/app/controllers/attendances_controller.rb index dc30df7e3..6e159cd77 100644 --- a/app/controllers/attendances_controller.rb +++ b/app/controllers/attendances_controller.rb @@ -8,23 +8,35 @@ class AttendancesController < ApplicationController current_date = Date.current current_end_time = Time.current.strftime("%H:%M:%S") + member = @course.students.find_by(user_id: current_user.id) + if params[:history] - @attendances = @course.course_attendances.where("attendance_date < '#{current_date}' or - (attendance_date = '#{current_date}' and end_time < '#{current_end_time}')") if @user_course_identity == Course::STUDENT - member = @course.students.find_by(user_id: current_user.id) - group_ids = [member&.course_group_id.to_i, 0] - @attendances = @attendances.joins(:course_attendance_groups).where(course_attendance_groups: {course_group_id: group_ids}) + history_attendance_ids = member.course_member_attendances.where(course_id: @course.id).pluck(:course_attendance_id) + + @attendances = @course.course_attendances.where(id: history_attendance_ids.uniq). + where("attendance_date < '#{current_date}' or (attendance_date = '#{current_date}' and end_time < '#{current_end_time}')") + else + @attendances = @course.course_attendances.where("attendance_date < '#{current_date}' or + (attendance_date = '#{current_date}' and end_time < '#{current_end_time}')") + end + else + @attendances = @course.course_attendances.where("attendance_date > '#{current_date}' or + (attendance_date = '#{current_date}' and end_time > '#{current_end_time}')") + end + if @user_course_identity == Course::STUDENT + group_ids = [member&.course_group_id.to_i, 0] + @attendances = @attendances.joins(:course_attendance_groups).where(course_attendance_groups: {course_group_id: group_ids}) + + if params[:history] attendance_ids = @attendances.pluck(:id) @normal_count = @course.course_member_attendances.where(course_member_id: member&.id, course_attendance_id: attendance_ids, attendance_status: "NORMAL").size @leave_count = @course.course_member_attendances.where(course_member_id: member&.id, course_attendance_id: attendance_ids, attendance_status: "LEAVE").size @absence_count = @course.course_member_attendances.where(course_member_id: member&.id, course_attendance_id: attendance_ids, attendance_status: "ABSENCE").size end - else - @attendances = @course.course_attendances.where("attendance_date > '#{current_date}' or - (attendance_date = '#{current_date}' and end_time > '#{current_end_time}')") end + @attendances_count = @attendances.size @attendances = @attendances.order("attendance_date desc, start_time desc") diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb index 124fc1094..baf522848 100644 --- a/app/controllers/courses_controller.rb +++ b/app/controllers/courses_controller.rb @@ -30,7 +30,7 @@ class CoursesController < ApplicationController :informs, :update_informs, :online_learning, :update_task_position, :tasks_list, :join_excellent_course, :export_couser_info, :export_member_act_score, :new_informs, :delete_informs, :change_member_role, :course_groups, :join_course_group, :statistics, - :work_score, :act_score, :calculate_all_shixun_scores, :move_to_category] + :work_score, :act_score, :calculate_all_shixun_scores, :move_to_category, :watch_video_histories] before_action :user_course_identity, except: [:join_excellent_course, :index, :create, :new, :apply_to_join_course, :search_course_list, :get_historical_course_students, :mine, :search_slim, :board_list] before_action :teacher_allowed, only: [:update, :destroy, :settings, :search_teacher_candidate, @@ -114,7 +114,7 @@ class CoursesController < ApplicationController #sql = "left join videos on videos.id=course_videos.video_id AND (videos.transcoded=1 OR videos.user_id = #{current_user.id})" #@videos = paginate videos.joins(sql).includes(video: [user: :user_extension], user: :user_extension) - videos = videos.includes(video: [user: :user_extension], user: :user_extension) + videos = videos.includes(video: [user: :user_extension],user: :user_extension).select("course_videos.id, course_videos.title, course_videos.link, course_videos.user_id") videos = videos.where(videos: {transcoded: true}) .or(videos.where(videos: {user_id: current_user.id})) .or(videos.where(course_videos: {is_link: true})) @@ -1297,7 +1297,7 @@ class CoursesController < ApplicationController def left_banner @user = current_user @is_teacher = @user_course_identity < Course::ASSISTANT_PROFESSOR - @course_modules = @course.course_modules.where(hidden: 0).includes(first_categories: :children) + @course_modules = @course.course_modules.where.not(module_type: 'attendance').where(hidden: 0).includes(first_categories: :children) @hidden_modules = @course.course_modules.where(hidden: 1) @second_category_type = ["shixun_homework", "graduation", "attachment", "board", "course_group", "video", "common_homework", "group_homework"] end @@ -1481,6 +1481,23 @@ class CoursesController < ApplicationController end end + def watch_video_histories + @videos = CourseVideo.find_by_sql(" + SELECT course_videos.id, videos.user_id, videos.title, IFNULL(hisotries.time,0) AS time, IFNULL(hisotries.num,0) AS num + FROM course_videos + JOIN videos ON course_videos.course_id = #{@course.id} AND videos.id = course_videos.video_id + LEFT JOIN ( + SELECT watch_course_videos.course_video_id, sum(watch_course_videos.total_duration) AS time, count(watch_course_videos.course_video_id) AS num + FROM watch_course_videos + JOIN course_videos ON course_videos.id = watch_course_videos.course_video_id + WHERE course_videos.course_id = #{@course.id} + GROUP BY watch_course_videos.course_video_id + ) AS hisotries ON hisotries.course_video_id = course_videos.id + ") + @count = @videos.count + @videos = paginate @videos + end + private # Use callbacks to share common setup or constraints between actions. diff --git a/app/controllers/files_controller.rb b/app/controllers/files_controller.rb index 6a7f7b4b0..8e6356201 100644 --- a/app/controllers/files_controller.rb +++ b/app/controllers/files_controller.rb @@ -367,9 +367,9 @@ class FilesController < ApplicationController @category_name = category.try(:module_name) else @category = CourseSecondCategory.find category_id - @category_id = category.try(:id) - @category_name = category.try(:name) - @parent_category_id = category&.parent_id.to_i + @category_id = @category.try(:id) + @category_name = @category.try(:name) + @parent_category_id = @category&.parent_id.to_i end end diff --git a/app/controllers/memos_controller.rb b/app/controllers/memos_controller.rb index c0ea8d601..ef61ea202 100644 --- a/app/controllers/memos_controller.rb +++ b/app/controllers/memos_controller.rb @@ -12,7 +12,14 @@ class MemosController < ApplicationController def index @user = current_user @memos = Memo.all - s_order = (params[:order] == "replies_count" ? "all_replies_count" : params[:order]) || "updated_at" + # replies_count created_at updated_at + s_order = + case params[:order] + when 'replies_count' then 'all_replies_count' + when 'created_at' then 'created_at' + else + 'updated_at' + end # @tidding_count = unviewed_tiddings(current_user) if current_user.present? page = params[:page] || 1 limit = params[:limit] || 15 diff --git a/app/controllers/shixuns_controller.rb b/app/controllers/shixuns_controller.rb index 3f202c994..b1920239c 100644 --- a/app/controllers/shixuns_controller.rb +++ b/app/controllers/shixuns_controller.rb @@ -70,7 +70,7 @@ class ShixunsController < ApplicationController end ## 排序参数 - bsort = params[:sort] || 'desc' + bsort = (params[:sort] == "desc" ? "desc" : "asc") case params[:order_by] || 'new' when 'hot' @shixuns = @shixuns.order("shixuns.public = 2 desc, shixuns.myshixuns_count #{bsort}") diff --git a/app/controllers/watch_video_histories_controller.rb b/app/controllers/watch_video_histories_controller.rb index 15ee62113..fe1fbf31b 100644 --- a/app/controllers/watch_video_histories_controller.rb +++ b/app/controllers/watch_video_histories_controller.rb @@ -5,6 +5,6 @@ class WatchVideoHistoriesController < ApplicationController watch_log = CreateWatchVideoService.new(current_user, request, params).call render_ok(log_id: watch_log&.id) rescue CreateWatchVideoService::Error => ex - render_error(ex.message) + render_ok(log_id: watch_log&.id) end end diff --git a/app/controllers/weapps/course_member_attendances_controller.rb b/app/controllers/weapps/course_member_attendances_controller.rb index 5e92d5928..254a89b1d 100644 --- a/app/controllers/weapps/course_member_attendances_controller.rb +++ b/app/controllers/weapps/course_member_attendances_controller.rb @@ -14,6 +14,9 @@ class Weapps::CourseMemberAttendancesController < ApplicationController @members = @members.where(course_group_id: params[:group_ids]) end + @page = params[:page] || 1 + @limit = params[:limit] || 5 + if params[:attendance_status].present? @members = @members.joins(:course_member_attendances).where(course_member_attendances: {course_attendance_id: attendance.id, attendance_status: params[:attendance_status]}) end @@ -34,7 +37,7 @@ class Weapps::CourseMemberAttendancesController < ApplicationController if params[:attendance_mode] == "QUICK" attendance = CourseAttendance.find_by(id: params[:attendance_id]) else - attendance = CourseAttendance.find_by(attendance_code: params[:code]) + attendance = CourseAttendance.find_by(id: params[:attendance_id], attendance_code: params[:code]) end tip_exception("该签到不存在") if attendance.blank? || attendance.course.blank? diff --git a/app/helpers/courses_helper.rb b/app/helpers/courses_helper.rb index 99925505f..4e088c0fd 100644 --- a/app/helpers/courses_helper.rb +++ b/app/helpers/courses_helper.rb @@ -82,7 +82,7 @@ module CoursesHelper when "video" "/classrooms/#{course.id}/course_videos" when "attendance" - "/classrooms/#{course.id}/signin" + "/classrooms/#{course.id}/attendances" end end diff --git a/app/queries/weapps/subject_query.rb b/app/queries/weapps/subject_query.rb index 0a3c9beb2..180176ce2 100644 --- a/app/queries/weapps/subject_query.rb +++ b/app/queries/weapps/subject_query.rb @@ -8,7 +8,7 @@ class Weapps::SubjectQuery < ApplicationQuery end def call - subjects = @current_laboratory.subjects.unhidden.publiced + subjects = @current_laboratory.subjects.unhidden.publiced.show_moblied # 课程体系的过滤 if params[:sub_discipline_id].present? @@ -21,7 +21,7 @@ class Weapps::SubjectQuery < ApplicationQuery # 搜索 if params[:keyword].present? - subjects = subjects.where("subjects.name like '%#{params[:keyword]}%'") + subjects = subjects.where("subjects.name like :keyword", keyword: "%#{params[:keyword]}%") end subjects = subjects.left_joins(:shixuns, :repertoire).select('subjects.id, subjects.name, subjects.excellent, subjects.stages_count, subjects.status, subjects.homepage_show, @@ -33,10 +33,10 @@ class Weapps::SubjectQuery < ApplicationQuery private def order_type - params[:order] || "updated_at" + params[:order] == "updated_at" ? "updated_at" : "myshixuns_count" end def sort_type - params[:sort] || "desc" + params[:sort] == "desc" ? "desc" : "asc" end end \ No newline at end of file diff --git a/app/services/create_watch_video_service.rb b/app/services/create_watch_video_service.rb index afdd57b5b..0f1b32814 100644 --- a/app/services/create_watch_video_service.rb +++ b/app/services/create_watch_video_service.rb @@ -10,29 +10,36 @@ class CreateWatchVideoService < ApplicationService def call ActiveRecord::Base.transaction do current_time = Time.now + params[:watch_duration] = params[:watch_duration].to_f.round(2) + params[:total_duration] = params[:total_duration].to_f.round(2) + params[:duration] = params[:duration].to_f.round(2) + if params[:log_id].present? - if params[:total_duration].to_f < params[:watch_duration].to_f || params[:watch_duration].to_f < 0 - raise Error, '观看时长错误' + watch_video_history = user.watch_video_histories.find(params[:log_id]) + if params[:total_duration] < params[:watch_duration] + return watch_video_history end # 更新观看时长 - watch_video_history = user.watch_video_histories.find(params[:log_id]) - - if watch_video_history.present? && watch_video_history.watch_duration <= params[:watch_duration].to_f && params[:total_duration].to_f > watch_video_history.total_duration + if watch_video_history.present? && !watch_video_history.is_finished && watch_video_history.watch_duration <= params[:watch_duration] && watch_video_history.total_duration <= params[:total_duration] # 如果观看总时长没变,说明视频没有播放,无需再去记录 - watch_video_history.end_at = current_time watch_video_history.total_duration = params[:total_duration] - watch_video_history.watch_duration = params[:watch_duration].to_f > watch_video_history.duration ? watch_video_history.duration : params[:watch_duration] - watch_video_history.is_finished = (watch_video_history.duration <= params[:watch_duration].to_f) + watch_video_history.watch_duration = params[:watch_duration] > watch_video_history.duration ? watch_video_history.duration : params[:watch_duration] + watch_video_history.is_finished = params[:ed].present? watch_video_history.save! watch_course_video = watch_video_history.watch_course_video - if watch_course_video.present? && !watch_course_video.is_finished && watch_course_video.watch_duration < params[:watch_duration].to_f - # 更新课程视频的时长及是否看完状态 - watch_course_video.watch_duration = params[:watch_duration] - watch_course_video.is_finished = (watch_course_video.duration <= params[:watch_duration].to_f) + if watch_course_video.present? + watch_course_video.total_duration = watch_course_video.watch_video_histories.sum(:total_duration) watch_course_video.end_at = current_time + if !watch_course_video.is_finished && watch_course_video.watch_duration < params[:watch_duration] + # 更新课程视频的时长及是否看完状态 + watch_course_video.watch_duration = params[:watch_duration] + if params[:ed].present? + watch_course_video.is_finished = watch_course_video.total_duration >= watch_course_video.duration + end + end watch_course_video.save! end end @@ -45,11 +52,10 @@ class CreateWatchVideoService < ApplicationService d.start_at = current_time d.duration = params[:duration] end - - watch_video_history = build_video_log(current_time, course_video.video_id, watch_course_video.id) - watch_video_history.save! watch_course_video.save! unless watch_course_video.persisted? + watch_video_history = build_video_log(current_time, course_video.video_id, watch_course_video.id) + watch_video_history.save! else # 非课堂视频 video = Video.find(params[:video_id]) diff --git a/app/views/attendances/index.json.jbuilder b/app/views/attendances/index.json.jbuilder index 8a4dd2bb1..b44f9a4fe 100644 --- a/app/views/attendances/index.json.jbuilder +++ b/app/views/attendances/index.json.jbuilder @@ -1,5 +1,5 @@ json.attendances @attendances do |attendance| - json.(attendance, :id, :name, :normal_count, :all_count, :mode) + json.(attendance, :id, :name, :normal_count, :all_count, :mode, :attendance_code) json.author do user = attendance.user json.user_name user.real_name diff --git a/app/views/courses/course_videos.json.jbuilder b/app/views/courses/course_videos.json.jbuilder index bee5e89cb..c2a4c1282 100644 --- a/app/views/courses/course_videos.json.jbuilder +++ b/app/views/courses/course_videos.json.jbuilder @@ -10,6 +10,8 @@ json.videos @videos do |video| json.user_login user&.login else json.partial! 'users/videos/video', locals: { video: video.video } + json.total_time video.watch_course_videos.sum(:total_duration).round(0) + json.people_num video.watch_course_videos.count(:user_id) end end diff --git a/app/views/courses/watch_video_histories.json.jbuilder b/app/views/courses/watch_video_histories.json.jbuilder new file mode 100644 index 000000000..4e7a4b174 --- /dev/null +++ b/app/views/courses/watch_video_histories.json.jbuilder @@ -0,0 +1,10 @@ +json.videos do + json.array! @videos do |v| + json.id v.id + json.title v.title + json.user_name v.user&.real_name + json.people_num v.num + json.total_time v.time + end +end +json.count @count \ No newline at end of file diff --git a/app/views/weapps/course_member_attendances/index.json.jbuilder b/app/views/weapps/course_member_attendances/index.json.jbuilder index cec70b3fe..765de5833 100644 --- a/app/views/weapps/course_member_attendances/index.json.jbuilder +++ b/app/views/weapps/course_member_attendances/index.json.jbuilder @@ -4,8 +4,9 @@ # json.student_id member.user&.student_id # end -json.member_attendances @members.each do |member| +json.member_attendances @members.each_with_index.to_a do |member, index| json.(member, :user_id) + json.index (@page.to_i - 1) * @limit.to_i + index + 1 json.user_name member.user&.real_name json.student_id member.user&.student_id json.attendance_status @member_attendances.select{|attendance| attendance.course_member_id == member.id}.first&.attendance_status || "ABSENCE" diff --git a/config/routes.rb b/config/routes.rb index 6c3efcfe8..881324e61 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -531,6 +531,7 @@ Rails.application.routes.draw do post :inform_up post :inform_down get :calculate_all_shixun_scores + get :watch_video_histories end collection do diff --git a/db/migrate/20200313104522_add_total_duration_to_watch_course_duration.rb b/db/migrate/20200313104522_add_total_duration_to_watch_course_duration.rb new file mode 100644 index 000000000..400e52ac8 --- /dev/null +++ b/db/migrate/20200313104522_add_total_duration_to_watch_course_duration.rb @@ -0,0 +1,8 @@ +class AddTotalDurationToWatchCourseDuration < ActiveRecord::Migration[5.2] + def change + add_column :watch_course_videos, :total_duration, :float, default: 0 + WatchVideoHistory.where("created_at < '2020-03-14 00:00:00'").each do |d| + d.watch_course_video.increment!(:total_duration, d.total_duration) if d.watch_course_video.present? + end + end +end diff --git a/public/react/package-lock.json b/public/react/package-lock.json index a22a5a9ea..4cb59a032 100644 --- a/public/react/package-lock.json +++ b/public/react/package-lock.json @@ -13577,6 +13577,21 @@ "resolved": "http://registry.npm.taobao.org/q/download/q-1.5.1.tgz", "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" }, + "qr.js": { + "version": "0.0.0", + "resolved": "https://registry.npm.taobao.org/qr.js/download/qr.js-0.0.0.tgz", + "integrity": "sha1-ys6GOG9ZoNuAUPqQ2baw6IoeNk8=" + }, + "qrcode.react": { + "version": "1.0.0", + "resolved": "https://registry.npm.taobao.org/qrcode.react/download/qrcode.react-1.0.0.tgz", + "integrity": "sha1-foiJ2zt2nlVejrRj1MbeIhw21d4=", + "requires": { + "loose-envify": "^1.4.0", + "prop-types": "^15.6.0", + "qr.js": "0.0.0" + } + }, "qs": { "version": "6.7.0", "resolved": "http://registry.npm.taobao.org/qs/download/qs-6.7.0.tgz", diff --git a/public/react/src/common/DateUtil.js b/public/react/src/common/DateUtil.js index dc2288ff3..4bc481b10 100644 --- a/public/react/src/common/DateUtil.js +++ b/public/react/src/common/DateUtil.js @@ -38,6 +38,36 @@ export function getNextHalfHourOfMoment(moment) { return moment } + export function formatSeconds(value) { + +         var theTime = parseInt(value);// 秒 +         var middle= 0;// 分 +         var hour= 0;// 小时 +      +         if(theTime > 60) { +             middle= parseInt(theTime/60); +             theTime = parseInt(theTime%60); +             if(middle> 60) { +                 hour= parseInt(middle/60); +                 middle= parseInt(middle%60); +             } +         } +         var result = ""+parseInt(theTime)+"秒"; +         if(middle > 0) { + if(hour>0){ + result = ""+parseInt(middle)+"分"; + }else{ + result = ""+parseInt(middle)+"分"+result; + } +              +         } +         if(hour> 0) { +             result = ""+parseInt(hour)+"小时"+result; +         } +         return result; +     } + + export function formatDuring(mss){ var days = parseInt(mss / (1000 * 60 * 60 * 24)); var hours = parseInt((mss % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); diff --git a/public/react/src/common/educoder.js b/public/react/src/common/educoder.js index 2cb074a6a..c990b5dea 100644 --- a/public/react/src/common/educoder.js +++ b/public/react/src/common/educoder.js @@ -20,7 +20,7 @@ export { bytesToSize as bytesToSize } from './UnitUtil'; export { markdownToHTML, uploadNameSizeSeperator, appendFileSizeToUploadFile, appendFileSizeToUploadFileAll, isImageExtension, downloadFile, sortDirections } from './TextUtil' -export { handleDateString, getNextHalfHourOfMoment,formatDuring } from './DateUtil' +export { handleDateString, getNextHalfHourOfMoment,formatDuring,formatSeconds} from './DateUtil' export { configShareForIndex, configShareForPaths, configShareForShixuns, configShareForCourses, configShareForCustom } from './util/ShareUtil' diff --git a/public/react/src/modules/courses/Video/Video.js b/public/react/src/modules/courses/Video/Video.js index 91d947300..181c082ae 100644 --- a/public/react/src/modules/courses/Video/Video.js +++ b/public/react/src/modules/courses/Video/Video.js @@ -240,8 +240,12 @@ class Video extends Component { { videos && videos.length > 0 ? - +

{videoData && videoData.count} 个视频

+ +

播放数据从2020-03-13 24:00开始统计

+
+
{ videos.map((item, key) => { diff --git a/public/react/src/modules/courses/Video/video-play/index.jsx b/public/react/src/modules/courses/Video/video-play/index.jsx index 84b465014..8c3a2eb20 100644 --- a/public/react/src/modules/courses/Video/video-play/index.jsx +++ b/public/react/src/modules/courses/Video/video-play/index.jsx @@ -43,7 +43,7 @@ export default ({ src, videoId, logWatchHistory, courseId = null }) => { let isSeeking = false let pos = []//播放时间点集 - const log = useCallback((callback) => { + const log = useCallback((callback, isEnd = false) => { let params = {} if (logId) { params['log_id'] = logId @@ -59,6 +59,9 @@ export default ({ src, videoId, logWatchHistory, courseId = null }) => { params['duration'] = totalDuration params['device'] = device } + if (isEnd) { + params['ed'] = "1" + } async function getLogId() { isLoging = true let id = await logWatchHistory(params) @@ -108,18 +111,15 @@ export default ({ src, videoId, logWatchHistory, courseId = null }) => { log() } } - + //循环播放, 累计时长不能清空 async function onEnded() { log(() => { logId = null - logCount = 1 lastUpdatedTime = 0 - sumTimePlayed = 0 initLog = false isLoging = false isSeeking = false - pos = [] - }) + }, true) } function onTimeupdate() { @@ -137,6 +137,8 @@ export default ({ src, videoId, logWatchHistory, courseId = null }) => { log() } } + }else { + lastUpdatedTime = newTime } } diff --git a/public/react/src/modules/courses/signin/Signinstatistics/Signinstatistics.js b/public/react/src/modules/courses/signin/Signinstatistics/Signinstatistics.js index d8ff88694..ca7ecace4 100644 --- a/public/react/src/modules/courses/signin/Signinstatistics/Signinstatistics.js +++ b/public/react/src/modules/courses/signin/Signinstatistics/Signinstatistics.js @@ -23,9 +23,7 @@ class Signinstatistics extends Component { } } getdata=(group_id)=>{ - this.setState({ - spal:true - }) + const coursesId=this.props.match.params.coursesId; let url=`/weapps/courses/${coursesId}/attendances.json` axios.get(url,{params:{ @@ -77,6 +75,9 @@ class Signinstatistics extends Component { } componentDidMount() { + this.setState({ + spal:true + }) const coursesId=this.props.match.params.coursesId; let newurl=`/courses/${coursesId}/all_course_groups.json`; axios.get(newurl).then((response) => { @@ -125,16 +126,16 @@ class Signinstatistics extends Component { { ` .lishiqiandao{ - background-image: url(${getImageUrl(`/images/qiandao/lishi.png`)}); + background-image: url(${getImageUrl(`images/qiandao/lishi.png`)}); } .daokeqiandao{ - background-image: url(${getImageUrl(`/images/qiandao/daoke.png`)}); + background-image: url(${getImageUrl(`images/qiandao/daoke.png`)}); } .kuangkeqiandao{ - background-image: url(${getImageUrl(`/images/qiandao/kuangke.png`)}); + background-image: url(${getImageUrl(`images/qiandao/kuangke.png`)}); } .qingjiaqiandao{ - background-image: url(${getImageUrl(`/images/qiandao/qingjia.png`)}); + background-image: url(${getImageUrl(`images/qiandao/qingjia.png`)}); } ` } diff --git a/public/react/src/modules/courses/signin/component/Teacherentry.js b/public/react/src/modules/courses/signin/component/Teacherentry.js index 6cbb48858..f3aa4c297 100644 --- a/public/react/src/modules/courses/signin/component/Teacherentry.js +++ b/public/react/src/modules/courses/signin/component/Teacherentry.js @@ -36,7 +36,7 @@ class Teacherentry extends Component {
-

this.props.qiandaoxiangq(true,item.id)}> +

this.props.qiandaoxiangq(true,item.id):""}> { item.name } diff --git a/public/react/src/modules/courses/signin/css/Signinstatistics.css b/public/react/src/modules/courses/signin/css/Signinstatistics.css index 0cd32b0a4..627458052 100644 --- a/public/react/src/modules/courses/signin/css/Signinstatistics.css +++ b/public/react/src/modules/courses/signin/css/Signinstatistics.css @@ -161,4 +161,28 @@ .textcenter{ text-align: center !important; +} + +.sginboxcolor26C7C9 .ant-select-selection--single{ + border:1px solid #26C7C9 !important; + } + +.sginboxcolor26C7C9 .ant-select-arrow{ + color: #26C7C9 !important; +} + +.sginboxcolorEAAE4E .ant-select-selection--single{ + border:1px solid #EAAE4E !important; +} + +.sginboxcolorEAAE4E .ant-select-arrow{ + color: #EAAE4E !important; +} + +.sginboxcolorFF835C .ant-select-selection--single{ + border:1px solid #FF835C !important; +} + +.sginboxcolorFF835C .ant-select-arrow{ + color: #FF835C !important; } \ No newline at end of file diff --git a/public/react/src/modules/courses/signin/student/Signedinlist.js b/public/react/src/modules/courses/signin/student/Signedinlist.js index 1f1074b49..f9c3459a6 100644 --- a/public/react/src/modules/courses/signin/student/Signedinlist.js +++ b/public/react/src/modules/courses/signin/student/Signedinlist.js @@ -21,14 +21,14 @@ class Signedinlist extends Component { attendance_status:undefined, state:[ {id:undefined,name:"全部状态"}, - {id:"NORMAL",name:"正常出勤"}, - {id:"LEAVE",name:"请假"}, - {id:"ABSENCE",name:"旷课"}, + {id:"NORMAL",name:"正常签到"}, + {id:"LEAVE",name:"请 假"}, + {id:"ABSENCE",name:"旷 课"}, ], newstate:[ - {id:"NORMAL",name:"正常出勤"}, - {id:"LEAVE",name:"请假"}, - {id:"ABSENCE",name:"旷课"}, + {id:"NORMAL",name:"正常签到"}, + {id:"LEAVE",name:"请 假"}, + {id:"ABSENCE",name:"旷 课"}, ], course_members_count:'--', attendance_count:'--', @@ -36,31 +36,36 @@ class Signedinlist extends Component { } componentDidMount() { - let {attendanceslist}=this.state; - if(this.props.headdata){ - let listattendanceslist=attendanceslist; - if(headdata.course_groups){ - - if(headdata.course_groups.length>0){ - headdata.course_groups.map((item,key)=>{ - listattendanceslist.push(item) - }) - } - } - this.setState({ - listattendanceslist:listattendanceslist, - data:response.data, - course_members_count:headdata.all_count, - attendance_count:headdata.normal_count - }) - } - this.getdatas(this.props&&this.props.switattendance_id,1,[],undefined) // this.getpath() } + componentDidUpdate(prevProps, prevState) { + if(prevProps.headdata!=this.props.headdata){ + + let {attendanceslist}=this.state; + if(this.props.headdata){ + let listattendanceslist=attendanceslist; + if(this.props.headdata.course_groups){ + + if(this.props.headdata.course_groups.length>0){ + this.props.headdata.course_groups.map((item,key)=>{ + listattendanceslist.push(item) + }) + } + } + this.setState({ + listattendanceslist:listattendanceslist, + data:this.props.headdata, + course_members_count:this.props.headdata.normal_count, + attendance_count:this.props.headdata.all_count + }) + } + + } + } getdatas=(id,page,group_ids,attendance_status)=>{ this.setState({ loading:true, @@ -101,24 +106,25 @@ class Signedinlist extends Component { neval=[] this.setState({ group_ids: [], + page:1 }) }else{ neval=[value] this.setState({ group_ids: [value], + page:1 }) } let {page,attendance_status}=this.state; - this.getdatas(this.props&&this.props.switattendance_id,page,neval,attendance_status) + this.getdatas(this.props&&this.props.switattendance_id,1,neval,attendance_status) if(this.props.defaultActiveKey==="1"){ this.getpath(value) } } getpath=(id)=>{ - let {attendanceslist}=this.state; - let listattendanceslist=attendanceslist + let listattendanceslist=[] let url=`/weapps/attendances/${this.props&&this.props.switattendance_id}.json`; axios.get(url).then((response) => { if(response.data){ @@ -140,12 +146,12 @@ class Signedinlist extends Component { }) }else{ this.setState({ - course_members_count:response.data.all_count, - attendance_count: response.data.normal_count + course_members_count:response.data.normal_count, + attendance_count: response.data.all_count }) } this.setState({ - listattendanceslist:attendanceslist, + listattendanceslist:listattendanceslist, data:response.data }) @@ -160,16 +166,18 @@ class Signedinlist extends Component { neval=undefined this.setState({ attendance_status:undefined, + page:1 }) }else{ neval=value this.setState({ attendance_status: value, + page:1 }) } let {page,group_ids}=this.state; - this.getdatas(this.props&&this.props.switattendance_id,page,group_ids,neval) + this.getdatas(this.props&&this.props.switattendance_id,1,group_ids,neval) } paginationonChange = (pageNumber) => { this.setState({ @@ -181,6 +189,17 @@ class Signedinlist extends Component { } handleChange=(attendance_status,value)=>{ + + let {member_attendances}=this.state; + let newmember_attendances=member_attendances; + + newmember_attendances.map((item,key)=>{ + if(item.user_id===value){ + item.attendance_status=attendance_status + } + }) + + let url=`/weapps/course_member_attendances/update_status.json`; axios.post(url, { @@ -192,7 +211,9 @@ class Signedinlist extends Component { .then((response) => { if (response.data.status == 0) { this.props.showNotification(`修改状态成功`); - + this.setState({ + member_attendances:newmember_attendances + }) } }) .catch(function (error) { @@ -203,38 +224,54 @@ class Signedinlist extends Component { } render() { - let {attendanceslist,state,data,member_attendances,newstate}=this.state; + let {attendanceslist,state,data,member_attendances,newstate,attendance_status}=this.state; const columns = [ { title: '序号', dataIndex: 'index', key: 'index', + width:300, className: "textcenter", }, { title: '姓名', dataIndex: 'user_name', key: 'user_name', + width:300, className: "textcenter", + render: (text, record) => ( + {record.user_name===null?"--":record.user_name} + ) }, { title: '学号', dataIndex: 'student_id', key: 'student_id', + width:300, className: "textcenter", + render: (text, record) => ( + {record.student_id===null?"--":record.student_id} + ) }, { title: '状态', key: 'attendance_status', + width:300, dataIndex: 'attendance_status', + className: "textcenter", render: (text, record) => ( - this.handleChange(e,record.user_id)}> { newstate&&newstate.map((item,key)=>{ return( - + ) }) } @@ -265,11 +302,18 @@ class Signedinlist extends Component { - { state&&state.map((item,key)=>{ return( - + ) }) } diff --git a/public/react/src/modules/courses/signin/student/Signindetails.js b/public/react/src/modules/courses/signin/student/Signindetails.js index 3eec58cad..d23ca76b2 100644 --- a/public/react/src/modules/courses/signin/student/Signindetails.js +++ b/public/react/src/modules/courses/signin/student/Signindetails.js @@ -25,8 +25,6 @@ class Signindetails extends Component{ //.log(response); if(response){ if(response.data){ - console.log("头部数据") - console.log(response.data) this.setState({ headdata:response.data }) @@ -37,12 +35,6 @@ class Signindetails extends Component{ } - componentDidUpdate = (prevProps) => { - console.log("componentDidUpdate"); - - - } - render(){ let {headdata}= this.state; diff --git a/public/react/src/modules/paths/ShixunPathSearch.js b/public/react/src/modules/paths/ShixunPathSearch.js index 844215974..d445a0c1d 100644 --- a/public/react/src/modules/paths/ShixunPathSearch.js +++ b/public/react/src/modules/paths/ShixunPathSearch.js @@ -30,7 +30,7 @@ class ShixunPathSearch extends Component { //适配器 onChangeLabel(value) { - let rs = value === 'new' ? 'updated_at' : 'myshixuns_scount' + let rs = value === 'new' ? 'updated_at' : 'myshixuns_count' let { discipline_id, sub_discipline_id } = this.state; this.setState({ order: rs, diff --git a/public/react/src/modules/user/usersInfo/video/InfosVideo.css b/public/react/src/modules/user/usersInfo/video/InfosVideo.css index fb78f9e85..a03a2c6f6 100644 --- a/public/react/src/modules/user/usersInfo/video/InfosVideo.css +++ b/public/react/src/modules/user/usersInfo/video/InfosVideo.css @@ -70,6 +70,7 @@ } .videoItem .time { + height: 15px; color: #C0C4CC; } .videoItem .square-main .buttonRow .dianjilianicon{ diff --git a/public/react/src/modules/user/usersInfo/video/VideoInReviewItem.js b/public/react/src/modules/user/usersInfo/video/VideoInReviewItem.js index 4e0ca8fb2..299af0d08 100644 --- a/public/react/src/modules/user/usersInfo/video/VideoInReviewItem.js +++ b/public/react/src/modules/user/usersInfo/video/VideoInReviewItem.js @@ -1,6 +1,6 @@ import React, { useState, useEffect, useContext, memo } from 'react'; import { Progress, Input, Tooltip , Spin } from 'antd' -import { getUrl2, isDev, CBreadcrumb, ActionBtn, ThemeContext } from 'educoder' +import { getUrl2, isDev, CBreadcrumb, ActionBtn, ThemeContext,formatSeconds} from 'educoder' import axios from 'axios' import moment from 'moment' import playIcon from './images/play.png' @@ -21,7 +21,7 @@ const clipboardMap = {} function VideoInReviewItem (props) { const theme = useContext(ThemeContext); const { history, file_url , play_url , cover_url , transcoded , title, created_at, published_at, isReview, id - , onEditVideo, onMaskClick, getCopyText, showNotification,vv,play_duration,operation , deleteVideo , moveVideo ,link} = props; + , onEditVideo, onMaskClick, getCopyText, showNotification,vv,play_duration,operation , deleteVideo , moveVideo ,link, people_num,total_time} = props; useEffect(()=> { if (!isReview) { _clipboard = new ClipboardJS(`.copybtn_item_${id}`); @@ -37,6 +37,9 @@ function VideoInReviewItem (props) { } } }, []) + + + const username = props.match.params.username function toList() { history.push(`/users/${username}/videos`) @@ -60,7 +63,7 @@ function VideoInReviewItem (props) { {!isReview && !link && transcoded &&

onMaskClick(props)}> - {play_duration===0?"":
累计学习时长:{play_duration} h
} + {/* {play_duration===0?"":
累计学习时长:{play_duration} h
} */}
} @@ -69,16 +72,22 @@ function VideoInReviewItem (props) { title={title && title.length > 20 ? title : ''} >{title}
- - {moment(published_at || created_at).format('YYYY-MM-DD HH:mm:ss')} + {/*
累计学习时长:{play_duration} h
*/} + {/* {moment(published_at || created_at).format('YYYY-MM-DD HH:mm:ss')}{people_num} */} + {link ? :累计学习时长:{ + formatSeconds(total_time)} + {/* total_time<60?total_time+' s':total_time/60<60?(total_time/60).toFixed(0)+' min':(total_time/3600).toFixed(1)+ ' h' */} + }
{/* 2019-09-01 10:00:22 */} - {!vv || (vv && vv)===0 ? "" : - - } {!vv || (vv && vv)===0?"":vv} + {!people_num || (people_num && people_num)===0 ? "" : + {!people_num || (people_num && people_num)===0?"":people_num} + } + +
{ isReview !== true && moveVideo &&