diff --git a/Gemfile.lock b/Gemfile.lock
index 8aa2daa6a..6a4a7e08f 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -378,7 +378,6 @@ DEPENDENCIES
kaminari (~> 1.1, >= 1.1.1)
listen (>= 3.0.5, < 3.2)
mysql2 (>= 0.4.4, < 0.6.0)
- newrelic_rpm
oauth2
pdfkit
puma (~> 3.11)
diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb
index 46b3964c2..ef30dac83 100644
--- a/app/controllers/accounts_controller.rb
+++ b/app/controllers/accounts_controller.rb
@@ -127,21 +127,21 @@ class AccountsController < ApplicationController
# UserDayCertification.create(user_id: user.id, status: 1)
end
- def set_autologin_cookie(user)
- token = Token.get_or_create_permanent_login_token(user, "autologin")
- cookie_options = {
- :value => token.value,
- :expires => 1.month.from_now,
- :path => '/',
- :secure => false,
- :httponly => true
- }
- if edu_setting('cookie_domain').present?
- cookie_options = cookie_options.merge(domain: edu_setting('cookie_domain'))
- end
- cookies[autologin_cookie_name] = cookie_options
- logger.info("cookies is #{cookies}")
- end
+ # def set_autologin_cookie(user)
+ # token = Token.get_or_create_permanent_login_token(user, "autologin")
+ # cookie_options = {
+ # :value => token.value,
+ # :expires => 1.month.from_now,
+ # :path => '/',
+ # :secure => false,
+ # :httponly => true
+ # }
+ # if edu_setting('cookie_domain').present?
+ # cookie_options = cookie_options.merge(domain: edu_setting('cookie_domain'))
+ # end
+ # cookies[autologin_cookie_name] = cookie_options
+ # logger.info("cookies is #{cookies}")
+ # end
def logout
UserAction.create(action_id: User.current.id, action_type: "Logout", user_id: User.current.id, :ip => request.remote_ip)
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 508d005a4..459ba5384 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -253,7 +253,10 @@ class ApplicationController < ActionController::Base
if Digest::MD5.hexdigest(content) == params[:chinaoocKey]
user = open_class_user
- start_user_session(user) if user
+ if user
+ start_user_session(user)
+ set_autologin_cookie(user)
+ end
User.current = user
end
end
@@ -617,6 +620,22 @@ class ApplicationController < ActionController::Base
cookies[:fileDownload] = true
end
+ def set_autologin_cookie(user)
+ token = Token.get_or_create_permanent_login_token(user, "autologin")
+ cookie_options = {
+ :value => token.value,
+ :expires => 1.month.from_now,
+ :path => '/',
+ :secure => false,
+ :httponly => true
+ }
+ if edu_setting('cookie_domain').present?
+ cookie_options = cookie_options.merge(domain: edu_setting('cookie_domain'))
+ end
+ cookies[autologin_cookie_name] = cookie_options
+ logger.info("cookies is #{cookies}")
+ end
+
# 149课程的评审用户数据创建(包含创建课堂学生)
def open_class_user
user = User.find_by(login: "OpenClassUser")
diff --git a/app/controllers/commons_controller.rb b/app/controllers/commons_controller.rb
index 43ea31c97..bcb0fa45a 100644
--- a/app/controllers/commons_controller.rb
+++ b/app/controllers/commons_controller.rb
@@ -51,7 +51,7 @@ class CommonsController < ApplicationController
200
end
when 'journals_for_message'
- course = @object.jour&.course || @object.jour&.student_work&.homework_common&.course
+ course = @object&.jour_type.to_s == "StudentWorksScore" ? @object.jour&.student_work&.homework_common&.course : @object.jour&.course
if current_user.course_identity(course) >= Course::STUDENT && @object.user != current_user
403
else
diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb
index 0dc8829da..d2c9f88d2 100644
--- a/app/controllers/courses_controller.rb
+++ b/app/controllers/courses_controller.rb
@@ -128,8 +128,8 @@ class CoursesController < ApplicationController
# POST /courses
# POST /courses.json
def create
- ActiveRecord::Base.transaction do
- begin
+ begin
+ ActiveRecord::Base.transaction do
@course = Course.new(name: params[:name], class_period: params[:class_period], credit: params[:credit],
end_date: params[:end_date], is_public: params[:is_public], school_id: @school.id,
authentication: params[:authentication], professional_certification: params[:professional_certification])
@@ -174,11 +174,12 @@ class CoursesController < ApplicationController
course_module_types = params[:course_module_types]
@course.create_course_modules(course_module_types)
end
- rescue => e
- uid_logger_error(e.message)
- tip_exception(e.message)
- raise ActiveRecord::Rollback
end
+ CreateSubjectCourseStudentJob.perform_later(@course.id) if @course.subject && @course.subject.subject_appointments.count > 0
+ rescue => e
+ uid_logger_error(e.message)
+ tip_exception(e.message)
+ raise ActiveRecord::Rollback
end
end
diff --git a/app/controllers/games_controller.rb b/app/controllers/games_controller.rb
index 4a087ae7a..be8173b2f 100644
--- a/app/controllers/games_controller.rb
+++ b/app/controllers/games_controller.rb
@@ -476,10 +476,13 @@ class GamesController < ApplicationController
if @myshixun.shixun.try(:status) < 2
tip_exception("代码获取异常,请检查实训模板的评测设置是否正确")
else
- # 报错继续retry
tip_exception(-3, "#{e.message}")
end
end
+ # 如果报错了,并且retry 为1的时候,则fork一个新的仓库
+ if params[:retry].to_i == 1
+ project_fork(@myshixun, @shixun.repo_path, current_user.login)
+ end
tip_exception(0, e.message)
end
end
diff --git a/app/controllers/gits_controller.rb b/app/controllers/gits_controller.rb
index 910864812..b52e75353 100644
--- a/app/controllers/gits_controller.rb
+++ b/app/controllers/gits_controller.rb
@@ -19,43 +19,48 @@ class GitsController < ApplicationController
result = false
if request.env["HTTP_AUTHORIZATION"] && request.env["HTTP_AUTHORIZATION"].split(" ").length == 2
username_password = Base64.decode64(request.env["HTTP_AUTHORIZATION"].split(" ")[1])
- input_username = username_password.split(":")[0].strip()
- input_password = username_password.split(":")[1].strip()
- uid_logger("git start auth: input_username is #{input_username}")
-
- # Git 超级权限用户
- if input_username.strip == gituser.strip && input_password.strip == gitpassword.strip
- result = true
+ if username_password.split(":")[0].nil? || username_password.split(":")[1].nil?
+ result = false
else
- # 用户是否对对象拥有权限
- system_user = User.find_by_login(input_username) || User.find_by_mail(input_username) || User.find_by_phone(input_username)
+ input_username = username_password.split(":")[0].strip()
+ input_password = username_password.split(":")[1].strip()
+ uid_logger("git start auth: input_username is #{input_username}")
+
- # 如果用户名密码错误
- if system_user && !system_user.check_password?(input_password)
- uid_logger_error("git start: password is wrong")
- result = false
+ # Git 超级权限用户
+ if input_username.strip == gituser.strip && input_password.strip == gitpassword.strip
+ result = true
else
- git_url = params["url"]
- username = git_url.split("/")[0]
- shixunname = git_url.split("/")[1].split(".")[0]
- repo_name = username + "/" + shixunname
- uid_logger("git start: repo_name is #{repo_name}")
- shixun = Shixun.select([:id, :user_id, :repo_name, :identifier]).where(repo_name: repo_name).first
- uid_logger("git start auth: shixun identifier is #{shixun.try(:identifier)}")
- uid_logger("git start auth: systemuser is #{system_user.try(:login)}")
+ # 用户是否对对象拥有权限
+ system_user = User.find_by_login(input_username) || User.find_by_mail(input_username) || User.find_by_phone(input_username)
- if shixun.present?
- if system_user.present? && system_user.manager_of_shixun?(shixun)
- result = true
+ # 如果用户名密码错误
+ if system_user && !system_user.check_password?(input_password)
+ uid_logger_error("git start: password is wrong")
+ result = false
+ else
+ git_url = params["url"]
+ username = git_url.split("/")[0]
+ shixunname = git_url.split("/")[1].split(".")[0]
+ repo_name = username + "/" + shixunname
+ uid_logger("git start: repo_name is #{repo_name}")
+ shixun = Shixun.select([:id, :user_id, :repo_name, :identifier]).where(repo_name: repo_name).first
+ uid_logger("git start auth: shixun identifier is #{shixun.try(:identifier)}")
+ uid_logger("git start auth: systemuser is #{system_user.try(:login)}")
+
+ if shixun.present?
+ if system_user.present? && system_user.manager_of_shixun?(shixun)
+ result = true
+ else
+ uid_logger_error("gituser is not shixun manager")
+ result = false
+ end
else
- uid_logger_error("gituser is not shixun manager")
- result = false
+ uid_logger_error("shixun is not exist")
+ # result = false
+ result = true # 为了测试跳出
end
- else
- uid_logger_error("shixun is not exist")
- # result = false
- result = true # 为了测试跳出
end
end
end
diff --git a/app/controllers/polls_controller.rb b/app/controllers/polls_controller.rb
index 7cb7ee800..6ffe277a3 100644
--- a/app/controllers/polls_controller.rb
+++ b/app/controllers/polls_controller.rb
@@ -692,7 +692,7 @@ class PollsController < ApplicationController
else
unified_setting = @poll.unified_setting
end
- show_result = params[:show_result] ? 1 : 0
+ show_result = params[:show_result].to_i
un_anonymous = params[:un_anonymous] ? true : false
# 统一设置或者分班为0,则更新问卷,并删除问卷分组
if unified_setting || (course_group_ids.size == 0)
diff --git a/app/jobs/create_subject_course_student_job.rb b/app/jobs/create_subject_course_student_job.rb
new file mode 100644
index 000000000..a7b8cb8af
--- /dev/null
+++ b/app/jobs/create_subject_course_student_job.rb
@@ -0,0 +1,22 @@
+class CreateSubjectCourseStudentJob < ApplicationJob
+ queue_as :default
+
+ def perform(course_id)
+ course = Course.find_by(id: course_id)
+ return if course.blank? || course.subject.blank?
+
+ attrs = %i[course_id user_id role created_at updated_at]
+ same_attrs = {course_id: course.id, role: 4}
+
+ Rails.logger.info("1:course.students.count:##{course.students.count}")
+ CourseMember.bulk_insert(*attrs) do |worker|
+ course.subject.subject_appointments.each do |app|
+ Rails.logger.info("##{course.students.where(user_id: app.user_id)}")
+ next if course.students.where(user_id: app.user_id).any?
+ worker.add same_attrs.merge(user_id: app.user_id)
+ end
+ end
+ Rails.logger.info("2:course.students.count:##{course.students.count}")
+ course.subject.subject_appointments.destroy_all
+ end
+end
diff --git a/app/models/homework_common.rb b/app/models/homework_common.rb
index 4c8f94a42..40de5a87c 100644
--- a/app/models/homework_common.rb
+++ b/app/models/homework_common.rb
@@ -134,6 +134,11 @@ class HomeworkCommon < ApplicationRecord
self.homework_type == 'practice' && self.publish_time.present? && self.publish_time < Time.now && self.homework_group_reviews.count == 0
end
+ # 作业查看最新成绩
+ def update_score identity
+ identity < Course::NORMAL && publish_time.present? && publish_time < Time.now && !course.is_end
+ end
+
# 作业能否立即发布
def publish_immediately user
homework_detail_manual.try(:comment_status) == 0 || homework_group_settings.where(course_group_id: course.charge_group_ids(user)).
diff --git a/app/models/poll.rb b/app/models/poll.rb
index 7f0d2fd94..9cb860f61 100644
--- a/app/models/poll.rb
+++ b/app/models/poll.rb
@@ -104,7 +104,7 @@ class Poll < ApplicationRecord
status = 4
else
if user.present? && user.student_of_course?(course)
- ex_time = get_poll_times(user_id,false)
+ ex_time = get_poll_times(user.id,false)
pb_time = ex_time[:publish_time]
ed_time = ex_time[:end_time]
if pb_time.present? && ed_time.present? && pb_time <= Time.now && ed_time > Time.now
diff --git a/app/views/homework_commons/works_list.json.jbuilder b/app/views/homework_commons/works_list.json.jbuilder
index 08c269670..e567ea79a 100644
--- a/app/views/homework_commons/works_list.json.jbuilder
+++ b/app/views/homework_commons/works_list.json.jbuilder
@@ -4,6 +4,7 @@ json.partial! "homework_btn_check", locals: {identity: @user_course_identity, ho
json.partial! "student_btn_check", locals: {identity: @user_course_identity, homework: @homework, work: @work}
+json.update_score @homework.update_score(@user_course_identity) if @homework.homework_type == "practice"
json.work_count @work_count
json.all_member_count @all_member_count
json.course_group_count @course.course_groups_count
diff --git a/app/views/searchs/index.json.jbuilder b/app/views/searchs/index.json.jbuilder
index 164e90b53..65c4d248c 100644
--- a/app/views/searchs/index.json.jbuilder
+++ b/app/views/searchs/index.json.jbuilder
@@ -10,9 +10,11 @@ json.results do
# 去除开头标点符号
reg = /^[,。?:;‘’!“”—……、]/
# 附件的替换
- atta_reg = /!\[\]\(\/api\/attachments\/\d+\)/
- highlights[:description]&.first&.sub!(reg, '').sub!(atta_reg, '')
- highlights[:content]&.first&.sub!(reg, '').sub!(atta_reg, '')
+ atta_reg = /!\[.*]\(\/api\/attachments\/\d+\)/
+ highlights[:description]&.first&.sub!(reg, '')
+ highlights[:description]&.map{|des| des.gsub!(atta_reg, '')}
+ highlights[:content]&.first&.sub!(reg, '')
+ highlights[:content]&.map{|des| des.gsub!(atta_reg, '')}
json.content highlights
end
diff --git a/app/views/shixun_lists/index.json.jbuilder b/app/views/shixun_lists/index.json.jbuilder
index c925d6876..79ce4b09c 100644
--- a/app/views/shixun_lists/index.json.jbuilder
+++ b/app/views/shixun_lists/index.json.jbuilder
@@ -8,9 +8,12 @@ json.shixun_list do
# 去除开头标点符号
reg = /^[,。?:;‘’!“”—……、]/
# 附件的替换
- atta_reg = /!\[\]\(\/api\/attachments\/\d+\)/
- highlights[:description]&.first&.sub!(reg, '')&.sub!(atta_reg, '')
- highlights[:content]&.first&.sub!(reg, '')&.sub!(atta_reg, '')
+ atta_reg = /!\[.*]\(\/api\/attachments\/\d+\)/
+
+ highlights[:description]&.first&.sub!(reg, '')
+ highlights[:description]&.map{|des| des.gsub!(atta_reg, '')}
+ highlights[:content]&.first&.sub!(reg, '')
+ highlights[:content]&.map{|des| des.gsub!(atta_reg, '')}
json.title highlights.delete(:name)&.join('...') || obj.searchable_title
json.description highlights[:description]&.join('...') || Util.extract_content(obj.description)[0..300]&.sub!(atta_reg, '')
diff --git a/app/views/users/courses/shared/_course.json.jbuilder b/app/views/users/courses/shared/_course.json.jbuilder
index e917033da..8da80f372 100644
--- a/app/views/users/courses/shared/_course.json.jbuilder
+++ b/app/views/users/courses/shared/_course.json.jbuilder
@@ -5,6 +5,7 @@ json.members_count course.course_members_count
# json.homework_commons_count course.homework_commons_count
json.homework_commons_count get_tasks_count course
json.attachments_count course.attachments.count
+json.visits course.visits
json.first_category_url module_url(course.course_modules.where(hidden: 0).order(position: :desc).first, course)
diff --git a/public/editormd/lib/marked.min.js b/public/editormd/lib/marked.min.js
index 1cd7c2bae..bfcb191af 100644
--- a/public/editormd/lib/marked.min.js
+++ b/public/editormd/lib/marked.min.js
@@ -13,6 +13,9 @@
// 0.4.0 /^ *(#{1,6}) ——》/^ *(#{1,6}) 去掉了一个空格 TODO 行内公式带_
/*if("string"!=typeof e)throw new Error("marked(): input parameter is of type "+Object.prototype.toString.call(e)+", string expected");*/
// b(i[1].replace(/^ *| *\| *$/g,"")) --> i[1].replace(/^ *| *\| *$/g, "").split(/ *\| */) table没识别的问题
-// header.length===a.align.length --> header.length table没识别的问题 a.header.length -> a.cells[p].split('|').length - 2
-!function(e){"use strict";var t={newline:/^\n+/,code:/^( {4}[^\n]+\n*)+/,fences:d,hr:/^ {0,3}((?:- *){3,}|(?:_ *){3,}|(?:\* *){3,})(?:\n+|$)/,heading:/^ *(#{1,6})*([^\n]+?) *(?:#+ *)?(?:\n+|$)/,nptable:d,blockquote:/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,list:/^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,html:"^ {0,3}(?:<(script|pre|style)[\\s>][\\s\\S]*?(?:\\1>[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?\\?>\\n*|\\n*|\\n*|?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:\\n{2,}|$)|<(?!script|pre|style)([a-z][\\w-]*)(?:attribute)*? */?>(?=\\h*\\n)[\\s\\S]*?(?:\\n{2,}|$)|(?!script|pre|style)[a-z][\\w-]*\\s*>(?=\\h*\\n)[\\s\\S]*?(?:\\n{2,}|$))",def:/^ {0,3}\[(label)\]: *\n? *([^\s>]+)>?(?:(?: +\n? *| *\n *)(title))? *(?:\n+|$)/,table:d,lheading:/^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,paragraph:/^([^\n]+(?:\n(?!hr|heading|lheading| {0,3}>|<\/?(?:tag)(?: +|\n|\/?>)|<(?:script|pre|style|!--))[^\n]+)*)/,text:/^[^\n]+/};function n(e){this.tokens=[],this.tokens.links={},this.options=e||m.defaults,this.rules=t.normal,this.options.pedantic?this.rules=t.pedantic:this.options.gfm&&(this.options.tables?this.rules=t.tables:this.rules=t.gfm)}t._label=/(?!\s*\])(?:\\[\[\]]|[^\[\]])+/,t._title=/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/,t.def=p(t.def).replace("label",t._label).replace("title",t._title).getRegex(),t.bullet=/(?:[*+-]|\d+\.)/,t.item=/^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/,t.item=p(t.item,"gm").replace(/bull/g,t.bullet).getRegex(),t.list=p(t.list).replace(/bull/g,t.bullet).replace("hr","\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))").replace("def","\\n+(?="+t.def.source+")").getRegex(),t._tag="address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",t._comment=//,t.html=p(t.html,"i").replace("comment",t._comment).replace("tag",t._tag).replace("attribute",/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),t.paragraph=p(t.paragraph).replace("hr",t.hr).replace("heading",t.heading).replace("lheading",t.lheading).replace("tag",t._tag).getRegex(),t.blockquote=p(t.blockquote).replace("paragraph",t.paragraph).getRegex(),t.normal=f({},t),t.gfm=f({},t.normal,{fences:/^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]*?)\n? *\1 *(?:\n+|$)/,paragraph:/^/,heading:/^ *(#{1,6})+([^\n]+?) *#* *(?:\n+|$)/}),t.gfm.paragraph=p(t.paragraph).replace("(?!","(?!"+t.gfm.fences.source.replace("\\1","\\2")+"|"+t.list.source.replace("\\1","\\3")+"|").getRegex(),t.tables=f({},t.gfm,{nptable:/^ *([^|\n ].*\|.*)\n *([-:]+ *\|[-| :]*)(?:\n((?:.*[^>\n ].*(?:\n|$))*)\n*|$)/,table:/^ *\|(.+)\n *\|?( *[-:]+[-| :]*)(?:\n((?: *[^>\n ].*(?:\n|$))*)\n*|$)/}),t.pedantic=f({},t.normal,{html:p("^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?\\1> *(?:\\n{2,}|\\s*$)| "+e+"
\n":"'+(n?e:a(e,!0))+"
"},i.prototype.blockquote=function(e){return""+(n?e:a(e,!0))+"
\n"+e+"
\n"},i.prototype.html=function(e){return e},i.prototype.heading=function(e,t,n){return this.options.headerIds?"
\n":"
\n"},i.prototype.list=function(e,t,n){var r=t?"ol":"ul";return"<"+r+(t&&1!==n?' start="'+n+'"':"")+">\n"+e+""+r+">\n"},i.prototype.listitem=function(e){return"\n\n"+e+"\n"+t+"
\n"},i.prototype.tablerow=function(e){return"\n"+e+" \n"},i.prototype.tablecell=function(e,t){var n=t.header?"th":"td";return(t.align?"<"+n+' align="'+t.align+'">':"<"+n+">")+e+""+n+">\n"},i.prototype.strong=function(e){return""+e+""},i.prototype.em=function(e){return""+e+""},i.prototype.codespan=function(e){return""+e+"
"},i.prototype.br=function(){return this.options.xhtml?"
":"
"},i.prototype.del=function(e){return""+e+""},i.prototype.link=function(e,t,n){if(this.options.sanitize){try{var r=decodeURIComponent(h(e)).replace(/[^\w:]/g,"").toLowerCase()}catch(e){return n}if(0===r.indexOf("javascript:")||0===r.indexOf("vbscript:")||0===r.indexOf("data:"))return n}this.options.baseUrl&&!g.test(e)&&(e=u(this.options.baseUrl,e));try{e=encodeURI(e).replace(/%25/g,"%")}catch(e){return n}var s='"+n+""},i.prototype.image=function(e,t,n){this.options.baseUrl&&!g.test(e)&&(e=u(this.options.baseUrl,e));var r='":">"},i.prototype.text=function(e){return e},l.prototype.strong=l.prototype.em=l.prototype.codespan=l.prototype.del=l.prototype.text=function(e){return e},l.prototype.link=l.prototype.image=function(e,t,n){return""+n},l.prototype.br=function(){return""},o.parse=function(e,t){return new o(t).parse(e)},o.prototype.parse=function(e){this.inline=new s(e.links,this.options),this.inlineText=new s(e.links,f({},this.options,{renderer:new l})),this.tokens=e.reverse();for(var t="";this.next();)t+=this.tok();return t},o.prototype.next=function(){return this.token=this.tokens.pop()},o.prototype.peek=function(){return this.tokens[this.tokens.length-1]||0},o.prototype.parseText=function(){for(var e=this.token.text;"text"===this.peek().type;)e+="\n"+this.next().text;return this.inline.output(e)},o.prototype.tok=function(){switch(this.token.type){case"space":return"";case"hr":return this.renderer.hr();case"heading":return this.renderer.heading(this.inline.output(this.token.text),this.token.depth,h(this.inlineText.output(this.token.text)));case"code":return this.renderer.code(this.token.text,this.token.lang,this.token.escaped);case"table":var e,t,n,r,s="",i="";for(n="",e=0;e
"+a(e.message+"",!0)+"";throw e}}d.exec=d,m.options=m.setOptions=function(e){return f(m.defaults,e),m},m.getDefaults=function(){return{baseUrl:null,breaks:!1,gfm:!0,headerIds:!0,headerPrefix:"",highlight:null,langPrefix:"language-",mangle:!0,pedantic:!1,renderer:new i,sanitize:!1,sanitizer:null,silent:!1,smartLists:!1,smartypants:!1,tables:!0,xhtml:!1}},m.defaults=m.getDefaults(),m.Parser=o,m.parser=o.parse,m.Renderer=i,m.TextRenderer=l,m.Lexer=n,m.lexer=n.lex,m.InlineLexer=s,m.inlineLexer=s.output,m.parse=m,"undefined"!=typeof module&&"object"==typeof exports?module.exports=m:"function"==typeof define&&define.amd?define(function(){return m}):e.marked=m}(this||("undefined"!=typeof window?window:global)); +// header.length===a.align.length --> header.length table没识别的问题 +// 2个table: b(a.cells[p],a.header.length) -> a.cells[p].replace(/^ *\| *| *\| *$/g, "").split(/ *\| */) +// .replace(/(?: *\| *)?\n$/,"") --> .replace(/\n$/, "") +// /^ *\|(.+)\n *\|?( *[-:]+[-| :]*)(?:\n((?: *[^>\n ].*(?:\n|$))*)\n*|$)/ --> /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/ +!function(e){"use strict";var t={newline:/^\n+/,code:/^( {4}[^\n]+\n*)+/,fences:d,hr:/^ {0,3}((?:- *){3,}|(?:_ *){3,}|(?:\* *){3,})(?:\n+|$)/,heading:/^ *(#{1,6})*([^\n]+?) *(?:#+ *)?(?:\n+|$)/,nptable:d,blockquote:/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,list:/^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,html:"^ {0,3}(?:<(script|pre|style)[\\s>][\\s\\S]*?(?:\\1>[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?\\?>\\n*|\\n*|\\n*|?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:\\n{2,}|$)|<(?!script|pre|style)([a-z][\\w-]*)(?:attribute)*? */?>(?=\\h*\\n)[\\s\\S]*?(?:\\n{2,}|$)|(?!script|pre|style)[a-z][\\w-]*\\s*>(?=\\h*\\n)[\\s\\S]*?(?:\\n{2,}|$))",def:/^ {0,3}\[(label)\]: *\n? *([^\s>]+)>?(?:(?: +\n? *| *\n *)(title))? *(?:\n+|$)/,table:d,lheading:/^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,paragraph:/^([^\n]+(?:\n(?!hr|heading|lheading| {0,3}>|<\/?(?:tag)(?: +|\n|\/?>)|<(?:script|pre|style|!--))[^\n]+)*)/,text:/^[^\n]+/};function n(e){this.tokens=[],this.tokens.links={},this.options=e||m.defaults,this.rules=t.normal,this.options.pedantic?this.rules=t.pedantic:this.options.gfm&&(this.options.tables?this.rules=t.tables:this.rules=t.gfm)}t._label=/(?!\s*\])(?:\\[\[\]]|[^\[\]])+/,t._title=/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/,t.def=p(t.def).replace("label",t._label).replace("title",t._title).getRegex(),t.bullet=/(?:[*+-]|\d+\.)/,t.item=/^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/,t.item=p(t.item,"gm").replace(/bull/g,t.bullet).getRegex(),t.list=p(t.list).replace(/bull/g,t.bullet).replace("hr","\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))").replace("def","\\n+(?="+t.def.source+")").getRegex(),t._tag="address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",t._comment=//,t.html=p(t.html,"i").replace("comment",t._comment).replace("tag",t._tag).replace("attribute",/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),t.paragraph=p(t.paragraph).replace("hr",t.hr).replace("heading",t.heading).replace("lheading",t.lheading).replace("tag",t._tag).getRegex(),t.blockquote=p(t.blockquote).replace("paragraph",t.paragraph).getRegex(),t.normal=f({},t),t.gfm=f({},t.normal,{fences:/^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]*?)\n? *\1 *(?:\n+|$)/,paragraph:/^/,heading:/^ *(#{1,6})+([^\n]+?) *#* *(?:\n+|$)/}),t.gfm.paragraph=p(t.paragraph).replace("(?!","(?!"+t.gfm.fences.source.replace("\\1","\\2")+"|"+t.list.source.replace("\\1","\\3")+"|").getRegex(),t.tables=f({},t.gfm,{nptable:/^ *([^|\n ].*\|.*)\n *([-:]+ *\|[-| :]*)(?:\n((?:.*[^>\n ].*(?:\n|$))*)\n*|$)/,table:/^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/}),t.pedantic=f({},t.normal,{html:p("^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?\\1> *(?:\\n{2,}|\\s*$)|
'+(n?e:a(e,!0))+"
\n":""+(n?e:a(e,!0))+"
"},i.prototype.blockquote=function(e){return"\n"+e+"\n"},i.prototype.html=function(e){return e},i.prototype.heading=function(e,t,n){return this.options.headerIds?"
"+e+"
\n"},i.prototype.table=function(e,t){return t&&(t=""+t+""),""+e+"
"},i.prototype.br=function(){return this.options.xhtml?""+a(e.message+"",!0)+"";throw e}}d.exec=d,m.options=m.setOptions=function(e){return f(m.defaults,e),m},m.getDefaults=function(){return{baseUrl:null,breaks:!1,gfm:!0,headerIds:!0,headerPrefix:"",highlight:null,langPrefix:"language-",mangle:!0,pedantic:!1,renderer:new i,sanitize:!1,sanitizer:null,silent:!1,smartLists:!1,smartypants:!1,tables:!0,xhtml:!1}},m.defaults=m.getDefaults(),m.Parser=o,m.parser=o.parse,m.Renderer=i,m.TextRenderer=l,m.Lexer=n,m.lexer=n.lex,m.InlineLexer=s,m.inlineLexer=s.output,m.parse=m,"undefined"!=typeof module&&"object"==typeof exports?module.exports=m:"function"==typeof define&&define.amd?define(function(){return m}):e.marked=m}(this||("undefined"!=typeof window?window:global)); diff --git a/public/javascripts/educoder/edu_application.js b/public/javascripts/educoder/edu_application.js index 7f8f8ac4d..d11511c63 100644 --- a/public/javascripts/educoder/edu_application.js +++ b/public/javascripts/educoder/edu_application.js @@ -1,4 +1,4 @@ -document.write(""); +document.write(""); /*! * JavaScript Cookie v2.2.0 diff --git a/public/react/config/webpack.config.dev.js b/public/react/config/webpack.config.dev.js index a04ec614c..aabcd8fb7 100644 --- a/public/react/config/webpack.config.dev.js +++ b/public/react/config/webpack.config.dev.js @@ -32,7 +32,7 @@ module.exports = { // See the discussion in https://github.com/facebookincubator/create-react-app/issues/343.s // devtool: "cheap-module-eval-source-map", // 开启调试 - // devtool: "eval", // 开启调试 + // devtool: "eval-source-map", // 开启调试 // These are the "entry points" to our application. // This means they will be the "root" imports that are included in JS bundle. // The first two entry points enable "hot" CSS and auto-refreshes for JS. diff --git a/public/react/src/modules/courses/busyWork/NewWorkForm.js b/public/react/src/modules/courses/busyWork/NewWorkForm.js index 27413ba04..e97822df8 100644 --- a/public/react/src/modules/courses/busyWork/NewWorkForm.js +++ b/public/react/src/modules/courses/busyWork/NewWorkForm.js @@ -70,10 +70,23 @@ class NewWorkForm extends Component{ contentFileList, answerFileList, }, () => { - setTimeout(() => { - this.contentMdRef.current.setValue(data.description || '') - this.answerMdRef.current.setValue(data.reference_answer || '') - }, 2000) + // setTimeout(() => { + // this._scrollToTop() + // 阻止setValue的滚动 + // $(window).scroll( function() { + // $("html").scrollTop(0) + // $(window).unbind("scroll"); + // }); + /** + setValue会调用到 codemirror的 o.scrollIntoView(i), 会导致滚动条跳动 + */ + // $('.editormd').parent().css('position', 'fixed').css('left', '-1000px') + // this.contentMdRef.current.setValue(data.description || '') + // this.answerMdRef.current.setValue(data.reference_answer || '') + // setTimeout(() => { + // $('.editormd').parent().css('position', '').css('left', 'auto') + // }, 100); + // }, 500) this.props.form.setFieldsValue({ title: data.name, @@ -85,12 +98,13 @@ class NewWorkForm extends Component{ } else { // new } - this._scrollToTop() + // this._scrollToTop() } _scrollToTop = () => { - setTimeout(() => { - $("html").animate({ scrollTop: 0 }) - }, 1500) + // setTimeout(() => { + $("html").scrollTop(0) + // $("html").animate({ scrollTop: 0 }) + // }, 1000) } // 输入title @@ -292,6 +306,8 @@ class NewWorkForm extends Component{ this.setState({ base_on_project: !this.state.base_on_project }) } componentDidMount() { + this.isEdit = this.props.match.url.indexOf('/edit') + window.$('.groupSetting .ant-form-item-label > label').addClass('ant-form-item-required') this._scrollToTop() } @@ -303,15 +319,13 @@ class NewWorkForm extends Component{ let{ title_value, contentFileList, answerFileList, max_num, min_num, base_on_project, init_max_num, init_min_num, - title_num, course_name, category, has_commit, has_project, - - isEdit + title_num, course_name, category, has_commit, has_project }=this.state const { current_user } = this.props const courseId = this.state.course_id || this.props.match.params.coursesId ; - if ((isEdit) && !this.state.workLoaded) { + if ((this.isEdit) && !this.state.description) { return '' } const uploadProps = { @@ -439,7 +453,8 @@ class NewWorkForm extends Component{ }], })(