diff --git a/app/controllers/challenges_controller.rb b/app/controllers/challenges_controller.rb index 103c33aab..c69f5bbfb 100644 --- a/app/controllers/challenges_controller.rb +++ b/app/controllers/challenges_controller.rb @@ -155,8 +155,14 @@ class ChallengesController < ApplicationController def index uid_logger("identifier: #{params}") - - @challenges = @shixun.challenges.fields_for_list + base_columns = "challenges.id, challenges.subject, challenges.st, challenges.score, challenges.position, + challenges.shixun_id, games.identifier, games.status" + join_sql = "LEFT JOIN games ON games.challenge_id = challenges.id AND games.user_id = #{current_user.id}" + # 下面2个参数是为了解决列表获取通关人数与正在游玩人数的问题 + @pass_games_map = @shixun.challenges.joins(:games).where(games: {status:2}).group(:challenge_id).reorder(nil).count + @play_games_map = @shixun.challenges.joins(:games).where(games: {status:[0,1]}).group(:challenge_id).reorder(nil).count + + @challenges = @shixun.challenges.joins(join_sql).select(base_columns) @editable = @shixun.status == 0 # before_action:有判断权限,如果没发布,则肯定是管理人员 @user = current_user diff --git a/app/controllers/course_videos_controller.rb b/app/controllers/course_videos_controller.rb new file mode 100644 index 000000000..0d5a3e460 --- /dev/null +++ b/app/controllers/course_videos_controller.rb @@ -0,0 +1,34 @@ +class CourseVideosController < ApplicationController + before_action :require_login + before_action :validate_params + before_action :find_course, only: [:create] + before_action :find_video, only: [:update] + before_action :teacher_allowed + + def create + title = params[:name].strip + link = params[:link].strip + @course.course_videos.create!(title: title, link: link, is_link: 1, user_id: current_user.id) + render_ok + end + + def update + title = params[:name].strip + link = params[:link].strip + @video.update!(title: title, link: link) + render_ok + end + + private + + def validate_params + tip_exception("视频名称不能为空") if params[:name].blank? + tip_exception("链接地址不能为空") if params[:link].blank? + end + + def find_video + @video = CourseVideo.find params[:id] + @course = @video.course + end + +end \ No newline at end of file diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb index fe9d20d8d..2e94e435d 100644 --- a/app/controllers/courses_controller.rb +++ b/app/controllers/courses_controller.rb @@ -102,22 +102,32 @@ class CoursesController < ApplicationController end def course_videos - videos = @course.videos + videos = @course.course_videos + @video_module = @course.course_modules.find_by(module_type: "video") if params[:category_id].present? && params[:category_id].to_i != 0 + @category = @video_module&.course_second_categories.find_by(id: params[:category_id]) + tip_exception("子目录id有误") if !@category.present? videos = videos.where(course_second_category_id: params[:category_id].to_i) end videos = custom_sort(videos, params[:sort_by], params[:sort_direction]) @count = videos.count - @videos = paginate videos.includes(user: :user_extension) + @videos = paginate videos.includes(video: [user: :user_extension], user: :user_extension) end def delete_course_video - video = Video.find_by(id: params[:video_id]) - tip_exception(404, "找不到资源") if video.blank? - tip_exception(403, "...") unless (video.user_id == current_user.id || current_user.admin_or_business?) - video.destroy! - AliyunVod::Service.delete_video([video.uuid]) rescue nil + if params[:is_link] + video = @course.course_videos.find_by!(id: params[:video_id]) + tip_exception(403, "...") unless (video.user_id == current_user.id || current_user.admin_or_business?) + video.destroy! + else + video = Video.find_by(id: params[:video_id]) + tip_exception(404, "找不到资源") if video.blank? + tip_exception(403, "...") unless (video.user_id == current_user.id || current_user.admin_or_business?) + video.destroy! + AliyunVod::Service.delete_video([video.uuid]) rescue nil + end + render_ok end @@ -127,7 +137,7 @@ class CoursesController < ApplicationController category = @course.course_second_categories.find_by(id: params[:new_category_id]) if params[:new_category_id].to_i == 0 || category.present? - videos = @course.course_videos.where(id: params[:video_ids]) + videos = @course.course_videos.where(video_id: params[:video_ids]).or(@course.course_videos.where(id: params[:video_ids])) videos.update_all(course_second_category_id: params[:new_category_id]) normal_status(0, "操作成功") diff --git a/app/controllers/files_controller.rb b/app/controllers/files_controller.rb index 25e0de44a..c1fa48be8 100644 --- a/app/controllers/files_controller.rb +++ b/app/controllers/files_controller.rb @@ -7,7 +7,7 @@ class FilesController < ApplicationController before_action :file_validate_sort_type, only: :index before_action :validate_send_message_to_course_params, only: :bulk_send 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 :validate_upload_params, only: %i[import] before_action :find_file, only: %i[show setting update] before_action :publish_params, only: %i[upload import update] @@ -163,6 +163,7 @@ class FilesController < ApplicationController # 上传资源 def upload + find_course_second_category_id 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 @@ -170,25 +171,48 @@ class FilesController < ApplicationController # course_group_publish_times = params[:course_group_publish_times] || [] begin - attachment_ids.each do |attchment_id| - attachment = Attachment.find_by_id attchment_id - unless attachment.nil? - attachment.container = @course - attachment.course_second_category_id = course_second_category_id - attachment.description = params[:description] - 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.unified_setting = @unified_setting - if @unified_setting == 0 - attachment_group_setting attachment, params[:group_settings] + if attachment_ids.present? + attachment_ids.each do |attchment_id| + attachment = Attachment.find_by_id attchment_id + unless attachment.nil? + attachment.container = @course + attachment.course_second_category_id = course_second_category_id + attachment.description = params[:description] + 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.unified_setting = @unified_setting + if @unified_setting == 0 + attachment_group_setting attachment, params[:group_settings] + end + # 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 - # 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 + else + tip_exception("资源名称不能为空") if params[:name].blank? + tip_exception("资源名称不能超过60个字符") if params[:name].strip.length > 60 + tip_exception("链接地址不能为空") if params[:link].blank? + attachment = Attachment.new + attachment.container = @course + attachment.course_second_category_id = course_second_category_id + attachment.author_id = current_user.id + attachment.filename = params[:name].strip + attachment.link = params[:link].strip + attachment.description = params[:description] + 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.unified_setting = @unified_setting + if @unified_setting == 0 + attachment_group_setting attachment, params[:group_settings] + end + attachment.save! end + rescue Exception => e uid_logger_error(e.message) tip_exception(e.message) diff --git a/app/controllers/users/videos_controller.rb b/app/controllers/users/videos_controller.rb index 0ae240dd7..645c25362 100644 --- a/app/controllers/users/videos_controller.rb +++ b/app/controllers/users/videos_controller.rb @@ -1,6 +1,6 @@ class Users::VideosController < Users::BaseController before_action :private_user_resources!, :check_account - before_action :require_teacher! + before_action :require_teacher!, except: [:destroy] before_action :require_auth_teacher!, except: [:index, :review] helper_method :current_video @@ -53,6 +53,19 @@ class Users::VideosController < Users::BaseController render_error(ex.message) end + def destroy + video = observed_user.videos.find_by(id: params[:video_id]) + render_forbidden unless video.user_id != observed_user.id || !current_user.admin_or_business? + return render_not_found if video.blank? + return render_error('该状态下不能删除视频') unless video.pending? + + video.destroy! + + AliyunVod::Service.delete_video([video.uuid]) rescue nil + + render_ok + end + private def current_video diff --git a/app/controllers/weapps/attendances_controller.rb b/app/controllers/weapps/attendances_controller.rb index 3f0eec248..57e1e10df 100644 --- a/app/controllers/weapps/attendances_controller.rb +++ b/app/controllers/weapps/attendances_controller.rb @@ -58,12 +58,18 @@ class Weapps::AttendancesController < ApplicationController @history_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}')").order("id desc") - @current_attendance = @course.course_attendances.where(id: all_attendance_ids.uniq). + @current_attendances = @course.course_attendances.where(id: all_attendance_ids.uniq). where("attendance_date = '#{current_date}' and start_time <= '#{current_end_time}' and end_time > '#{current_end_time}'") @history_count = @history_attendances.size + # 当前签到如果存在快捷签到,则直接签到 + quick_attendances = @current_attendances.where(mode: "QUICK") + if quick_attendances.present? + student_direct_attendance quick_attendances, member + end + student_attendance_ids = @history_attendances.pluck(:id) - student_attendance_ids += @current_attendance.present? ? @current_attendance.pluck(:id) : [] + student_attendance_ids += @current_attendances.present? ? @current_attendances.pluck(:id) : [] if student_attendance_ids.uniq.blank? @normal_count = 0 @@ -141,4 +147,16 @@ class Weapps::AttendancesController < ApplicationController def edit_auth tip_exception(403, "") unless @user_course_identity < Course::PROFESSOR || @attendance.user_id == current_user.id end + + def student_direct_attendance quick_attendances, member + quick_attendances.each do |attendance| + current_attendance = attendance.course_member_attendances.find_by(user_id: member.user_id) + if current_attendance.present? + current_attendance.update!(attendance_status: "NORMAL", attendance_mode: "QUICK") + else + attendance.course_member_attendances.create!(course_member_id: member.id, user_id: member.user_id, course_id: attendance.course_id, + course_group_id: member.course_group_id, attendance_status: "NORMAL", attendance_mode: "QUICK") + end + end + end end \ No newline at end of file diff --git a/app/helpers/courses_helper.rb b/app/helpers/courses_helper.rb index e9d6e4b06..ed76a4b0c 100644 --- a/app/helpers/courses_helper.rb +++ b/app/helpers/courses_helper.rb @@ -98,7 +98,7 @@ module CoursesHelper when "attachment" "/courses/#{course.id}/file/#{category.id}" when "video" - "/courses/#{course.id}/course_videos/#{category.id}" + "/courses/#{course.id}/course_video/#{category.id}" end end diff --git a/app/models/challenge.rb b/app/models/challenge.rb index 70fac990b..5646da363 100644 --- a/app/models/challenge.rb +++ b/app/models/challenge.rb @@ -69,12 +69,13 @@ class Challenge < ApplicationRecord end # 开启挑战 - def open_game user_id, shixun - game = self.games.where(user_id: user_id).first - if game.present? - shixun.task_pass || game.status != 3 ? "/tasks/#{game.identifier}" : "" + def open_game shixun + # 这里的identifier,status是关联了games取了games的identifier,status + identifier = self.identifier + if identifier.present? + shixun.task_pass || self.status != 3 ? "/tasks/#{identifier}" : "" else - "/api/shixuns/#{shixun.identifier}/shixun_exec" + self.position == 1 ? "/api/shixuns/#{shixun.identifier}/shixun_exec" : "" end end @@ -92,16 +93,16 @@ class Challenge < ApplicationRecord # end ## 用户关卡状态 0: 不能开启实训; 1:直接开启; 2表示已完成 - def user_tpi_status user_id + def user_tpi_status shixun # todo: 以前没加索引导致相同关卡,同一用户有多个games # 允许跳关则直接开启 - game = games.where(user_id: user_id).take - if game.blank? - position == 1 ? 1 : 0 + identifier = self.identifier + if identifier.blank? + self.position == 1 ? 1 : 0 else - if game.status == 3 + if status == 3 shixun.task_pass ? 1 : 0 - elsif game.status == 2 + elsif status == 2 2 else 1 diff --git a/app/models/course_attendance.rb b/app/models/course_attendance.rb index 28059efc1..3b7e07fdf 100644 --- a/app/models/course_attendance.rb +++ b/app/models/course_attendance.rb @@ -1,6 +1,6 @@ class CourseAttendance < ApplicationRecord # status: 0: 未开启,1:已开启,2:已截止 - # mode: 0 两种签到,1 二维码签到,2 数字签到 + # mode: 0 两种签到,1 二维码签到,2 数字签到,3 快捷签到 enum mode: { ALL: 0, QRCODE: 1, NUMBER: 2, QUICK: 3 } belongs_to :course diff --git a/app/models/course_member_attendance.rb b/app/models/course_member_attendance.rb index 152bb48b6..b854acfe7 100644 --- a/app/models/course_member_attendance.rb +++ b/app/models/course_member_attendance.rb @@ -1,6 +1,6 @@ class CourseMemberAttendance < ApplicationRecord # attendance_mode :0 初始数据,1 二维码签到,2 数字签到,3 老师签到 - enum attendance_mode: { DEFAULT: 0, QRCODE: 1, NUMBER: 2, TEACHER: 3} + enum attendance_mode: { DEFAULT: 0, QRCODE: 1, NUMBER: 2, QUICK: 3, TEACHER: 4} # attendance_status :1 正常签到,2 请假,0 旷课 enum attendance_status: { NORMAL: 1, LEAVE: 2, ABSENCE: 0 } belongs_to :course_member diff --git a/app/models/course_video.rb b/app/models/course_video.rb index e61a439dc..246be34fd 100644 --- a/app/models/course_video.rb +++ b/app/models/course_video.rb @@ -1,4 +1,7 @@ class CourseVideo < ApplicationRecord belongs_to :course - belongs_to :video + belongs_to :video, optional: true + belongs_to :user, optional: true + + validates :title, length: { maximum: 60, too_long: "不能超过60个字符" } end diff --git a/app/views/challenges/index.json.jbuilder b/app/views/challenges/index.json.jbuilder index c53ab9c58..d4f2a7f59 100644 --- a/app/views/challenges/index.json.jbuilder +++ b/app/views/challenges/index.json.jbuilder @@ -16,10 +16,12 @@ if @challenges.present? json.st challenge.st json.name challenge.subject json.score challenge.score - json.passed_count challenge.user_passed_count - json.playing_count challenge.playing_count + json.passed_count @pass_games_map.fetch(challenge.id, 0) + #json.passed_count challenge.user_passed_count + json.playing_count @play_games_map.fetch(challenge.id, 0) + #json.playing_count challenge.playing_count json.name_url shixun_challenge_path(challenge, shixun_identifier: @shixun.identifier) - #json.open_game challenge.open_game(@user.id, @shixun) + json.open_game challenge.open_game(@shixun) if @editable json.edit_url edit_shixun_challenge_path(challenge, shixun_identifier: @shixun.identifier) json.delete_url shixun_challenge_path(challenge, shixun_identifier: @shixun.identifier) @@ -27,6 +29,6 @@ if @challenges.present? json.down_url index_down_shixun_challenge_path(challenge, :shixun_identifier => @shixun.identifier) if @shixun.challenges_count != challenge.position end #json.passed challenge.has_passed?(@user.id) - json.status challenge.user_tpi_status @user.id + json.status challenge.user_tpi_status(@shixun) end end diff --git a/app/views/courses/course_videos.json.jbuilder b/app/views/courses/course_videos.json.jbuilder index 807ff92bb..bee5e89cb 100644 --- a/app/views/courses/course_videos.json.jbuilder +++ b/app/views/courses/course_videos.json.jbuilder @@ -1,3 +1,22 @@ json.count @count -json.videos @videos, partial: 'users/videos/video', as: :video -json.course_id @course.id \ No newline at end of file + +json.videos @videos do |video| + if video.is_link + json.(video, :id, :title, :link, :user_id) + + user = video.user + json.user_name user&.real_name + json.user_img url_to_avatar(user) + json.user_login user&.login + else + json.partial! 'users/videos/video', locals: { video: video.video } + end +end + +json.course_id @course.id +if @category.present? + json.category_id @category.id + json.category_name @category.name +end +json.course_module_id @video_module&.id +json.has_category @video_module.course_second_categories.size > 0 \ No newline at end of file diff --git a/app/views/weapps/attendances/student_attendances.json.jbuilder b/app/views/weapps/attendances/student_attendances.json.jbuilder index c2b9fca12..f0ee4c8f8 100644 --- a/app/views/weapps/attendances/student_attendances.json.jbuilder +++ b/app/views/weapps/attendances/student_attendances.json.jbuilder @@ -1,4 +1,4 @@ -json.current_attendance @current_attendance do |attendance| +json.current_attendance @current_attendances do |attendance| json.partial! 'student_attendance', locals: {attendance: attendance} end diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml index f9671eec1..4c5c808ac 100644 --- a/config/locales/zh-CN.yml +++ b/config/locales/zh-CN.yml @@ -183,6 +183,9 @@ zh-CN: attendance_date: '签到日期' start_time: '开始时间' end_time: '结束时间' + course_video: + title: '视频名称' + link: '链接地址' diff --git a/config/routes.rb b/config/routes.rb index 1f9d4cfc4..7bf1b6c1b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -538,6 +538,8 @@ Rails.application.routes.draw do get 'search_slim' end + resources :course_videos, only:[:create, :update], shallow: true + resources :course_stages, shallow: true do member do post :up_position diff --git a/db/migrate/20200309071103_migrate_member_attendance_mode.rb b/db/migrate/20200309071103_migrate_member_attendance_mode.rb new file mode 100644 index 000000000..41f81444a --- /dev/null +++ b/db/migrate/20200309071103_migrate_member_attendance_mode.rb @@ -0,0 +1,5 @@ +class MigrateMemberAttendanceMode < ActiveRecord::Migration[5.2] + def change + CourseMemberAttendance.where(attendance_mode: 3).update_all(attendance_mode: 4) + end +end diff --git a/db/migrate/20200309101753_add_link_to_course_videos.rb b/db/migrate/20200309101753_add_link_to_course_videos.rb new file mode 100644 index 000000000..d5580d92e --- /dev/null +++ b/db/migrate/20200309101753_add_link_to_course_videos.rb @@ -0,0 +1,8 @@ +class AddLinkToCourseVideos < ActiveRecord::Migration[5.2] + def change + add_column :course_videos, :is_link, :boolean, default: 0 + add_column :course_videos, :title, :string + add_column :course_videos, :link, :string + add_column :course_videos, :user_id, :integer, index: true + end +end diff --git a/db/migrate/20200309123121_add_link_to_attachments.rb b/db/migrate/20200309123121_add_link_to_attachments.rb new file mode 100644 index 000000000..23510be26 --- /dev/null +++ b/db/migrate/20200309123121_add_link_to_attachments.rb @@ -0,0 +1,5 @@ +class AddLinkToAttachments < ActiveRecord::Migration[5.2] + def change + add_column :attachments, :link, :string + end +end diff --git a/public/images/educoder/xcx/fenxiangs.png b/public/images/educoder/xcx/fenxiangs.png new file mode 100755 index 000000000..f5b170bed Binary files /dev/null and b/public/images/educoder/xcx/fenxiangs.png differ diff --git a/public/images/educoder/xcx/xuesqiandao.png b/public/images/educoder/xcx/xuesqiandao.png new file mode 100755 index 000000000..7124615fd Binary files /dev/null and b/public/images/educoder/xcx/xuesqiandao.png differ diff --git a/public/react/src/common/components/comment/CommentForm.js b/public/react/src/common/components/comment/CommentForm.js index 11eea72e2..058cceda7 100644 --- a/public/react/src/common/components/comment/CommentForm.js +++ b/public/react/src/common/components/comment/CommentForm.js @@ -10,11 +10,9 @@ import './index.scss'; import React, { useState } from 'react'; import { Form, Button, Input } from 'antd'; import QuillForEditor from '../../quillForEditor'; -// import { QuillDeltaToHtmlConverter } from 'quill-delta-to-html' -// import {formatDelta} from './util'; const FormItem = Form.Item; -function CommentForm (props) { +function CommentForm(props) { const { onCancel, @@ -28,9 +26,6 @@ function CommentForm (props) { const [focus, setFocus] = useState(false); const options = [ - // ['bold', 'italic', 'underline'], - // [{header: [1,2,3,false]}], - 'code-block', 'link', 'image', 'formula' @@ -52,12 +47,10 @@ function CommentForm (props) { // 编辑器内容变化时 const handleContentChange = (content) => { - console.log('编辑器内容', content); setCtx(content); try { // const _html = new QuillDeltaToHtmlConverter(content.ops, {}).convert(); - // props.form.setFieldsValue({'comment': _html.replace(/<\/?[^>]*>/g, '')}); - props.form.setFieldsValue({'comment': content}); + props.form.setFieldsValue({ 'comment': content }); } catch (error) { console.log(error); } @@ -69,7 +62,7 @@ function CommentForm (props) { if (!err) { setShowQuill(false); const content = ctx; - props.form.setFieldsValue({'comment': ''}); + props.form.setFieldsValue({ 'comment': '' }); setCtx(''); // const _html = formatDelta(content.ops); // console.log('保存的内容=====》》》》', content); @@ -95,7 +88,7 @@ function CommentForm (props) { { getFieldDecorator('comment', { rules: [ - { required: true, message: '评论内容不能为空'} + { required: true, message: '评论内容不能为空' } ], })( - + ); diff --git a/public/react/src/common/components/comment/CommentItem.js b/public/react/src/common/components/comment/CommentItem.js index a70a15e75..28351cac9 100644 --- a/public/react/src/common/components/comment/CommentItem.js +++ b/public/react/src/common/components/comment/CommentItem.js @@ -237,7 +237,6 @@ function CommentItem({ /> - {/* 显示上传的图片信息 */}
diff --git a/public/react/src/common/quillForEditor/FillBlot.js b/public/react/src/common/quillForEditor/FillBlot.js index 5e5e2aa77..07b8b4a47 100644 --- a/public/react/src/common/quillForEditor/FillBlot.js +++ b/public/react/src/common/quillForEditor/FillBlot.js @@ -8,19 +8,15 @@ */ import Quill from 'quill'; let Inline = Quill.import('blots/inline'); -// const BlockEmbed = Quill.import('blots/embed'); class FillBlot extends Inline { - static create (value) { + static create(value) { const node = super.cerate(value); - // node.classList.add('icon icon-bianji2'); - // node.setAttribute('data-fill', 'fill'); - console.log('编辑器值===》》》》》', value); node.setAttribute('data_index', value.data_index); - node.nodeValue = value.text; + node.nodeValue = value.text; return node; } - - static value (node) { + + static value(node) { return { // dataSet: node.getAttribute('data-fill'), data_index: node.getAttribute('data_index') diff --git a/public/react/src/common/quillForEditor/ImageBlot.js b/public/react/src/common/quillForEditor/ImageBlot.js index 5ff84b249..0a9bec733 100644 --- a/public/react/src/common/quillForEditor/ImageBlot.js +++ b/public/react/src/common/quillForEditor/ImageBlot.js @@ -17,7 +17,6 @@ export default class ImageBlot extends BlockEmbed { const node = super.create(); node.setAttribute('alt', value.alt); node.setAttribute('src', value.url); - // console.log('~~~~~~~~~~~', node, value); node.addEventListener('click', function () { value.onclick(value.url); }, false); @@ -33,25 +32,14 @@ export default class ImageBlot extends BlockEmbed { } // 宽度和高度都不存在时, if (!value.width && !value.height) { - // node.setAttribute('display', 'block'); node.setAttribute('width', '100%'); } - // node.setAttribute('style', { cursor: 'pointer' }); - - // if (node.onclick) { - // console.log('image 有图片点击事件======》》》》》》'); - // // node.setAttribute('onclick', node.onCLick); - // } - // 给图片添加点击事件 - // node.onclick = () => { - // value.onClick && value.onClick(value.url); - // } return node; } // 获取节点值 - static value (node) { + static value(node) { return { alt: node.getAttribute('alt'), @@ -61,7 +49,6 @@ export default class ImageBlot extends BlockEmbed { height: node.height, display: node.getAttribute('display'), id: node.id, - // style: node.style }; } } diff --git a/public/react/src/common/quillForEditor/index.js b/public/react/src/common/quillForEditor/index.js index ba37059ba..46b02b94e 100644 --- a/public/react/src/common/quillForEditor/index.js +++ b/public/react/src/common/quillForEditor/index.js @@ -20,16 +20,17 @@ import { fetchUploadImage } from '../../services/ojService.js'; import { getImageUrl } from 'educoder' import ImageBlot from './ImageBlot'; import FillBlot from './FillBlot'; +import LinkBlot from './link-blot' var Size = Quill.import('attributors/style/size'); -// const Color = Quill.import('attributes/style/color'); Size.whitelist = ['14px', '16px', '18px', '20px', false]; -var fonts = ['Microsoft-YaHei','SimSun', 'SimHei','KaiTi','FangSong']; +var fonts = ['Microsoft-YaHei', 'SimSun', 'SimHei', 'KaiTi', 'FangSong']; var Font = Quill.import('formats/font'); Font.whitelist = fonts; //将字体加入到白名单 window.Quill = Quill; window.katex = katex; Quill.register(ImageBlot); Quill.register(Size); +Quill.register(LinkBlot); Quill.register(Font, true); // Quill.register({'modules/toolbar': Toolbar}); Quill.register({ @@ -38,7 +39,7 @@ Quill.register({ // Quill.register(Color); -function QuillForEditor ({ +function QuillForEditor({ placeholder, readOnly, autoFocus = false, @@ -51,17 +52,16 @@ function QuillForEditor ({ onContentChange, addFill, // 点击填空成功的回调 deleteFill // 删除填空,返回删除的下标 - // getQuillContent }) { // toolbar 默认值 const defaultConfig = [ 'bold', 'italic', 'underline', - {size: ['14px', '16px', '18px', '20px']}, - {align: []}, {list: 'ordered'}, {list: 'bullet'}, // 列表 - {script: 'sub'}, {script: 'super'}, + { size: ['14px', '16px', '18px', '20px'] }, + { align: [] }, { list: 'ordered' }, { list: 'bullet' }, // 列表 + { script: 'sub' }, { script: 'super' }, { 'color': [] }, { 'background': [] }, - { 'font': []}, - {header: [1,2,3,4,5,false]}, + { 'font': [] }, + { header: [1, 2, 3, 4, 5, false] }, 'blockquote', 'code-block', 'link', 'image', 'video', 'formula', @@ -77,7 +77,6 @@ function QuillForEditor ({ // 文本内容变化时 const handleOnChange = content => { - // getQuillContent && getQuillContent(quill); onContentChange && onContentChange(content, quill); }; @@ -86,9 +85,7 @@ function QuillForEditor ({ const bindings = { tab: { key: 9, - handler: function () { - console.log('调用了tab=====>>>>'); - } + handler: function () { } }, backspace: { key: 'Backspace', @@ -104,11 +101,10 @@ function QuillForEditor ({ * index: 删除元素的位置 * length: 删除元素的个数 */ - const {index, length} = range; + const { index, length } = range; const _start = length === 0 ? index - 1 : index; const _length = length || 1; let delCtx = this.quill.getText(_start, _length); // 删除的元素 - // aa const reg = /▁/g; const delArrs = delCtx.match(reg); if (delArrs) { @@ -216,7 +212,7 @@ function QuillForEditor ({ const ops = value.ops || []; ops.forEach((item, i) => { if (item.insert['image']) { - item.insert['image'] = Object.assign({}, item.insert['image'], {style: { cursor: 'pointer' }, onclick: (url) => showUploadImage(url)}); + item.insert['image'] = Object.assign({}, item.insert['image'], { style: { cursor: 'pointer' }, onclick: (url) => showUploadImage(url) }); } }); } @@ -225,7 +221,7 @@ function QuillForEditor ({ if (!deepEqual(previous, current)) { setSelection(quill.getSelection()) if (typeof value === 'string' && value) { - // debugger + // debugger quill.clipboard.dangerouslyPasteHTML(value, 'api'); if (autoFocus) { quill.focus(); @@ -273,9 +269,9 @@ function QuillForEditor ({ // 返回结果 return ( -
-
-
+
+
+
); } diff --git a/public/react/src/common/quillForEditor/link-blot.js b/public/react/src/common/quillForEditor/link-blot.js new file mode 100644 index 000000000..8f508dd34 --- /dev/null +++ b/public/react/src/common/quillForEditor/link-blot.js @@ -0,0 +1,21 @@ +import Quill from "quill"; +const Inline = Quill.import('blots/inline'); + +export default class LinkBlot extends Inline { + static create(value) { + let node = super.create() + let rs = value + if (rs.indexOf('http://') < 0) { + rs = 'http://' + rs + } + node.setAttribute('href', rs) + node.setAttribute('target', '_blank') + return node; + } + + static formats(node) { + return node.getAttribute('href'); + } +} +LinkBlot.blotName = 'link' +LinkBlot.tagName = 'a' \ No newline at end of file diff --git a/public/react/src/modules/tpm/shixuns/shixun-search-bar/index.jsx b/public/react/src/modules/tpm/shixuns/shixun-search-bar/index.jsx index 29a3b8485..c936de66d 100644 --- a/public/react/src/modules/tpm/shixuns/shixun-search-bar/index.jsx +++ b/public/react/src/modules/tpm/shixuns/shixun-search-bar/index.jsx @@ -91,7 +91,7 @@ export default ({ StatusEnquiry, allUpdatashixunlist, Updatasearchlist }) => {
方向:
- 全部 +
  • 全部
  • { navs.map((item, key) => { return ( diff --git a/public/react/src/redux/reducers/ojForUserReducer.js b/public/react/src/redux/reducers/ojForUserReducer.js index d20656513..60c3dc7af 100644 --- a/public/react/src/redux/reducers/ojForUserReducer.js +++ b/public/react/src/redux/reducers/ojForUserReducer.js @@ -17,7 +17,6 @@ const initialState = { commitTestRecordDetail: {}, // 调试代码执行结果 commitRecordDetail: {}, // 提交成功后记录提交的详情 commitRecord: [], // 提交记录 - userCode: '', // 保存当前用户输入的代码 isUpdateCode: false, // 是否更新了代码内容 userCodeTab: 'task', // 学员测评tab位置: task | record | comment userTestInput: '', // 用户自定义输入值 @@ -59,7 +58,7 @@ const ojForUserReducer = (state = initialState, action) => { hack: Object.assign({}, hack), test_case: Object.assign({}, test_case), comment_identifier: hack.identifier, - userCode: tempCode + editor_code: tempCode } case types.COMMIT_RECORD_DETAIL: let result = action.payload.data; @@ -127,7 +126,8 @@ const ojForUserReducer = (state = initialState, action) => { } return { ...state, - recordDetail: tempDetail + recordDetail: tempDetail, + editor_code: tempDetail['code'] } case types.RESTORE_INITIAL_CODE: const curHack = state.hack;