diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 8797c4074..508d005a4 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -250,8 +250,9 @@ class ApplicationController < ActionController::Base # 开放课程通过链接访问的用户 if !User.current.logged? && !params[:chinaoocTimestamp].blank? && !params[:websiteName].blank? && !params[:chinaoocKey].blank? content = "#{OPENKEY}#{params[:websiteName]}#{params[:chinaoocTimestamp]}" + if Digest::MD5.hexdigest(content) == params[:chinaoocKey] - user = User.open_class_user + user = open_class_user start_user_session(user) if user User.current = user end @@ -615,4 +616,27 @@ class ApplicationController < ActionController::Base def set_export_cookies cookies[:fileDownload] = true end + + # 149课程的评审用户数据创建(包含创建课堂学生) + def open_class_user + user = User.find_by(login: "OpenClassUser") + unless user + ActiveRecord::Base.transaction do + user_params = {status: 1, login: "OpenClassUser", lastname: "开放课程", + nickname: "开放课程", professional_certification: 1, certification: 1, grade: 0, + password: "12345678", phone: "11122223333", profile_completed: 1} + user = User.create!(user_params) + + UserExtension.create!(user_id: user.id, gender: 0, school_id: 3396, :identity => 1, :student_id => "openclassuser") # 3396 + + subject = Subject.find_by(id: 149) + if subject + subject.courses.each do |course| + CourseMember.create!(course_id: course.id, role: 3, user_id: user.id) if !course.course_members.exists?(user_id: user.id) + end + end + end + end + user + end end diff --git a/app/controllers/colleges_controller.rb b/app/controllers/colleges_controller.rb index 66d327649..f869e9ec6 100644 --- a/app/controllers/colleges_controller.rb +++ b/app/controllers/colleges_controller.rb @@ -40,8 +40,8 @@ class CollegesController < ApplicationController def teachers @teachers = User.find_by_sql("SELECT users.id, users.login, users.lastname, users.firstname, users.nickname, IFNULL((SELECT count(shixuns.id) FROM shixuns where shixuns.user_id =users.id group by shixuns.user_id), 0) AS publish_shixun_count, - (SELECT count(c.id) FROM courses c, course_members m WHERE c.id != 1309 and m.course_id = c.id AND m.role in (1,2,3) and c.school_id = #{current_school.id} AND m.user_id=users.id AND c.is_delete = 0) as course_count - FROM `users`, user_extensions ue where users.id=ue.user_id and ue.identity=0 and ue.school_id=#{current_school.id} ORDER BY publish_shixun_count desc, course_count desc, id desc LIMIT 10") + (SELECT count(c.id) FROM courses c, course_members m WHERE c.id != 1309 and m.course_id = c.id AND m.user_id=users.id AND m.role in (1,2,3) and c.school_id = #{current_school.id} AND c.is_delete = 0) as course_count + FROM `users`, user_extensions ue where ue.school_id=#{current_school.id} and users.id=ue.user_id and ue.identity=0 ORDER BY publish_shixun_count desc, course_count desc, id desc LIMIT 10") # ).order("publish_shixun_count desc, experience desc").limit(10) @teachers = @teachers.map do |teacher| diff --git a/app/controllers/commons_controller.rb b/app/controllers/commons_controller.rb index 0c0fe79af..43ea31c97 100644 --- a/app/controllers/commons_controller.rb +++ b/app/controllers/commons_controller.rb @@ -51,7 +51,8 @@ class CommonsController < ApplicationController 200 end when 'journals_for_message' - if current_user.course_identity(@object.jour.course) >= Course::STUDENT && @object.user != current_user + course = @object.jour&.course || @object.jour&.student_work&.homework_common&.course + if current_user.course_identity(course) >= Course::STUDENT && @object.user != current_user 403 else 200 diff --git a/app/controllers/ecs/students_controller.rb b/app/controllers/ecs/students_controller.rb index c21d625e0..abc5ddb65 100644 --- a/app/controllers/ecs/students_controller.rb +++ b/app/controllers/ecs/students_controller.rb @@ -14,7 +14,7 @@ class Ecs::StudentsController < Ecs::BaseController end def import - success_count = Ecs::ImportStudentService.call(current_year, params[:attachment_id]) + success_count = Ecs::ImportStudentService.call(current_year, params) render_ok(success_count: success_count) rescue Ecs::ImportStudentService::Error => ex render_error(ex.message) diff --git a/app/controllers/games_controller.rb b/app/controllers/games_controller.rb index b9da12ab0..4a087ae7a 100644 --- a/app/controllers/games_controller.rb +++ b/app/controllers/games_controller.rb @@ -559,7 +559,7 @@ class GamesController < ApplicationController secret_rep = @shixun.shixun_secret_repository logger.info("############secret_rep: #{secret_rep}") if secret_rep&.repo_name - secretGitUrl = repo_url secret_rep.repo_path + secretGitUrl = repo_ip_url secret_rep.repo_path br_params.merge!({secretGitUrl: Base64.urlsafe_encode64(secretGitUrl), secretDir: secret_rep.secret_dir_path}) logger.info("#######br_params:#{br_params}") end diff --git a/app/controllers/graduation_tasks_controller.rb b/app/controllers/graduation_tasks_controller.rb index 6a0ce85a9..8792959d8 100644 --- a/app/controllers/graduation_tasks_controller.rb +++ b/app/controllers/graduation_tasks_controller.rb @@ -171,7 +171,7 @@ class GraduationTasksController < ApplicationController end end else - @work_list = @work + @work_list = !@task.published? ? [] : @work @view_work = false @work_count = @work_list.count @all_work_count = @work_list.count diff --git a/app/models/graduation_work.rb b/app/models/graduation_work.rb index 73c217114..94c2633ae 100644 --- a/app/models/graduation_work.rb +++ b/app/models/graduation_work.rb @@ -55,7 +55,7 @@ class GraduationWork < ApplicationRecord def delete_atta atta last_score = graduation_work_scores.where.not(score: nil).last - atta.author_id == user_id && (!last_score.present? || last_score.try(:created_at) < atta.created_on) + (atta.author_id == User.current.id) && (last_score.blank? || last_score.try(:created_at) < atta.created_on) end # 分班名 diff --git a/app/models/student_work.rb b/app/models/student_work.rb index 6b4025885..2e7f843ae 100644 --- a/app/models/student_work.rb +++ b/app/models/student_work.rb @@ -106,7 +106,7 @@ class StudentWork < ApplicationRecord def delete_atta atta last_score = student_works_scores.where.not(score: nil).last - atta.author_id == user_id && (!last_score.present? || last_score.try(:created_at) < atta.created_on) + (atta.author_id == User.current.id) && (last_score.blank? || last_score.try(:created_at) < atta.created_on) end # 作品总体评价 diff --git a/app/models/student_works_score.rb b/app/models/student_works_score.rb index 86d393f93..299b61596 100644 --- a/app/models/student_works_score.rb +++ b/app/models/student_works_score.rb @@ -1,6 +1,6 @@ class StudentWorksScore < ApplicationRecord #appeal_status: 0:正常;1:申诉中,2:撤销申诉;3:申诉成功;4:申诉被拒绝;5:申诉失效 -belongs_to :student_work + belongs_to :student_work belongs_to :user has_many :journals_for_messages, -> { order('created_on desc') }, as: :jour, dependent: :destroy has_one :student_works_scores_appeal, dependent: :destroy diff --git a/app/models/user.rb b/app/models/user.rb index ebf68cce6..70cd54c92 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,686 +1,663 @@ -class User < ApplicationRecord - include Watchable - include Searchable::Dependents::User - - # Account statuses - STATUS_ANONYMOUS = 0 - STATUS_ACTIVE = 1 - STATUS_REGISTERED = 2 - STATUS_LOCKED = 3 - - # tpi tpm权限控制 - EDU_ADMIN = 1 # 超级管理员 - EDU_BUSINESS = 2 # 运营人员 - EDU_SHIXUN_MANAGER = 3 # 实训管理员 - EDU_SHIXUN_MEMBER = 4 # 实训成员 - EDU_CERTIFICATION_TEACHER = 5 # 平台认证的老师 - EDU_GAME_MANAGER = 6 # TPI的创建者 - EDU_TEACHER = 7 # 平台老师,但是未认证 - EDU_NORMAL = 8 # 普通用户 - - VALID_EMAIL_REGEX = /^[a-zA-Z0-9]+([.\-_\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/i - VALID_PHONE_REGEX = /^1\d{10}$/ - - LOGIN_LENGTH_LIMIT = 30 - MAIL_LENGTH_LMIT = 60 - - MIX_PASSWORD_LIMIT = 8 - - has_one :user_extension, dependent: :destroy - accepts_nested_attributes_for :user_extension, update_only: true - - has_many :memos, foreign_key: 'author_id' - has_many :created_shixuns, class_name: 'Shixun' - has_many :shixun_members, :dependent => :destroy - has_many :shixuns, :through => :shixun_members - has_many :myshixuns, :dependent => :destroy - has_many :study_shixuns, through: :myshixuns, source: :shixun # 已学习的实训 - has_many :course_messages - has_many :courses, dependent: :destroy - - #试卷 - has_many :exercise_banks, :dependent => :destroy - has_many :exercise_users, :dependent => :destroy - has_many :exercise_answers, :dependent => :destroy #针对每个题目学生的答案 - has_many :exercise_shixun_answers, :dependent => :destroy #针对每个实训题目学生的答案 - has_many :exercise_answer_comments, :dependent => :destroy - has_many :exercises, :dependent => :destroy #创建的试卷 - - has_many :homework_banks, dependent: :destroy - - has_many :graduation_works, dependent: :destroy - - has_many :students_for_courses, foreign_key: :student_id, dependent: :destroy - has_one :onclick_time, :dependent => :destroy - - # 新版私信 - has_many :private_messages, dependent: :destroy - has_many :recent_contacts, through: :private_messages, source: :target - has_many :tidings, :dependent => :destroy - - has_many :games, :dependent => :destroy - has_many :created_subjects, foreign_key: :user_id, class_name: 'Subject' - has_many :subject_members, :dependent => :destroy - has_many :subjects, :through => :subject_members - has_many :grades, :dependent => :destroy - has_many :experiences, :dependent => :destroy - has_many :student_works, :dependent => :destroy - has_many :student_works_scores - has_many :student_works_evaluation_distributions - - # 毕业设计 - has_many :graduation_topics, :dependent => :destroy - has_many :student_graduation_topics, :dependent => :destroy - - # 题库 - has_many :question_banks, :dependent => :destroy - # 毕设任务题库 - has_many :gtask_banks, dependent: :destroy - has_many :gtopic_banks, dependent: :destroy - - #问卷 - has_many :course_members, :dependent => :destroy - has_many :poll_votes, :dependent => :destroy - has_many :poll_users, :dependent => :destroy - - has_many :messages,foreign_key: 'author_id',:dependent => :destroy - - has_many :journals_for_messages, :as => :jour, :dependent => :destroy - has_many :teacher_course_groups, :dependent => :destroy - - has_many :attachments,foreign_key: :author_id, :dependent => :destroy - - # 工程认证 - has_many :ec_school_users,:dependent => :destroy - has_many :schools, :through => :ec_school_users - - has_many :ec_major_school_users, :dependent => :destroy - has_many :ec_major_schools, :through => :ec_major_school_users - - has_many :ec_course_users - - has_many :department_members, dependent: :destroy #部门管理员 - - # 课堂 - has_many :student_course_members, -> { course_students }, class_name: 'CourseMember' - has_many :as_student_courses, through: :student_course_members, source: :course - has_many :manage_course_members, -> { teachers_and_admin }, class_name: 'CourseMember' - has_many :manage_courses, through: :manage_course_members, source: :course - - # 关注 - has_many :be_watchers, foreign_key: :user_id, dependent: :destroy # 我的关注 - has_many :be_watcher_users, through: :be_watchers, dependent: :destroy # 我关注的用户 - - # 认证 - has_many :apply_user_authentication - has_one :process_real_name_apply, -> { processing.real_name_auth.order(created_at: :desc) }, class_name: 'ApplyUserAuthentication' - has_one :process_professional_apply, -> { processing.professional_auth.order(created_at: :desc) }, class_name: 'ApplyUserAuthentication' - has_many :apply_actions, dependent: :destroy - has_many :trail_auth_apply_actions, -> { where(container_type: 'TrialAuthorization') }, class_name: 'ApplyAction' - - has_many :attendances - - # 兴趣 - has_many :user_interests, dependent: :delete_all - has_many :interests, through: :user_interests, source: :repertoire - - # 众包 - has_many :project_packages, foreign_key: :creator_id, dependent: :destroy - has_many :bidding_users, dependent: :destroy - has_many :bidden_project_packages, through: :bidding_users, source: :project_package - - # 项目 - has_many :applied_projects, dependent: :destroy - - # 教学案例 - has_many :libraries, dependent: :destroy - - # 视频 - has_many :videos, dependent: :destroy - - # 客户管理 - belongs_to :partner, optional: true - - # Groups and active users - scope :active, lambda { where(status: STATUS_ACTIVE) } - - attr_accessor :password, :password_confirmation - - delegate :gender, :department_id, :school_id, :location, :location_city, :technical_title, to: :user_extension, allow_nil: true - - before_save :update_hashed_password - - # - # validations - # - validates_presence_of :login, :if => Proc.new { |user| !user.is_a?(AnonymousUser) }, case_sensitive: false - validates_uniqueness_of :login, :if => Proc.new { |user| user.login_changed? && user.login.present? }, case_sensitive: false - validates_uniqueness_of :mail, :if => Proc.new { |user| user.mail_changed? && user.mail.present? }, case_sensitive: false - validates_uniqueness_of :phone, :if => Proc.new { |user| user.phone_changed? && user.phone.present? }, case_sensitive: false - validates_length_of :login, maximum: LOGIN_LENGTH_LIMIT - validates_length_of :mail, maximum: MAIL_LENGTH_LMIT - # validates_format_of :mail, with: VALID_EMAIL_REGEX, multiline: true - # validates_format_of :phone, with: VALID_PHONE_REGEX, multiline: true - validate :validate_password_length - - # validates :nickname, presence: true, length: { maximum: 10 } - # validates :lastname, presence: true - - # 删除自动登录的token,一旦退出下次会提示需要登录 - def delete_autologin_token(value) - Token.where(:user_id => id, :action => 'autologin', :value => value).delete_all - end - - def delete_session_token(value) - Token.where(:user_id => id, :action => 'session', :value => value).delete_all - end - - def git_mail - mail.blank? ? "#{login}@educoder.net" : mail - end - - # 学号 - def student_id - self.user_extension.try(:student_id) - end - - # 关注数 - def follow_count - Watcher.where(user_id: id, watchable_type: %w(Principal User)).count - # User.watched_by(id).count - end - - # 粉丝数 - def fan_count - Watcher.where(watchable_type: %w(Principal User), watchable_id: id).count - # watchers.count - end - - # 判断当前用户是否为老师 - def is_teacher? - self.user_extension.teacher? - end - - # 平台认证的老师 - def is_certification_teacher - self.user_extension.teacher? && self.professional_certification - end - - def certification_teacher? - professional_certification? && user_extension.teacher? - end - - # 判断用户的身份 - def identity - ue = self.user_extension - unless ue.blank? - if ue.teacher? - ue.technical_title ? ue.technical_title : "老师" - elsif ue.student? - "学生" - else - ue.technical_title ? ue.technical_title : "专业人士" - end - end - end - - # 判断当前用户是否通过职业认证 - def pro_certification? - professional_certification - end - - # 用户的学校名称 - def school_name - user_extension&.school&.name || '' - end - - # 用户的学院名称 - def department_name - user_extension&.department&.name || '' - end - - # 课堂的老师(创建者、老师、助教) - def teacher_of_course?(course) - course.course_members.exists?(user_id: id, role: [1,2,3], is_active: 1) || admin? || business? - end - - # 课堂的老师(创建者、老师、助教),不用考虑当前身份 - def teacher_of_course_non_active?(course) - course.course_members.exists?(user_id: id, role: [1,2,3]) - end - - # 是否是教师,课堂管理员或者超级管理员 - def teacher_or_admin?(course) - course.course_members.exists?(user_id: id, role: [1,2], is_active: 1) || admin? || business? - end - - # 课堂的创建者(考虑到多重身份的用户) - def creator_of_course?(course) - course.course_members.exists?(user_id: id, role: 1, is_active: 1) || admin? || business? - end - - # 课堂的学生 - def student_of_course?(course) - course.course_members.exists?(user_id: id, role: %i[STUDENT]) - end - - # 课堂成员 - def member_of_course?(course) - course&.course_members.exists?(user_id: id) - end - - # 实训路径管理员 - def creator_of_subject?(subject) - subject.user_id == id || admin? - end - - # 实训路径:合作者、admin - def manager_of_subject?(subject) - subject.subject_members.exists?(user_id: id, role: [1,2]) || admin? - end - - # 实训管理员:实训合作者、admin - def manager_of_shixun?(shixun) - shixun.shixun_members.exists?(role: [1,2], user_id: id) || admin? || business? - end - - # 实训管理员 - def creator_of_shixun?(shixun) - id == shixun.user_id - end - - # 实训的合作者 - def member_of_shixun?(shixun) - #self.shixun_members.where(:role => 2, :shixun_id => shixun.id).present? - shixun.shixun_members.exists?(role: 2, user_id: id) - end - - # TPI的创建者 - def creator_of_game?(game) - id == game.user_id - end - - # 用户账号状态 - def active? - status == STATUS_ACTIVE - end - - def registered? - status == STATUS_REGISTERED - end - - def locked? - status == STATUS_LOCKED - end - - def activate - self.status = STATUS_ACTIVE - end - - def register - self.status = STATUS_REGISTERED - end - - def lock - self.status = STATUS_LOCKED - end - - def activate! - update_attribute(:status, STATUS_ACTIVE) - end - - def register! - update_attribute(:status, STATUS_REGISTERED) - end - - def lock! - update_attribute(:status, STATUS_LOCKED) - end - - # 课程用户身份 - def course_identity(course) - if !logged? - Course::Anonymous - elsif admin? - Course::ADMIN - elsif business? - Course::BUSINESS - else - role = course.course_members.find_by(user_id: id, is_active: 1)&.role - case role - when nil then Course::NORMAL - when 'CREATOR' then Course::CREATOR - when 'PROFESSOR' then Course::PROFESSOR - when 'STUDENT' then Course::STUDENT - when 'ASSISTANT_PROFESSOR' then Course::ASSISTANT_PROFESSOR - end - end - end - - # 实训用户身份 - def shixun_identity(shixun) - @identity = - if admin? - User::EDU_ADMIN - elsif business? - User::EDU_BUSINESS - elsif creator_of_shixun?(shixun) - User::EDU_SHIXUN_MANAGER - elsif member_of_shixun?(shixun) - User::EDU_SHIXUN_MEMBER - elsif is_certification_teacher - User::EDU_CERTIFICATION_TEACHER - elsif is_teacher? - User::EDU_TEACHER - else - User::EDU_NORMAL - end - return @identity - end - - # tpi的用户身份 - def game_identity(game) - shixun = game.myshixun.shixun - @identity = - if admin? - User::EDU_ADMIN - elsif business? - User::EDU_BUSINESS - elsif creator_of_shixun?(shixun) - User::EDU_SHIXUN_MANAGER - elsif member_of_shixun?(shixun) - User::EDU_SHIXUN_MEMBER - elsif is_certification_teacher - User::EDU_CERTIFICATION_TEACHER - elsif creator_of_game?(game) - User::EDU_GAME_MANAGER - elsif is_teacher? - User::EDU_TEACHER - else - User::EDU_NORMAL - end - return @identity - end - - # 我的实训 - def my_shixuns - shixun_ids = shixun_members.pluck(:shixun_id) + myshixuns.pluck(:shixun_id) - Shixun.where(:id => shixun_ids).visible - end - - # 用户是否有权限查看实训 - # 1、实训删除只有管理员能看到 - # 2、实训隐藏了只有管理员、实训合作者能看到 - # 3、如果有限制学校范围,则学校的用户、管理员、实训合作者能看到 - def shixun_permission(shixun) - case shixun.status - when -1 # 软删除只有管理员能访问 - admin? - when 0, 1, 3 # 申请发布或者已关闭的实训,只有实训管理员可以访问 - manager_of_shixun?(shixun) - when 2 - if shixun.hidden - manager_of_shixun?(shixun) - else - shixun.use_scope == 0 || manager_of_shixun?(shixun) || shixun.shixun_schools.exists?(school_id: school_id) - end - end - end - - # 用户在平台名称的显示方式 - def full_name - return '游客' unless logged? - - name = show_realname? ? lastname + firstname : nickname - name.blank? ? (nickname.blank? ? login : nickname) : name - end - - # 用户的真实姓名(不考虑用户是否隐藏了真实姓名,课堂模块都用真实姓名) - def real_name - return '游客' unless logged? - name = lastname + firstname - name = name.blank? ? (nickname.blank? ? login : nickname) : name - name.gsub(/\s+/, '').strip #6.11 -hs - end - - def only_real_name - "#{lastname}#{firstname}" - end - - # 用户是否选题毕设课题 - def selected_topic?(topic) - student_graduation_topics.where(graduation_topic_id: topic.id).last.try(:status) - end - - def click_time - click_time = OnclickTime.find_by(user_id: id) || OnclickTime.create(user_id: id, onclick_time: created_on) - click_time.onclick_time - end - - def manager_of_memo?(memo) - id == memo.author_id || admin? || business? - end - - # 是否是项目管理者 - def manager_of_project?(project) - project.project_members.where(user_id: id).count > 0 - end - - def logged? - true - end - - def active? - status == STATUS_ACTIVE - end - - def locked? - status == STATUS_LOCKED - end - - def phone_binded? - phone.present? - end - - def self.current=(user) - Thread.current[:current_user] = user - end - - def self.current - Thread.current[:current_user] ||= User.anonymous - end - - def self.anonymous - anonymous_user = AnonymousUser.unscoped.take - if anonymous_user.nil? - anonymous_user = AnonymousUser.unscoped.create(lastname: 'Anonymous', firstname: '', login: '', - mail: '358551897@qq.com', phone: '13333333333', status: 0) - raise "Unable to create the anonymous user: error_info:#{anonymous_user.errors.messages}" if anonymous_user.new_record? - end - anonymous_user - end - - # Returns the user who matches the given autologin +key+ or nil - def self.try_to_autologin(key) - user = Token.find_active_user('autologin', key) - user.update(last_login_on: Time.now) if user - user - end - - def self.hash_password(clear_password) - Digest::SHA1.hexdigest(clear_password || "") - end - - def check_password?(clear_password) - # Preventing Timing Attack - ActiveSupport::SecurityUtils.secure_compare( - User.hash_password("#{salt}#{User.hash_password clear_password}"), - hashed_password - ) - end - - # 工程认证的学校 - def ec_school - school_id = self.ec_school_users.pluck(:school_id).first || - self.ec_major_schools.pluck(:school_id).first || - (self.ec_course_users.first && self.ec_course_users.first.try(:ec_course).try(:ec_year).try(:ec_major_school).try(:school_id)) - end - - # 登录,返回用户名与密码匹配的用户 - def self.try_to_login(login, password) - login = login.to_s.strip - password = password.to_s - - # Make sure no one can sign in with an empty login or password - return nil if login.empty? || password.empty? - if (login =~ VALID_EMAIL_REGEX) - user = find_by_mail(login) - elsif (login =~ VALID_PHONE_REGEX) - user = find_by_phone(login) - else - user = find_by_login(login) - end - - user - rescue => text - raise text - end - - def show_real_name - name = lastname + firstname - if name.blank? - nickname.blank? ? login : nickname - else - name - end - end - - def update_hashed_password - if password - salt_password(password) - end - end - - def salt_password(clear_password) - self.salt = User.generate_salt - self.hashed_password = User.hash_password("#{salt}#{User.hash_password clear_password}") - end - - def self.generate_salt - Educoder::Utils.random_hex(16) - end - - # 全部已认证 - def all_certified? - authentication? && professional_certification? - end - - # 是否绑定邮箱 - def email_binded? - mail.present? - end - - # 学院的url标识 - def college_identifier - Department.find_by_id(department_members.pluck(:department_id).first)&.identifier - end - - # 是否能申请试用 - def can_apply_trial? - return false if certification == 1 - - apply = ApplyAction.order(created_at: :desc).find_by(user_id: id, container_type: 'TrialAuthorization') - - apply.present? && !apply.status.zero? - end - - # 是否已经签到 - def attendance_signed? - attendance = Attendance.find_by(user_id: id) - - attendance.present? && Util.days_between(Time.zone.now, attendance.created_at).zero? - end - - # 明日签到金币 - def tomorrow_attendance_gold - Attendance.find_by(user_id: id)&.next_gold || 60 # 基础50,连续签到+10 - end - - def admin_or_business? - admin? || business? - end - - # 149课程的评审用户数据创建(包含创建课堂学生) - def open_class_user - user = User.find_by(login: "OpenClassUser") - unless user - ActiveRecord::Base.transaction do - user_params = {status: 1, login: "OpenClassUser", lastname: "开放课程", - nickname: "开放课程", professional_certification: 1, certification: 1, grade: 0, - password: "12345678", phone: "11122223333", profile_completed: 1} - user = User.create!(user_params) - - UserExtension.create!(user_id: user.id, gender: 0, school_id: 117, :identity => 1, :student_id => "openclassuser") - - subject = Subject.find_by(id: 149) - if subject - subject.courses.each do |course| - CourseMember.create!(course_id: course.id, role: 4, user_id: user.id) if !course.course_students.exists?(user_id: user.id) - end - end - end - end - user - end - - protected - def validate_password_length - # 管理员的初始密码是5位 - if password.present? && password.size < MIX_PASSWORD_LIMIT && !User.current.admin? - raise("密码长度不能低于#{MIX_PASSWORD_LIMIT}位") - end - end -end - - -class AnonymousUser < User - validate :validate_anonymous_uniqueness, :on => :create - - def validate_anonymous_uniqueness - # There should be only one AnonymousUser in the database - errors.add :base, 'An anonymous user already exists.' if AnonymousUser.exists? - end - - def available_custom_fields - [] - end - - # Overrides a few properties - def logged?; false end - def admin; false end - def name(*args); I18n.t(:label_user_anonymous) end - # def mail=(*args); nil end - # def mail; nil end - def time_zone; nil end - def rss_key; nil end - - - def membership(*args) - nil - end - - def member_of?(*args) - false - end - - # Anonymous user can not be destroyed - def destroy - false - end - - protected - - def instantiate_email_address - end - -end +class User < ApplicationRecord + include Watchable + include Searchable::Dependents::User + + # Account statuses + STATUS_ANONYMOUS = 0 + STATUS_ACTIVE = 1 + STATUS_REGISTERED = 2 + STATUS_LOCKED = 3 + + # tpi tpm权限控制 + EDU_ADMIN = 1 # 超级管理员 + EDU_BUSINESS = 2 # 运营人员 + EDU_SHIXUN_MANAGER = 3 # 实训管理员 + EDU_SHIXUN_MEMBER = 4 # 实训成员 + EDU_CERTIFICATION_TEACHER = 5 # 平台认证的老师 + EDU_GAME_MANAGER = 6 # TPI的创建者 + EDU_TEACHER = 7 # 平台老师,但是未认证 + EDU_NORMAL = 8 # 普通用户 + + VALID_EMAIL_REGEX = /^[a-zA-Z0-9]+([.\-_\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/i + VALID_PHONE_REGEX = /^1\d{10}$/ + + LOGIN_LENGTH_LIMIT = 30 + MAIL_LENGTH_LMIT = 60 + + MIX_PASSWORD_LIMIT = 8 + + has_one :user_extension, dependent: :destroy + accepts_nested_attributes_for :user_extension, update_only: true + + has_many :memos, foreign_key: 'author_id' + has_many :created_shixuns, class_name: 'Shixun' + has_many :shixun_members, :dependent => :destroy + has_many :shixuns, :through => :shixun_members + has_many :myshixuns, :dependent => :destroy + has_many :study_shixuns, through: :myshixuns, source: :shixun # 已学习的实训 + has_many :course_messages + has_many :courses, dependent: :destroy + + #试卷 + has_many :exercise_banks, :dependent => :destroy + has_many :exercise_users, :dependent => :destroy + has_many :exercise_answers, :dependent => :destroy #针对每个题目学生的答案 + has_many :exercise_shixun_answers, :dependent => :destroy #针对每个实训题目学生的答案 + has_many :exercise_answer_comments, :dependent => :destroy + has_many :exercises, :dependent => :destroy #创建的试卷 + + has_many :homework_banks, dependent: :destroy + + has_many :graduation_works, dependent: :destroy + + has_many :students_for_courses, foreign_key: :student_id, dependent: :destroy + has_one :onclick_time, :dependent => :destroy + + # 新版私信 + has_many :private_messages, dependent: :destroy + has_many :recent_contacts, through: :private_messages, source: :target + has_many :tidings, :dependent => :destroy + + has_many :games, :dependent => :destroy + has_many :created_subjects, foreign_key: :user_id, class_name: 'Subject' + has_many :subject_members, :dependent => :destroy + has_many :subjects, :through => :subject_members + has_many :grades, :dependent => :destroy + has_many :experiences, :dependent => :destroy + has_many :student_works, :dependent => :destroy + has_many :student_works_scores + has_many :student_works_evaluation_distributions + + # 毕业设计 + has_many :graduation_topics, :dependent => :destroy + has_many :student_graduation_topics, :dependent => :destroy + + # 题库 + has_many :question_banks, :dependent => :destroy + # 毕设任务题库 + has_many :gtask_banks, dependent: :destroy + has_many :gtopic_banks, dependent: :destroy + + #问卷 + has_many :course_members, :dependent => :destroy + has_many :poll_votes, :dependent => :destroy + has_many :poll_users, :dependent => :destroy + + has_many :messages,foreign_key: 'author_id',:dependent => :destroy + + has_many :journals_for_messages, :as => :jour, :dependent => :destroy + has_many :teacher_course_groups, :dependent => :destroy + + has_many :attachments,foreign_key: :author_id, :dependent => :destroy + + # 工程认证 + has_many :ec_school_users,:dependent => :destroy + has_many :schools, :through => :ec_school_users + + has_many :ec_major_school_users, :dependent => :destroy + has_many :ec_major_schools, :through => :ec_major_school_users + + has_many :ec_course_users + + has_many :department_members, dependent: :destroy #部门管理员 + + # 课堂 + has_many :student_course_members, -> { course_students }, class_name: 'CourseMember' + has_many :as_student_courses, through: :student_course_members, source: :course + has_many :manage_course_members, -> { teachers_and_admin }, class_name: 'CourseMember' + has_many :manage_courses, through: :manage_course_members, source: :course + + # 关注 + has_many :be_watchers, foreign_key: :user_id, dependent: :destroy # 我的关注 + has_many :be_watcher_users, through: :be_watchers, dependent: :destroy # 我关注的用户 + + # 认证 + has_many :apply_user_authentication + has_one :process_real_name_apply, -> { processing.real_name_auth.order(created_at: :desc) }, class_name: 'ApplyUserAuthentication' + has_one :process_professional_apply, -> { processing.professional_auth.order(created_at: :desc) }, class_name: 'ApplyUserAuthentication' + has_many :apply_actions, dependent: :destroy + has_many :trail_auth_apply_actions, -> { where(container_type: 'TrialAuthorization') }, class_name: 'ApplyAction' + + has_many :attendances + + # 兴趣 + has_many :user_interests, dependent: :delete_all + has_many :interests, through: :user_interests, source: :repertoire + + # 众包 + has_many :project_packages, foreign_key: :creator_id, dependent: :destroy + has_many :bidding_users, dependent: :destroy + has_many :bidden_project_packages, through: :bidding_users, source: :project_package + + # 项目 + has_many :applied_projects, dependent: :destroy + + # 教学案例 + has_many :libraries, dependent: :destroy + + # 视频 + has_many :videos, dependent: :destroy + + # 客户管理 + belongs_to :partner, optional: true + + # Groups and active users + scope :active, lambda { where(status: STATUS_ACTIVE) } + + attr_accessor :password, :password_confirmation + + delegate :gender, :department_id, :school_id, :location, :location_city, :technical_title, to: :user_extension, allow_nil: true + + before_save :update_hashed_password + + # + # validations + # + validates_presence_of :login, :if => Proc.new { |user| !user.is_a?(AnonymousUser) }, case_sensitive: false + validates_uniqueness_of :login, :if => Proc.new { |user| user.login_changed? && user.login.present? }, case_sensitive: false + validates_uniqueness_of :mail, :if => Proc.new { |user| user.mail_changed? && user.mail.present? }, case_sensitive: false + validates_uniqueness_of :phone, :if => Proc.new { |user| user.phone_changed? && user.phone.present? }, case_sensitive: false + validates_length_of :login, maximum: LOGIN_LENGTH_LIMIT + validates_length_of :mail, maximum: MAIL_LENGTH_LMIT + # validates_format_of :mail, with: VALID_EMAIL_REGEX, multiline: true + # validates_format_of :phone, with: VALID_PHONE_REGEX, multiline: true + validate :validate_password_length + + # validates :nickname, presence: true, length: { maximum: 10 } + # validates :lastname, presence: true + + # 删除自动登录的token,一旦退出下次会提示需要登录 + def delete_autologin_token(value) + Token.where(:user_id => id, :action => 'autologin', :value => value).delete_all + end + + def delete_session_token(value) + Token.where(:user_id => id, :action => 'session', :value => value).delete_all + end + + def git_mail + mail.blank? ? "#{login}@educoder.net" : mail + end + + # 学号 + def student_id + self.user_extension.try(:student_id) + end + + # 关注数 + def follow_count + Watcher.where(user_id: id, watchable_type: %w(Principal User)).count + # User.watched_by(id).count + end + + # 粉丝数 + def fan_count + Watcher.where(watchable_type: %w(Principal User), watchable_id: id).count + # watchers.count + end + + # 判断当前用户是否为老师 + def is_teacher? + self.user_extension.teacher? + end + + # 平台认证的老师 + def is_certification_teacher + self.user_extension.teacher? && self.professional_certification + end + + def certification_teacher? + professional_certification? && user_extension.teacher? + end + + # 判断用户的身份 + def identity + ue = self.user_extension + unless ue.blank? + if ue.teacher? + ue.technical_title ? ue.technical_title : "老师" + elsif ue.student? + "学生" + else + ue.technical_title ? ue.technical_title : "专业人士" + end + end + end + + # 判断当前用户是否通过职业认证 + def pro_certification? + professional_certification + end + + # 用户的学校名称 + def school_name + user_extension&.school&.name || '' + end + + # 用户的学院名称 + def department_name + user_extension&.department&.name || '' + end + + # 课堂的老师(创建者、老师、助教) + def teacher_of_course?(course) + course.course_members.exists?(user_id: id, role: [1,2,3], is_active: 1) || admin? || business? + end + + # 课堂的老师(创建者、老师、助教),不用考虑当前身份 + def teacher_of_course_non_active?(course) + course.course_members.exists?(user_id: id, role: [1,2,3]) + end + + # 是否是教师,课堂管理员或者超级管理员 + def teacher_or_admin?(course) + course.course_members.exists?(user_id: id, role: [1,2], is_active: 1) || admin? || business? + end + + # 课堂的创建者(考虑到多重身份的用户) + def creator_of_course?(course) + course.course_members.exists?(user_id: id, role: 1, is_active: 1) || admin? || business? + end + + # 课堂的学生 + def student_of_course?(course) + course.course_members.exists?(user_id: id, role: %i[STUDENT]) + end + + # 课堂成员 + def member_of_course?(course) + course&.course_members.exists?(user_id: id) + end + + # 实训路径管理员 + def creator_of_subject?(subject) + subject.user_id == id || admin? + end + + # 实训路径:合作者、admin + def manager_of_subject?(subject) + subject.subject_members.exists?(user_id: id, role: [1,2]) || admin? + end + + # 实训管理员:实训合作者、admin + def manager_of_shixun?(shixun) + shixun.shixun_members.exists?(role: [1,2], user_id: id) || admin? || business? + end + + # 实训管理员 + def creator_of_shixun?(shixun) + id == shixun.user_id + end + + # 实训的合作者 + def member_of_shixun?(shixun) + #self.shixun_members.where(:role => 2, :shixun_id => shixun.id).present? + shixun.shixun_members.exists?(role: 2, user_id: id) + end + + # TPI的创建者 + def creator_of_game?(game) + id == game.user_id + end + + # 用户账号状态 + def active? + status == STATUS_ACTIVE + end + + def registered? + status == STATUS_REGISTERED + end + + def locked? + status == STATUS_LOCKED + end + + def activate + self.status = STATUS_ACTIVE + end + + def register + self.status = STATUS_REGISTERED + end + + def lock + self.status = STATUS_LOCKED + end + + def activate! + update_attribute(:status, STATUS_ACTIVE) + end + + def register! + update_attribute(:status, STATUS_REGISTERED) + end + + def lock! + update_attribute(:status, STATUS_LOCKED) + end + + # 课程用户身份 + def course_identity(course) + if !logged? + Course::Anonymous + elsif admin? + Course::ADMIN + elsif business? + Course::BUSINESS + else + role = course&.course_members&.find_by(user_id: id, is_active: 1)&.role + case role + when nil then Course::NORMAL + when 'CREATOR' then Course::CREATOR + when 'PROFESSOR' then Course::PROFESSOR + when 'STUDENT' then Course::STUDENT + when 'ASSISTANT_PROFESSOR' then Course::ASSISTANT_PROFESSOR + end + end + end + + # 实训用户身份 + def shixun_identity(shixun) + @identity = + if admin? + User::EDU_ADMIN + elsif business? + User::EDU_BUSINESS + elsif creator_of_shixun?(shixun) + User::EDU_SHIXUN_MANAGER + elsif member_of_shixun?(shixun) + User::EDU_SHIXUN_MEMBER + elsif is_certification_teacher + User::EDU_CERTIFICATION_TEACHER + elsif is_teacher? + User::EDU_TEACHER + else + User::EDU_NORMAL + end + return @identity + end + + # tpi的用户身份 + def game_identity(game) + shixun = game.myshixun.shixun + @identity = + if admin? + User::EDU_ADMIN + elsif business? + User::EDU_BUSINESS + elsif creator_of_shixun?(shixun) + User::EDU_SHIXUN_MANAGER + elsif member_of_shixun?(shixun) + User::EDU_SHIXUN_MEMBER + elsif is_certification_teacher + User::EDU_CERTIFICATION_TEACHER + elsif creator_of_game?(game) + User::EDU_GAME_MANAGER + elsif is_teacher? + User::EDU_TEACHER + else + User::EDU_NORMAL + end + return @identity + end + + # 我的实训 + def my_shixuns + shixun_ids = shixun_members.pluck(:shixun_id) + myshixuns.pluck(:shixun_id) + Shixun.where(:id => shixun_ids).visible + end + + # 用户是否有权限查看实训 + # 1、实训删除只有管理员能看到 + # 2、实训隐藏了只有管理员、实训合作者能看到 + # 3、如果有限制学校范围,则学校的用户、管理员、实训合作者能看到 + def shixun_permission(shixun) + case shixun.status + when -1 # 软删除只有管理员能访问 + admin? + when 0, 1, 3 # 申请发布或者已关闭的实训,只有实训管理员可以访问 + manager_of_shixun?(shixun) + when 2 + if shixun.hidden + manager_of_shixun?(shixun) + else + shixun.use_scope == 0 || manager_of_shixun?(shixun) || shixun.shixun_schools.exists?(school_id: school_id) + end + end + end + + # 用户在平台名称的显示方式 + def full_name + return '游客' unless logged? + + name = show_realname? ? lastname + firstname : nickname + name.blank? ? (nickname.blank? ? login : nickname) : name + end + + # 用户的真实姓名(不考虑用户是否隐藏了真实姓名,课堂模块都用真实姓名) + def real_name + return '游客' unless logged? + name = lastname + firstname + name = name.blank? ? (nickname.blank? ? login : nickname) : name + name.gsub(/\s+/, '').strip #6.11 -hs + end + + def only_real_name + "#{lastname}#{firstname}" + end + + # 用户是否选题毕设课题 + def selected_topic?(topic) + student_graduation_topics.where(graduation_topic_id: topic.id).last.try(:status) + end + + def click_time + click_time = OnclickTime.find_by(user_id: id) || OnclickTime.create(user_id: id, onclick_time: created_on) + click_time.onclick_time + end + + def manager_of_memo?(memo) + id == memo.author_id || admin? || business? + end + + # 是否是项目管理者 + def manager_of_project?(project) + project.project_members.where(user_id: id).count > 0 + end + + def logged? + true + end + + def active? + status == STATUS_ACTIVE + end + + def locked? + status == STATUS_LOCKED + end + + def phone_binded? + phone.present? + end + + def self.current=(user) + Thread.current[:current_user] = user + end + + def self.current + Thread.current[:current_user] ||= User.anonymous + end + + def self.anonymous + anonymous_user = AnonymousUser.unscoped.take + if anonymous_user.nil? + anonymous_user = AnonymousUser.unscoped.create(lastname: 'Anonymous', firstname: '', login: '', + mail: '358551897@qq.com', phone: '13333333333', status: 0) + raise "Unable to create the anonymous user: error_info:#{anonymous_user.errors.messages}" if anonymous_user.new_record? + end + anonymous_user + end + + # Returns the user who matches the given autologin +key+ or nil + def self.try_to_autologin(key) + user = Token.find_active_user('autologin', key) + user.update(last_login_on: Time.now) if user + user + end + + def self.hash_password(clear_password) + Digest::SHA1.hexdigest(clear_password || "") + end + + def check_password?(clear_password) + # Preventing Timing Attack + ActiveSupport::SecurityUtils.secure_compare( + User.hash_password("#{salt}#{User.hash_password clear_password}"), + hashed_password + ) + end + + # 工程认证的学校 + def ec_school + school_id = self.ec_school_users.pluck(:school_id).first || + self.ec_major_schools.pluck(:school_id).first || + (self.ec_course_users.first && self.ec_course_users.first.try(:ec_course).try(:ec_year).try(:ec_major_school).try(:school_id)) + end + + # 登录,返回用户名与密码匹配的用户 + def self.try_to_login(login, password) + login = login.to_s.strip + password = password.to_s + + # Make sure no one can sign in with an empty login or password + return nil if login.empty? || password.empty? + if (login =~ VALID_EMAIL_REGEX) + user = find_by_mail(login) + elsif (login =~ VALID_PHONE_REGEX) + user = find_by_phone(login) + else + user = find_by_login(login) + end + + user + rescue => text + raise text + end + + def show_real_name + name = lastname + firstname + if name.blank? + nickname.blank? ? login : nickname + else + name + end + end + + def update_hashed_password + if password + salt_password(password) + end + end + + def salt_password(clear_password) + self.salt = User.generate_salt + self.hashed_password = User.hash_password("#{salt}#{User.hash_password clear_password}") + end + + def self.generate_salt + Educoder::Utils.random_hex(16) + end + + # 全部已认证 + def all_certified? + authentication? && professional_certification? + end + + # 是否绑定邮箱 + def email_binded? + mail.present? + end + + # 学院的url标识 + def college_identifier + Department.find_by_id(department_members.pluck(:department_id).first)&.identifier + end + + # 是否能申请试用 + def can_apply_trial? + return false if certification == 1 + + apply = ApplyAction.order(created_at: :desc).find_by(user_id: id, container_type: 'TrialAuthorization') + + apply.present? && !apply.status.zero? + end + + # 是否已经签到 + def attendance_signed? + attendance = Attendance.find_by(user_id: id) + + attendance.present? && Util.days_between(Time.zone.now, attendance.created_at).zero? + end + + # 明日签到金币 + def tomorrow_attendance_gold + Attendance.find_by(user_id: id)&.next_gold || 60 # 基础50,连续签到+10 + end + + def admin_or_business? + admin? || business? + end + + protected + def validate_password_length + # 管理员的初始密码是5位 + if password.present? && password.size < MIX_PASSWORD_LIMIT && !User.current.admin? + raise("密码长度不能低于#{MIX_PASSWORD_LIMIT}位") + end + end +end + + +class AnonymousUser < User + validate :validate_anonymous_uniqueness, :on => :create + + def validate_anonymous_uniqueness + # There should be only one AnonymousUser in the database + errors.add :base, 'An anonymous user already exists.' if AnonymousUser.exists? + end + + def available_custom_fields + [] + end + + # Overrides a few properties + def logged?; false end + def admin; false end + def name(*args); I18n.t(:label_user_anonymous) end + # def mail=(*args); nil end + # def mail; nil end + def time_zone; nil end + def rss_key; nil end + + + def membership(*args) + nil + end + + def member_of?(*args) + false + end + + # Anonymous user can not be destroyed + def destroy + false + end + + protected + + def instantiate_email_address + end + +end diff --git a/app/services/ecs/import_student_service.rb b/app/services/ecs/import_student_service.rb index 9014e221c..f5cd7c6ac 100644 --- a/app/services/ecs/import_student_service.rb +++ b/app/services/ecs/import_student_service.rb @@ -1,21 +1,20 @@ class Ecs::ImportStudentService < ApplicationService Error = Class.new(StandardError) - attr_reader :ec_year, :attachment + attr_reader :ec_year, :params - def initialize(ec_year, attachment_id) - @ec_year = ec_year - @attachment = Attachment.find_by(id: attachment_id) + def initialize(ec_year, params) + @ec_year = ec_year + @params = params end def call - raise Error, '文件不存在' if attachment.blank? + raise Error, '文件不存在' if params[:file].blank? || !params[:file].is_a?(ActionDispatch::Http::UploadedFile) - path = attachment.diskfile - excel = Ecs::ImportStudentExcel.new(path) + excel = Ecs::ImportStudentExcel.new(params[:file].path) success_count = 0 - EcYearStudent.bulk_insert(:student_id, :name, :created_at, :updated_at) do |worker| + EcYearStudent.bulk_insert(:ec_year_id, :student_id, :name, :created_at, :updated_at) do |worker| excel.read_each do |student_id, name| success_count += 1 @@ -25,7 +24,7 @@ class Ecs::ImportStudentService < ApplicationService next end - worker.add(student_id: student_id, name: name) + worker.add(ec_year_id: ec_year.id, student_id: student_id, name: name) end end diff --git a/app/services/ecs/save_graduation_course_supports_service.rb b/app/services/ecs/save_graduation_course_supports_service.rb index bfbdb997f..de4ecc71a 100644 --- a/app/services/ecs/save_graduation_course_supports_service.rb +++ b/app/services/ecs/save_graduation_course_supports_service.rb @@ -9,6 +9,8 @@ class Ecs::SaveGraduationCourseSupportsService < ApplicationService end def call + set_course_supports_position! + Ecs::SaveGraduationCourseSupportForm.new(params).validate! accepts_attributes = build_accepts_nested_attributes( @@ -20,4 +22,10 @@ class Ecs::SaveGraduationCourseSupportsService < ApplicationService graduation_subitem.save! graduation_subitem end + + def set_course_supports_position! + params[:course_supports].each_with_index do |item, index| + item[:position] = index + 1 + end + end end \ No newline at end of file diff --git a/app/tasks/statistic_school_daily_report_task.rb b/app/tasks/statistic_school_daily_report_task.rb index 5cd3fda7c..794a4b573 100644 --- a/app/tasks/statistic_school_daily_report_task.rb +++ b/app/tasks/statistic_school_daily_report_task.rb @@ -27,8 +27,8 @@ class StatisticSchoolDailyReportTask # 新增实训评测数量 shixun_evaluate_count = EvaluateRecord.joins('LEFT JOIN homework_commons_shixuns hcs ON hcs.shixun_id = evaluate_records.shixun_id') .joins('LEFT JOIN homework_commons hc ON hcs.homework_common_id = hc.id AND hc.homework_type = 4') - .joins('LEFT JOIN members ON members.user_id = evaluate_records.user_id') - .joins('LEFT JOIN courses ON members.course_id = courses.id AND hc.course_id = courses.id') + .joins('LEFT JOIN course_members ON course_members.user_id = evaluate_records.user_id') + .joins('LEFT JOIN courses ON course_members.course_id = courses.id AND hc.course_id = courses.id') .where(courses: { school_id: school.id }) .where(created_at: yesterday).reorder(nil).count diff --git a/app/tasks/statistic_school_report_task.rb b/app/tasks/statistic_school_report_task.rb index a55eb7a42..a72c57830 100644 --- a/app/tasks/statistic_school_report_task.rb +++ b/app/tasks/statistic_school_report_task.rb @@ -2,10 +2,10 @@ class StatisticSchoolReportTask def call School.find_each do |school| evaluate_count = Game.joins(:challenge) - .joins('LEFT JOIN members ON members.user_id = games.user_id') + .joins('LEFT JOIN course_members ON course_members.user_id = games.user_id') .joins('LEFT JOIN homework_commons_shixuns hcs ON hcs.shixun_id = challenges.shixun_id') .joins('LEFT JOIN homework_commons hc ON hcs.homework_common_id = hc.id AND hc.homework_type = 4') - .joins('LEFT JOIN courses ON hc.course_id = courses.id AND members.course_id = courses.id') + .joins('LEFT JOIN courses ON hc.course_id = courses.id AND course_members.course_id = courses.id') .where(courses: { school_id: school.id }) .sum(:evaluate_count) diff --git a/app/views/admins/professional_authentications/shared/_list.html.erb b/app/views/admins/professional_authentications/shared/_list.html.erb index fd7685f98..10934a702 100644 --- a/app/views/admins/professional_authentications/shared/_list.html.erb +++ b/app/views/admins/professional_authentications/shared/_list.html.erb @@ -53,12 +53,12 @@ <td><span class="apply-status-<%= apply.status %>"><%= apply.status_text %></span></td> <% else %> <td class="action-container"> - <%= agree_link '同意', agree_admins_professional_authentication_path(apply, element: ".professional-authentication-#{apply.id}"), 'data-confirm': '确认审核通过?' %> + <%= agree_link '同意', agree_admins_professional_authentication_path(apply, element: ".professional-authentication-#{apply.id}"), 'data-confirm': '确认审核通过?', 'data-disable-with': "提交中..." %> <%= javascript_void_link('拒绝', class: 'action refuse-action', data: { toggle: 'modal', target: '.admin-common-refuse-modal', id: apply.id, url: refuse_admins_professional_authentication_path(apply, element: ".professional-authentication-#{apply.id}") - }) %> + }, 'data-disable-with': "拒绝中...") %> </td> <% end %> </tr> diff --git a/app/views/ecs/graduation_course_supports/show.xlsx.axlsx b/app/views/ecs/graduation_course_supports/show.xlsx.axlsx index e2c2599ec..ae81d931b 100644 --- a/app/views/ecs/graduation_course_supports/show.xlsx.axlsx +++ b/app/views/ecs/graduation_course_supports/show.xlsx.axlsx @@ -9,13 +9,13 @@ wb = xlsx_package.workbook wb.styles do |style| title_style = style.add_style(sz: 16, height: 20, b: true) ec_year_style = style.add_style(sz: 10, height: 14) - label_style = style.add_style(sz: 11, b: true, bg_color: '90EE90', alignment: { horizontal: :center }, border: { style: :thin, color: '000000' }) + label_style = style.add_style(sz: 11, b: true, bg_color: '90EE90', alignment: { horizontal: :center, vertical: :center }, border: { style: :thin, color: '000000' }) content_style = style.add_style(sz: 11, height: 16, border: { style: :thin, color: '000000' }) - tip_style = style.add_style(sz: 11, height: 16, color: 'FFA07A') + tip_style = style.add_style(sz: 11, height: 16, color: Axlsx::Color.new(rgb: 'FFFFA07A')) wb.add_worksheet(:name => '课程体系对毕业要求的支撑') do |sheet| sheet.add_row ['课程体系VS毕业要求'], style: title_style - sheet.merge_cells wb.rows.first.cells[(1..(3 + max_support_length - 1))] + sheet.merge_cells sheet.rows.first.cells[(1..(3 + max_support_length - 1))] sheet.add_row [] @@ -25,8 +25,8 @@ wb.styles do |style| sheet.add_row ['注:有对应关系的课程名称下方为其权重系数,一个指标点的权重系数之和必须等于1'], style: tip_style sheet.add_row ['注:“★” 表示关联度高'] - sheet.merge_cells wb.rows[5].cells[(1..(3 + max_support_length - 1))] - sheet.merge_cells wb.rows[6].cells[(1..(3 + max_support_length - 1))] + sheet.merge_cells sheet.rows[5].cells[(1..(3 + max_support_length - 1))] + sheet.merge_cells sheet.rows[6].cells[(1..(3 + max_support_length - 1))] sheet.add_row [] @@ -34,9 +34,9 @@ wb.styles do |style| data[last_column_index] = '课程数量' sheet.add_row data, style: label_style course_columns = max_support_length.times.map { |i| "课程#{i + 1}" } - sheet.add_row %w('一级 二级') + course_columns + ['∑目标值'], style: label_style + sheet.add_row %w(一级 二级) + course_columns + ['∑目标值'], style: label_style sheet.merge_cells("A9:B9") - sheet.merge_cells wb.rows[8].cells[(3..(3 + max_support_length - 1))] + # sheet.merge_cells sheet.rows[8].cells[(3..(3 + max_support_length - 1))] current_row = 11 graduation_subitems.group_by(&:ec_graduation_requirement).each do |requirement, items| @@ -61,11 +61,11 @@ wb.styles do |style| sheet.add_row course_data, style: styles sheet.add_row weight_data, style: styles - sheet.merge_cells("B#{current_row - 1}:B#{current_row}") + sheet.merge_cells("B#{current_row}:B#{current_row + 1}") current_row += 2 end - sheet.merge_cells("A#{start_row - 1}:B#{current_row - 1}") + sheet.merge_cells("A#{start_row}:A#{current_row - 1}") end end end \ No newline at end of file diff --git a/app/views/student_works/show.json.jbuilder b/app/views/student_works/show.json.jbuilder index 192e4d8ec..9bafbe93e 100644 --- a/app/views/student_works/show.json.jbuilder +++ b/app/views/student_works/show.json.jbuilder @@ -11,7 +11,7 @@ json.update_user_name @is_evaluation ? "匿名" : @work.update_user.try(:real_na json.update_atta @homework.late_duration && @is_author json.attachments @attachments do |atta| - json.partial! "attachments/attachment_simple", locals: {attachment: atta, delete: @work.delete_atta(atta)} + json.partial! "attachments/attachment_simple", locals: {attachment: atta, delete: false} end unless @is_evaluation diff --git a/db/migrate/20190920073337_migrate_user_extension_index.rb b/db/migrate/20190920073337_migrate_user_extension_index.rb new file mode 100644 index 000000000..1d333bd99 --- /dev/null +++ b/db/migrate/20190920073337_migrate_user_extension_index.rb @@ -0,0 +1,6 @@ +class MigrateUserExtensionIndex < ActiveRecord::Migration[5.2] + def change + remove_index :user_extensions, :school_id + add_index :user_extensions, [:school_id, :user_id] + end +end diff --git a/public/editormd/lib/marked.min.js b/public/editormd/lib/marked.min.js index 6f14c6e7c..1cd7c2bae 100644 --- a/public/editormd/lib/marked.min.js +++ b/public/editormd/lib/marked.min.js @@ -12,5 +12,7 @@ */ // 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");*/ -!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*|<![A-Z][\\s\\S]*?>\\n*|<!\\[CDATA\\[[\\s\\S]*?\\]\\]>\\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=/<!--(?!-?>)[\s\S]*?-->/,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*$)|<tag(?:\"[^\"]*\"|'[^']*'|\\s[^'\"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))").replace("comment",t._comment).replace(/tag/g,"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),def:/^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/}),n.rules=t,n.lex=function(e,t){return new n(t).lex(e)},n.prototype.lex=function(e){return e=e.replace(/\r\n|\r/g,"\n").replace(/\t/g," ").replace(/\u00a0/g," ").replace(/\u2424/g,"\n"),this.token(e,!0)},n.prototype.token=function(e,n){var r,s,i,l,o,a,h,p,u,c,g,d,f;for(e=e.replace(/^ +$/gm,"");e;)if((i=this.rules.newline.exec(e))&&(e=e.substring(i[0].length),i[0].length>1&&this.tokens.push({type:"space"})),i=this.rules.code.exec(e))e=e.substring(i[0].length),i=i[0].replace(/^ {4}/gm,""),this.tokens.push({type:"code",text:this.options.pedantic?i:i.replace(/\n+$/,"")});else if(i=this.rules.fences.exec(e))e=e.substring(i[0].length),this.tokens.push({type:"code",lang:i[2],text:i[3]||""});else if(i=this.rules.heading.exec(e))e=e.substring(i[0].length),this.tokens.push({type:"heading",depth:i[1].length,text:i[2]});else if(n&&(i=this.rules.nptable.exec(e))&&(a={type:"table",header:b(i[1].replace(/^ *| *\| *$/g,"")),align:i[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:i[3]?i[3].replace(/\n$/,"").split("\n"):[]}).header.length===a.align.length){for(e=e.substring(i[0].length),p=0;p<a.align.length;p++)/^ *-+: *$/.test(a.align[p])?a.align[p]="right":/^ *:-+: *$/.test(a.align[p])?a.align[p]="center":/^ *:-+ *$/.test(a.align[p])?a.align[p]="left":a.align[p]=null;for(p=0;p<a.cells.length;p++)a.cells[p]=b(a.cells[p],a.header.length);this.tokens.push(a)}else if(i=this.rules.hr.exec(e))e=e.substring(i[0].length),this.tokens.push({type:"hr"});else if(i=this.rules.blockquote.exec(e))e=e.substring(i[0].length),this.tokens.push({type:"blockquote_start"}),i=i[0].replace(/^ *> ?/gm,""),this.token(i,n),this.tokens.push({type:"blockquote_end"});else if(i=this.rules.list.exec(e)){for(e=e.substring(i[0].length),g=(l=i[2]).length>1,this.tokens.push({type:"list_start",ordered:g,start:g?+l:""}),r=!1,c=(i=i[0].match(this.rules.item)).length,p=0;p<c;p++)h=(a=i[p]).length,~(a=a.replace(/^ *([*+-]|\d+\.) +/,"")).indexOf("\n ")&&(h-=a.length,a=this.options.pedantic?a.replace(/^ {1,4}/gm,""):a.replace(new RegExp("^ {1,"+h+"}","gm"),"")),this.options.smartLists&&p!==c-1&&(l===(o=t.bullet.exec(i[p+1])[0])||l.length>1&&o.length>1||(e=i.slice(p+1).join("\n")+e,p=c-1)),s=r||/\n\n(?!\s*$)/.test(a),p!==c-1&&(r="\n"===a.charAt(a.length-1),s||(s=r)),f=void 0,(d=/^\[[ xX]\] /.test(a))&&(f=" "!==a[1],a=a.replace(/^\[[ xX]\] +/,"")),this.tokens.push({type:s?"loose_item_start":"list_item_start",task:d,checked:f}),this.token(a,!1),this.tokens.push({type:"list_item_end"});this.tokens.push({type:"list_end"})}else if(i=this.rules.html.exec(e))e=e.substring(i[0].length),this.tokens.push({type:this.options.sanitize?"paragraph":"html",pre:!this.options.sanitizer&&("pre"===i[1]||"script"===i[1]||"style"===i[1]),text:i[0]});else if(n&&(i=this.rules.def.exec(e)))e=e.substring(i[0].length),i[3]&&(i[3]=i[3].substring(1,i[3].length-1)),u=i[1].toLowerCase().replace(/\s+/g," "),this.tokens.links[u]||(this.tokens.links[u]={href:i[2],title:i[3]});else if(n&&(i=this.rules.table.exec(e))&&(a={type:"table",header:b(i[1].replace(/^ *| *\| *$/g,"")),align:i[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:i[3]?i[3].replace(/(?: *\| *)?\n$/,"").split("\n"):[]}).header.length===a.align.length){for(e=e.substring(i[0].length),p=0;p<a.align.length;p++)/^ *-+: *$/.test(a.align[p])?a.align[p]="right":/^ *:-+: *$/.test(a.align[p])?a.align[p]="center":/^ *:-+ *$/.test(a.align[p])?a.align[p]="left":a.align[p]=null;for(p=0;p<a.cells.length;p++)a.cells[p]=b(a.cells[p].replace(/^ *\| *| *\| *$/g,""),a.header.length);this.tokens.push(a)}else if(i=this.rules.lheading.exec(e))e=e.substring(i[0].length),this.tokens.push({type:"heading",depth:"="===i[2]?1:2,text:i[1]});else if(n&&(i=this.rules.paragraph.exec(e)))e=e.substring(i[0].length),this.tokens.push({type:"paragraph",text:"\n"===i[1].charAt(i[1].length-1)?i[1].slice(0,-1):i[1]});else if(i=this.rules.text.exec(e))e=e.substring(i[0].length),this.tokens.push({type:"text",text:i[0]});else if(e)throw new Error("Infinite loop on byte: "+e.charCodeAt(0));return this.tokens};var r={escape:/^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,autolink:/^<(scheme:[^\s\x00-\x1f<>]*|email)>/,url:d,tag:"^comment|^</[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>",link:/^!?\[(label)\]\(href(?:\s+(title))?\s*\)/,reflink:/^!?\[(label)\]\[(?!\s*\])((?:\\[\[\]]?|[^\[\]\\])+)\]/,nolink:/^!?\[(?!\s*\])((?:\[[^\[\]]*\]|\\[\[\]]|[^\[\]])*)\](?:\[\])?/,strong:/^__([^\s][\s\S]*?[^\s])__(?!_)|^\*\*([^\s][\s\S]*?[^\s])\*\*(?!\*)|^__([^\s])__(?!_)|^\*\*([^\s])\*\*(?!\*)/,em:/^_([^\s][\s\S]*?[^\s_])_(?!_)|^_([^\s_][\s\S]*?[^\s])_(?!_)|^\*([^\s][\s\S]*?[^\s*])\*(?!\*)|^\*([^\s*][\s\S]*?[^\s])\*(?!\*)|^_([^\s_])_(?!_)|^\*([^\s*])\*(?!\*)/,code:/^(`+)\s*([\s\S]*?[^`]?)\s*\1(?!`)/,br:/^ {2,}\n(?!\s*$)/,del:d,text:/^[\s\S]+?(?=[\\<!\[`*]|\b_| {2,}\n|$)/};function s(e,t){if(this.options=t||m.defaults,this.links=e,this.rules=r.normal,this.renderer=this.options.renderer||new i,this.renderer.options=this.options,!this.links)throw new Error("Tokens array requires a `links` property.");this.options.pedantic?this.rules=r.pedantic:this.options.gfm&&(this.options.breaks?this.rules=r.breaks:this.rules=r.gfm)}function i(e){this.options=e||m.defaults}function l(){}function o(e){this.tokens=[],this.token=null,this.options=e||m.defaults,this.options.renderer=this.options.renderer||new i,this.renderer=this.options.renderer,this.renderer.options=this.options}function a(e,t){return e.replace(t?/&/g:/&(?!#?\w+;)/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function h(e){return e.replace(/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/gi,function(e,t){return"colon"===(t=t.toLowerCase())?":":"#"===t.charAt(0)?"x"===t.charAt(1)?String.fromCharCode(parseInt(t.substring(2),16)):String.fromCharCode(+t.substring(1)):""})}function p(e,t){return e=e.source||e,t=t||"",{replace:function(t,n){return n=(n=n.source||n).replace(/(^|[^\[])\^/g,"$1"),e=e.replace(t,n),this},getRegex:function(){return new RegExp(e,t)}}}function u(e,t){return c[" "+e]||(/^[^:]+:\/*[^/]*$/.test(e)?c[" "+e]=e+"/":c[" "+e]=e.replace(/[^/]*$/,"")),e=c[" "+e],"//"===t.slice(0,2)?e.replace(/:[\s\S]*/,":")+t:"/"===t.charAt(0)?e.replace(/(:\/*[^/]*)[\s\S]*/,"$1")+t:e+t}r._escapes=/\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g,r._scheme=/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/,r._email=/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/,r.autolink=p(r.autolink).replace("scheme",r._scheme).replace("email",r._email).getRegex(),r._attribute=/\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/,r.tag=p(r.tag).replace("comment",t._comment).replace("attribute",r._attribute).getRegex(),r._label=/(?:\[[^\[\]]*\]|\\[\[\]]?|`[^`]*`|[^\[\]\\])*?/,r._href=/\s*(<(?:\\[<>]?|[^\s<>\\])*>|(?:\\[()]?|\([^\s\x00-\x1f()\\]*\)|[^\s\x00-\x1f()\\])*?)/,r._title=/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/,r.link=p(r.link).replace("label",r._label).replace("href",r._href).replace("title",r._title).getRegex(),r.reflink=p(r.reflink).replace("label",r._label).getRegex(),r.normal=f({},r),r.pedantic=f({},r.normal,{strong:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,em:/^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/,link:p(/^!?\[(label)\]\((.*?)\)/).replace("label",r._label).getRegex(),reflink:p(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label",r._label).getRegex()}),r.gfm=f({},r.normal,{escape:p(r.escape).replace("])","~|])").getRegex(),url:p(/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/).replace("email",r._email).getRegex(),_backpedal:/(?:[^?!.,:;*_~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_~)]+(?!$))+/,del:/^~~(?=\S)([\s\S]*?\S)~~/,text:p(r.text).replace("]|","~]|").replace("|","|https?://|ftp://|www\\.|[a-zA-Z0-9.!#$%&'*+/=?^_`{\\|}~-]+@|").getRegex()}),r.breaks=f({},r.gfm,{br:p(r.br).replace("{2,}","*").getRegex(),text:p(r.gfm.text).replace("{2,}","*").getRegex()}),s.rules=r,s.output=function(e,t,n){return new s(t,n).output(e)},s.prototype.output=function(e){for(var t,n,r,i,l,o="";e;)if(l=this.rules.escape.exec(e))e=e.substring(l[0].length),o+=l[1];else if(l=this.rules.autolink.exec(e))e=e.substring(l[0].length),r="@"===l[2]?"mailto:"+(n=a(this.mangle(l[1]))):n=a(l[1]),o+=this.renderer.link(r,null,n);else if(this.inLink||!(l=this.rules.url.exec(e))){if(l=this.rules.tag.exec(e))!this.inLink&&/^<a /i.test(l[0])?this.inLink=!0:this.inLink&&/^<\/a>/i.test(l[0])&&(this.inLink=!1),e=e.substring(l[0].length),o+=this.options.sanitize?this.options.sanitizer?this.options.sanitizer(l[0]):a(l[0]):l[0];else if(l=this.rules.link.exec(e))e=e.substring(l[0].length),this.inLink=!0,r=l[2],this.options.pedantic?(t=/^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(r))?(r=t[1],i=t[3]):i="":i=l[3]?l[3].slice(1,-1):"",r=r.trim().replace(/^<([\s\S]*)>$/,"$1"),o+=this.outputLink(l,{href:s.escapes(r),title:s.escapes(i)}),this.inLink=!1;else if((l=this.rules.reflink.exec(e))||(l=this.rules.nolink.exec(e))){if(e=e.substring(l[0].length),t=(l[2]||l[1]).replace(/\s+/g," "),!(t=this.links[t.toLowerCase()])||!t.href){o+=l[0].charAt(0),e=l[0].substring(1)+e;continue}this.inLink=!0,o+=this.outputLink(l,t),this.inLink=!1}else if(l=this.rules.strong.exec(e))e=e.substring(l[0].length),o+=this.renderer.strong(this.output(l[4]||l[3]||l[2]||l[1]));else if(l=this.rules.em.exec(e))e=e.substring(l[0].length),o+=this.renderer.em(this.output(l[6]||l[5]||l[4]||l[3]||l[2]||l[1]));else if(l=this.rules.code.exec(e))e=e.substring(l[0].length),o+=this.renderer.codespan(a(l[2].trim(),!0));else if(l=this.rules.br.exec(e))e=e.substring(l[0].length),o+=this.renderer.br();else if(l=this.rules.del.exec(e))e=e.substring(l[0].length),o+=this.renderer.del(this.output(l[1]));else if(l=this.rules.text.exec(e))e=e.substring(l[0].length),o+=this.renderer.text(a(this.smartypants(l[0])));else if(e)throw new Error("Infinite loop on byte: "+e.charCodeAt(0))}else l[0]=this.rules._backpedal.exec(l[0])[0],e=e.substring(l[0].length),"@"===l[2]?r="mailto:"+(n=a(l[0])):(n=a(l[0]),r="www."===l[1]?"http://"+n:n),o+=this.renderer.link(r,null,n);return o},s.escapes=function(e){return e?e.replace(s.rules._escapes,"$1"):e},s.prototype.outputLink=function(e,t){var n=t.href,r=t.title?a(t.title):null;return"!"!==e[0].charAt(0)?this.renderer.link(n,r,this.output(e[1])):this.renderer.image(n,r,a(e[1]))},s.prototype.smartypants=function(e){return this.options.smartypants?e.replace(/---/g,"—").replace(/--/g,"–").replace(/(^|[-\u2014/(\[{"\s])'/g,"$1‘").replace(/'/g,"’").replace(/(^|[-\u2014/(\[{\u2018\s])"/g,"$1“").replace(/"/g,"”").replace(/\.{3}/g,"…"):e},s.prototype.mangle=function(e){if(!this.options.mangle)return e;for(var t,n="",r=e.length,s=0;s<r;s++)t=e.charCodeAt(s),Math.random()>.5&&(t="x"+t.toString(16)),n+="&#"+t+";";return n},i.prototype.code=function(e,t,n){if(this.options.highlight){var r=this.options.highlight(e,t);null!=r&&r!==e&&(n=!0,e=r)}return t?'<pre><code class="'+this.options.langPrefix+a(t,!0)+'">'+(n?e:a(e,!0))+"</code></pre>\n":"<pre><code>"+(n?e:a(e,!0))+"</code></pre>"},i.prototype.blockquote=function(e){return"<blockquote>\n"+e+"</blockquote>\n"},i.prototype.html=function(e){return e},i.prototype.heading=function(e,t,n){return this.options.headerIds?"<h"+t+' id="'+this.options.headerPrefix+n.toLowerCase().replace(/[^\w]+/g,"-")+'">'+e+"</h"+t+">\n":"<h"+t+">"+e+"</h"+t+">\n"},i.prototype.hr=function(){return this.options.xhtml?"<hr/>\n":"<hr>\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"<li>"+e+"</li>\n"},i.prototype.checkbox=function(e){return"<input "+(e?'checked="" ':"")+'disabled="" type="checkbox"'+(this.options.xhtml?" /":"")+"> "},i.prototype.paragraph=function(e){return"<p>"+e+"</p>\n"},i.prototype.table=function(e,t){return t&&(t="<tbody>"+t+"</tbody>"),"<table>\n<thead>\n"+e+"</thead>\n"+t+"</table>\n"},i.prototype.tablerow=function(e){return"<tr>\n"+e+"</tr>\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"<strong>"+e+"</strong>"},i.prototype.em=function(e){return"<em>"+e+"</em>"},i.prototype.codespan=function(e){return"<code>"+e+"</code>"},i.prototype.br=function(){return this.options.xhtml?"<br/>":"<br>"},i.prototype.del=function(e){return"<del>"+e+"</del>"},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='<a href="'+a(e)+'"';return t&&(s+=' title="'+t+'"'),s+=">"+n+"</a>"},i.prototype.image=function(e,t,n){this.options.baseUrl&&!g.test(e)&&(e=u(this.options.baseUrl,e));var r='<img src="'+e+'" alt="'+n+'"';return t&&(r+=' title="'+t+'"'),r+=this.options.xhtml?"/>":">"},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<this.token.header.length;e++)n+=this.renderer.tablecell(this.inline.output(this.token.header[e]),{header:!0,align:this.token.align[e]});for(s+=this.renderer.tablerow(n),e=0;e<this.token.cells.length;e++){for(t=this.token.cells[e],n="",r=0;r<t.length;r++)n+=this.renderer.tablecell(this.inline.output(t[r]),{header:!1,align:this.token.align[r]});i+=this.renderer.tablerow(n)}return this.renderer.table(s,i);case"blockquote_start":for(i="";"blockquote_end"!==this.next().type;)i+=this.tok();return this.renderer.blockquote(i);case"list_start":i="";for(var l=this.token.ordered,o=this.token.start;"list_end"!==this.next().type;)i+=this.tok();return this.renderer.list(i,l,o);case"list_item_start":for(i="",this.token.task&&(i+=this.renderer.checkbox(this.token.checked));"list_item_end"!==this.next().type;)i+="text"===this.token.type?this.parseText():this.tok();return this.renderer.listitem(i);case"loose_item_start":for(i="";"list_item_end"!==this.next().type;)i+=this.tok();return this.renderer.listitem(i);case"html":return this.renderer.html(this.token.text);case"paragraph":return this.renderer.paragraph(this.inline.output(this.token.text));case"text":return this.renderer.paragraph(this.parseText())}};var c={},g=/^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;function d(){}function f(e){for(var t,n,r=1;r<arguments.length;r++)for(n in t=arguments[r])Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n]);return e}function b(e,t){var n=e.replace(/([^\\])\|/g,"$1 |").split(/ +\| */),r=0;if(n.length>t)n.splice(t);else for(;n.length<t;)n.push("");for(;r<n.length;r++)n[r]=n[r].replace(/\\\|/g,"|");return n}function m(e,t,r){if(null==e)throw new Error("marked(): input parameter is undefined or null");/*if("string"!=typeof e)throw new Error("marked(): input parameter is of type "+Object.prototype.toString.call(e)+", string expected");*/if(r||"function"==typeof t){r||(r=t,t=null);var s,i,l=(t=f({},m.defaults,t||{})).highlight,h=0;try{s=n.lex(e,t)}catch(e){return r(e)}i=s.length;var p=function(e){if(e)return t.highlight=l,r(e);var n;try{n=o.parse(s,t)}catch(t){e=t}return t.highlight=l,e?r(e):r(null,n)};if(!l||l.length<3)return p();if(delete t.highlight,!i)return p();for(;h<s.length;h++)!function(e){"code"!==e.type?--i||p():l(e.text,e.lang,function(t,n){return t?p(t):null==n||n===e.text?--i||p():(e.text=n,e.escaped=!0,void(--i||p()))})}(s[h])}else try{return t&&(t=f({},m.defaults,t)),o.parse(n.lex(e,t),t)}catch(e){if(e.message+="\nPlease report this to https://github.com/markedjs/marked.",(t||m.defaults).silent)return"<p>An error occurred:</p><pre>"+a(e.message+"",!0)+"</pre>";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)); +// 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*|<![A-Z][\\s\\S]*?>\\n*|<!\\[CDATA\\[[\\s\\S]*?\\]\\]>\\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=/<!--(?!-?>)[\s\S]*?-->/,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*$)|<tag(?:\"[^\"]*\"|'[^']*'|\\s[^'\"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))").replace("comment",t._comment).replace(/tag/g,"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),def:/^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/}),n.rules=t,n.lex=function(e,t){return new n(t).lex(e)},n.prototype.lex=function(e){return e=e.replace(/\r\n|\r/g,"\n").replace(/\t/g," ").replace(/\u00a0/g," ").replace(/\u2424/g,"\n"),this.token(e,!0)},n.prototype.token=function(e,n){var r,s,i,l,o,a,h,p,u,c,g,d,f;for(e=e.replace(/^ +$/gm,"");e;)if((i=this.rules.newline.exec(e))&&(e=e.substring(i[0].length),i[0].length>1&&this.tokens.push({type:"space"})),i=this.rules.code.exec(e))e=e.substring(i[0].length),i=i[0].replace(/^ {4}/gm,""),this.tokens.push({type:"code",text:this.options.pedantic?i:i.replace(/\n+$/,"")});else if(i=this.rules.fences.exec(e))e=e.substring(i[0].length),this.tokens.push({type:"code",lang:i[2],text:i[3]||""});else if(i=this.rules.heading.exec(e))e=e.substring(i[0].length),this.tokens.push({type:"heading",depth:i[1].length,text:i[2]});else if(n&&(i=this.rules.nptable.exec(e))&&(a={type:"table",header:i[1].replace(/^ *| *\| *$/g, "").split(/ *\| */),align:i[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:i[3]?i[3].replace(/\n$/,"").split("\n"):[]}).header.length){for(e=e.substring(i[0].length),p=0;p<a.align.length;p++)/^ *-+: *$/.test(a.align[p])?a.align[p]="right":/^ *:-+: *$/.test(a.align[p])?a.align[p]="center":/^ *:-+ *$/.test(a.align[p])?a.align[p]="left":a.align[p]=null;for(p=0;p<a.cells.length;p++)a.cells[p]=b(a.cells[p],a.cells[p].split('|').length - 2 );this.tokens.push(a)}else if(i=this.rules.hr.exec(e))e=e.substring(i[0].length),this.tokens.push({type:"hr"});else if(i=this.rules.blockquote.exec(e))e=e.substring(i[0].length),this.tokens.push({type:"blockquote_start"}),i=i[0].replace(/^ *> ?/gm,""),this.token(i,n),this.tokens.push({type:"blockquote_end"});else if(i=this.rules.list.exec(e)){for(e=e.substring(i[0].length),g=(l=i[2]).length>1,this.tokens.push({type:"list_start",ordered:g,start:g?+l:""}),r=!1,c=(i=i[0].match(this.rules.item)).length,p=0;p<c;p++)h=(a=i[p]).length,~(a=a.replace(/^ *([*+-]|\d+\.) +/,"")).indexOf("\n ")&&(h-=a.length,a=this.options.pedantic?a.replace(/^ {1,4}/gm,""):a.replace(new RegExp("^ {1,"+h+"}","gm"),"")),this.options.smartLists&&p!==c-1&&(l===(o=t.bullet.exec(i[p+1])[0])||l.length>1&&o.length>1||(e=i.slice(p+1).join("\n")+e,p=c-1)),s=r||/\n\n(?!\s*$)/.test(a),p!==c-1&&(r="\n"===a.charAt(a.length-1),s||(s=r)),f=void 0,(d=/^\[[ xX]\] /.test(a))&&(f=" "!==a[1],a=a.replace(/^\[[ xX]\] +/,"")),this.tokens.push({type:s?"loose_item_start":"list_item_start",task:d,checked:f}),this.token(a,!1),this.tokens.push({type:"list_item_end"});this.tokens.push({type:"list_end"})}else if(i=this.rules.html.exec(e))e=e.substring(i[0].length),this.tokens.push({type:this.options.sanitize?"paragraph":"html",pre:!this.options.sanitizer&&("pre"===i[1]||"script"===i[1]||"style"===i[1]),text:i[0]});else if(n&&(i=this.rules.def.exec(e)))e=e.substring(i[0].length),i[3]&&(i[3]=i[3].substring(1,i[3].length-1)),u=i[1].toLowerCase().replace(/\s+/g," "),this.tokens.links[u]||(this.tokens.links[u]={href:i[2],title:i[3]});else if(n&&(i=this.rules.table.exec(e))&&(a={type:"table",header:i[1].replace(/^ *| *\| *$/g, "").split(/ *\| */),align:i[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:i[3]?i[3].replace(/(?: *\| *)?\n$/,"").split("\n"):[]}).header.length){for(e=e.substring(i[0].length),p=0;p<a.align.length;p++)/^ *-+: *$/.test(a.align[p])?a.align[p]="right":/^ *:-+: *$/.test(a.align[p])?a.align[p]="center":/^ *:-+ *$/.test(a.align[p])?a.align[p]="left":a.align[p]=null;for(p=0;p<a.cells.length;p++)a.cells[p]=b(a.cells[p].replace(/^ *\| *| *\| *$/g,""),a.cells[p].split('|').length - 2 );this.tokens.push(a)}else if(i=this.rules.lheading.exec(e))e=e.substring(i[0].length),this.tokens.push({type:"heading",depth:"="===i[2]?1:2,text:i[1]});else if(n&&(i=this.rules.paragraph.exec(e)))e=e.substring(i[0].length),this.tokens.push({type:"paragraph",text:"\n"===i[1].charAt(i[1].length-1)?i[1].slice(0,-1):i[1]});else if(i=this.rules.text.exec(e))e=e.substring(i[0].length),this.tokens.push({type:"text",text:i[0]});else if(e)throw new Error("Infinite loop on byte: "+e.charCodeAt(0));return this.tokens};var r={escape:/^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,autolink:/^<(scheme:[^\s\x00-\x1f<>]*|email)>/,url:d,tag:"^comment|^</[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>",link:/^!?\[(label)\]\(href(?:\s+(title))?\s*\)/,reflink:/^!?\[(label)\]\[(?!\s*\])((?:\\[\[\]]?|[^\[\]\\])+)\]/,nolink:/^!?\[(?!\s*\])((?:\[[^\[\]]*\]|\\[\[\]]|[^\[\]])*)\](?:\[\])?/,strong:/^__([^\s][\s\S]*?[^\s])__(?!_)|^\*\*([^\s][\s\S]*?[^\s])\*\*(?!\*)|^__([^\s])__(?!_)|^\*\*([^\s])\*\*(?!\*)/,em:/^_([^\s][\s\S]*?[^\s_])_(?!_)|^_([^\s_][\s\S]*?[^\s])_(?!_)|^\*([^\s][\s\S]*?[^\s*])\*(?!\*)|^\*([^\s*][\s\S]*?[^\s])\*(?!\*)|^_([^\s_])_(?!_)|^\*([^\s*])\*(?!\*)/,code:/^(`+)\s*([\s\S]*?[^`]?)\s*\1(?!`)/,br:/^ {2,}\n(?!\s*$)/,del:d,text:/^[\s\S]+?(?=[\\<!\[`*]|\b_| {2,}\n|$)/};function s(e,t){if(this.options=t||m.defaults,this.links=e,this.rules=r.normal,this.renderer=this.options.renderer||new i,this.renderer.options=this.options,!this.links)throw new Error("Tokens array requires a `links` property.");this.options.pedantic?this.rules=r.pedantic:this.options.gfm&&(this.options.breaks?this.rules=r.breaks:this.rules=r.gfm)}function i(e){this.options=e||m.defaults}function l(){}function o(e){this.tokens=[],this.token=null,this.options=e||m.defaults,this.options.renderer=this.options.renderer||new i,this.renderer=this.options.renderer,this.renderer.options=this.options}function a(e,t){return e.replace(t?/&/g:/&(?!#?\w+;)/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function h(e){return e.replace(/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/gi,function(e,t){return"colon"===(t=t.toLowerCase())?":":"#"===t.charAt(0)?"x"===t.charAt(1)?String.fromCharCode(parseInt(t.substring(2),16)):String.fromCharCode(+t.substring(1)):""})}function p(e,t){return e=e.source||e,t=t||"",{replace:function(t,n){return n=(n=n.source||n).replace(/(^|[^\[])\^/g,"$1"),e=e.replace(t,n),this},getRegex:function(){return new RegExp(e,t)}}}function u(e,t){return c[" "+e]||(/^[^:]+:\/*[^/]*$/.test(e)?c[" "+e]=e+"/":c[" "+e]=e.replace(/[^/]*$/,"")),e=c[" "+e],"//"===t.slice(0,2)?e.replace(/:[\s\S]*/,":")+t:"/"===t.charAt(0)?e.replace(/(:\/*[^/]*)[\s\S]*/,"$1")+t:e+t}r._escapes=/\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g,r._scheme=/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/,r._email=/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/,r.autolink=p(r.autolink).replace("scheme",r._scheme).replace("email",r._email).getRegex(),r._attribute=/\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/,r.tag=p(r.tag).replace("comment",t._comment).replace("attribute",r._attribute).getRegex(),r._label=/(?:\[[^\[\]]*\]|\\[\[\]]?|`[^`]*`|[^\[\]\\])*?/,r._href=/\s*(<(?:\\[<>]?|[^\s<>\\])*>|(?:\\[()]?|\([^\s\x00-\x1f()\\]*\)|[^\s\x00-\x1f()\\])*?)/,r._title=/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/,r.link=p(r.link).replace("label",r._label).replace("href",r._href).replace("title",r._title).getRegex(),r.reflink=p(r.reflink).replace("label",r._label).getRegex(),r.normal=f({},r),r.pedantic=f({},r.normal,{strong:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,em:/^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/,link:p(/^!?\[(label)\]\((.*?)\)/).replace("label",r._label).getRegex(),reflink:p(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label",r._label).getRegex()}),r.gfm=f({},r.normal,{escape:p(r.escape).replace("])","~|])").getRegex(),url:p(/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/).replace("email",r._email).getRegex(),_backpedal:/(?:[^?!.,:;*_~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_~)]+(?!$))+/,del:/^~~(?=\S)([\s\S]*?\S)~~/,text:p(r.text).replace("]|","~]|").replace("|","|https?://|ftp://|www\\.|[a-zA-Z0-9.!#$%&'*+/=?^_`{\\|}~-]+@|").getRegex()}),r.breaks=f({},r.gfm,{br:p(r.br).replace("{2,}","*").getRegex(),text:p(r.gfm.text).replace("{2,}","*").getRegex()}),s.rules=r,s.output=function(e,t,n){return new s(t,n).output(e)},s.prototype.output=function(e){for(var t,n,r,i,l,o="";e;)if(l=this.rules.escape.exec(e))e=e.substring(l[0].length),o+=l[1];else if(l=this.rules.autolink.exec(e))e=e.substring(l[0].length),r="@"===l[2]?"mailto:"+(n=a(this.mangle(l[1]))):n=a(l[1]),o+=this.renderer.link(r,null,n);else if(this.inLink||!(l=this.rules.url.exec(e))){if(l=this.rules.tag.exec(e))!this.inLink&&/^<a /i.test(l[0])?this.inLink=!0:this.inLink&&/^<\/a>/i.test(l[0])&&(this.inLink=!1),e=e.substring(l[0].length),o+=this.options.sanitize?this.options.sanitizer?this.options.sanitizer(l[0]):a(l[0]):l[0];else if(l=this.rules.link.exec(e))e=e.substring(l[0].length),this.inLink=!0,r=l[2],this.options.pedantic?(t=/^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(r))?(r=t[1],i=t[3]):i="":i=l[3]?l[3].slice(1,-1):"",r=r.trim().replace(/^<([\s\S]*)>$/,"$1"),o+=this.outputLink(l,{href:s.escapes(r),title:s.escapes(i)}),this.inLink=!1;else if((l=this.rules.reflink.exec(e))||(l=this.rules.nolink.exec(e))){if(e=e.substring(l[0].length),t=(l[2]||l[1]).replace(/\s+/g," "),!(t=this.links[t.toLowerCase()])||!t.href){o+=l[0].charAt(0),e=l[0].substring(1)+e;continue}this.inLink=!0,o+=this.outputLink(l,t),this.inLink=!1}else if(l=this.rules.strong.exec(e))e=e.substring(l[0].length),o+=this.renderer.strong(this.output(l[4]||l[3]||l[2]||l[1]));else if(l=this.rules.em.exec(e))e=e.substring(l[0].length),o+=this.renderer.em(this.output(l[6]||l[5]||l[4]||l[3]||l[2]||l[1]));else if(l=this.rules.code.exec(e))e=e.substring(l[0].length),o+=this.renderer.codespan(a(l[2].trim(),!0));else if(l=this.rules.br.exec(e))e=e.substring(l[0].length),o+=this.renderer.br();else if(l=this.rules.del.exec(e))e=e.substring(l[0].length),o+=this.renderer.del(this.output(l[1]));else if(l=this.rules.text.exec(e))e=e.substring(l[0].length),o+=this.renderer.text(a(this.smartypants(l[0])));else if(e)throw new Error("Infinite loop on byte: "+e.charCodeAt(0))}else l[0]=this.rules._backpedal.exec(l[0])[0],e=e.substring(l[0].length),"@"===l[2]?r="mailto:"+(n=a(l[0])):(n=a(l[0]),r="www."===l[1]?"http://"+n:n),o+=this.renderer.link(r,null,n);return o},s.escapes=function(e){return e?e.replace(s.rules._escapes,"$1"):e},s.prototype.outputLink=function(e,t){var n=t.href,r=t.title?a(t.title):null;return"!"!==e[0].charAt(0)?this.renderer.link(n,r,this.output(e[1])):this.renderer.image(n,r,a(e[1]))},s.prototype.smartypants=function(e){return this.options.smartypants?e.replace(/---/g,"—").replace(/--/g,"–").replace(/(^|[-\u2014/(\[{"\s])'/g,"$1‘").replace(/'/g,"’").replace(/(^|[-\u2014/(\[{\u2018\s])"/g,"$1“").replace(/"/g,"”").replace(/\.{3}/g,"…"):e},s.prototype.mangle=function(e){if(!this.options.mangle)return e;for(var t,n="",r=e.length,s=0;s<r;s++)t=e.charCodeAt(s),Math.random()>.5&&(t="x"+t.toString(16)),n+="&#"+t+";";return n},i.prototype.code=function(e,t,n){if(this.options.highlight){var r=this.options.highlight(e,t);null!=r&&r!==e&&(n=!0,e=r)}return t?'<pre><code class="'+this.options.langPrefix+a(t,!0)+'">'+(n?e:a(e,!0))+"</code></pre>\n":"<pre><code>"+(n?e:a(e,!0))+"</code></pre>"},i.prototype.blockquote=function(e){return"<blockquote>\n"+e+"</blockquote>\n"},i.prototype.html=function(e){return e},i.prototype.heading=function(e,t,n){return this.options.headerIds?"<h"+t+' id="'+this.options.headerPrefix+n.toLowerCase().replace(/[^\w]+/g,"-")+'">'+e+"</h"+t+">\n":"<h"+t+">"+e+"</h"+t+">\n"},i.prototype.hr=function(){return this.options.xhtml?"<hr/>\n":"<hr>\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"<li>"+e+"</li>\n"},i.prototype.checkbox=function(e){return"<input "+(e?'checked="" ':"")+'disabled="" type="checkbox"'+(this.options.xhtml?" /":"")+"> "},i.prototype.paragraph=function(e){return"<p>"+e+"</p>\n"},i.prototype.table=function(e,t){return t&&(t="<tbody>"+t+"</tbody>"),"<table>\n<thead>\n"+e+"</thead>\n"+t+"</table>\n"},i.prototype.tablerow=function(e){return"<tr>\n"+e+"</tr>\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"<strong>"+e+"</strong>"},i.prototype.em=function(e){return"<em>"+e+"</em>"},i.prototype.codespan=function(e){return"<code>"+e+"</code>"},i.prototype.br=function(){return this.options.xhtml?"<br/>":"<br>"},i.prototype.del=function(e){return"<del>"+e+"</del>"},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='<a href="'+a(e)+'"';return t&&(s+=' title="'+t+'"'),s+=">"+n+"</a>"},i.prototype.image=function(e,t,n){this.options.baseUrl&&!g.test(e)&&(e=u(this.options.baseUrl,e));var r='<img src="'+e+'" alt="'+n+'"';return t&&(r+=' title="'+t+'"'),r+=this.options.xhtml?"/>":">"},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<this.token.header.length;e++)n+=this.renderer.tablecell(this.inline.output(this.token.header[e]),{header:!0,align:this.token.align[e]});for(s+=this.renderer.tablerow(n),e=0;e<this.token.cells.length;e++){for(t=this.token.cells[e],n="",r=0;r<t.length;r++)n+=this.renderer.tablecell(this.inline.output(t[r]),{header:!1,align:this.token.align[r]});i+=this.renderer.tablerow(n)}return this.renderer.table(s,i);case"blockquote_start":for(i="";"blockquote_end"!==this.next().type;)i+=this.tok();return this.renderer.blockquote(i);case"list_start":i="";for(var l=this.token.ordered,o=this.token.start;"list_end"!==this.next().type;)i+=this.tok();return this.renderer.list(i,l,o);case"list_item_start":for(i="",this.token.task&&(i+=this.renderer.checkbox(this.token.checked));"list_item_end"!==this.next().type;)i+="text"===this.token.type?this.parseText():this.tok();return this.renderer.listitem(i);case"loose_item_start":for(i="";"list_item_end"!==this.next().type;)i+=this.tok();return this.renderer.listitem(i);case"html":return this.renderer.html(this.token.text);case"paragraph":return this.renderer.paragraph(this.inline.output(this.token.text));case"text":return this.renderer.paragraph(this.parseText())}};var c={},g=/^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;function d(){}function f(e){for(var t,n,r=1;r<arguments.length;r++)for(n in t=arguments[r])Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n]);return e}function b(e,t){var n=e.replace(/([^\\])\|/g,"$1 |").split(/ +\| */),r=0;if(n.length>t)n.splice(t);else for(;n.length<t;)n.push("");for(;r<n.length;r++)n[r]=n[r].replace(/\\\|/g,"|");return n}function m(e,t,r){if(null==e)throw new Error("marked(): input parameter is undefined or null");/*if("string"!=typeof e)throw new Error("marked(): input parameter is of type "+Object.prototype.toString.call(e)+", string expected");*/if(r||"function"==typeof t){r||(r=t,t=null);var s,i,l=(t=f({},m.defaults,t||{})).highlight,h=0;try{s=n.lex(e,t)}catch(e){return r(e)}i=s.length;var p=function(e){if(e)return t.highlight=l,r(e);var n;try{n=o.parse(s,t)}catch(t){e=t}return t.highlight=l,e?r(e):r(null,n)};if(!l||l.length<3)return p();if(delete t.highlight,!i)return p();for(;h<s.length;h++)!function(e){"code"!==e.type?--i||p():l(e.text,e.lang,function(t,n){return t?p(t):null==n||n===e.text?--i||p():(e.text=n,e.escaped=!0,void(--i||p()))})}(s[h])}else try{return t&&(t=f({},m.defaults,t)),o.parse(n.lex(e,t),t)}catch(e){if(e.message+="\nPlease report this to https://github.com/markedjs/marked.",(t||m.defaults).silent)return"<p>An error occurred:</p><pre>"+a(e.message+"",!0)+"</pre>";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/react/package-lock.json b/public/react/package-lock.json index 8f387e045..631da270e 100644 --- a/public/react/package-lock.json +++ b/public/react/package-lock.json @@ -4,20 +4,6 @@ "lockfileVersion": 1, "requires": true, "dependencies": { - "@ant-design/icons": { - "version": "1.2.1", - "resolved": "http://registry.npm.taobao.org/@ant-design/icons/download/@ant-design/icons-1.2.1.tgz", - "integrity": "sha1-jhkwGxQz7GfWu9DoknguKt5WH/k=" - }, - "@ant-design/icons-react": { - "version": "1.1.5", - "resolved": "http://registry.npm.taobao.org/@ant-design/icons-react/download/@ant-design/icons-react-1.1.5.tgz", - "integrity": "sha1-GwPajcztKku5gu97JcHSQBTDWmg=", - "requires": { - "ant-design-palettes": "^1.1.3", - "babel-runtime": "^6.26.0" - } - }, "@babel/helper-annotate-as-pure": { "version": "7.0.0", "resolved": "http://registry.npm.taobao.org/@babel/helper-annotate-as-pure/download/@babel/helper-annotate-as-pure-7.0.0.tgz", @@ -95,15 +81,10 @@ "resolved": "http://registry.npm.taobao.org/@emotion/unitless/download/@emotion/unitless-0.7.3.tgz", "integrity": "sha1-YxCgR/EtIaEDb7AxMXIZiSRAQW8=" }, - "@flatten/array": { - "version": "1.1.7", - "resolved": "https://registry.npm.taobao.org/@flatten/array/download/@flatten/array-1.1.7.tgz", - "integrity": "sha1-+UZZu/MtVY9pKmI0MEokcxKm+jg=" - }, "@icedesign/base": { - "version": "0.2.7", - "resolved": "http://registry.npm.taobao.org/@icedesign/base/download/@icedesign/base-0.2.7.tgz", - "integrity": "sha1-cFvLHH1UQVQKYuvsJRsGh56oN+U=", + "version": "0.2.8", + "resolved": "https://registry.npm.taobao.org/@icedesign/base/download/@icedesign/base-0.2.8.tgz", + "integrity": "sha1-hmlSY+17gnKJB3sbgoy446sqzAk=", "requires": { "async-validator": "^1.6.7", "classnames": "^2.2.3", @@ -147,14 +128,6 @@ "csstype": "^2.2.0" } }, - "@types/react-slick": { - "version": "0.23.3", - "resolved": "http://registry.npm.taobao.org/@types/react-slick/download/@types/react-slick-0.23.3.tgz", - "integrity": "sha1-ydFDI6dfVPRqZS+3Rf5VOq0JHOA=", - "requires": { - "@types/react": "*" - } - }, "@types/react-transition-group": { "version": "2.9.0", "resolved": "http://registry.npm.taobao.org/@types/react-transition-group/download/@types/react-transition-group-2.9.0.tgz?cache=0&other_urls=http%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freact-transition-group%2Fdownload%2F%40types%2Freact-transition-group-2.9.0.tgz", @@ -333,102 +306,6 @@ "color-convert": "^1.9.0" } }, - "ant-design-palettes": { - "version": "1.1.3", - "resolved": "http://registry.npm.taobao.org/ant-design-palettes/download/ant-design-palettes-1.1.3.tgz", - "integrity": "sha1-hBGbGk2GNjrcUqONWH5lM2oKJ90=", - "requires": { - "tinycolor2": "^1.4.1" - } - }, - "antd": { - "version": "3.16.2", - "resolved": "http://registry.npm.taobao.org/antd/download/antd-3.16.2.tgz", - "integrity": "sha1-o7SoRKbegubIfJb4jdojF/TYkHU=", - "requires": { - "@ant-design/icons": "~1.2.0", - "@ant-design/icons-react": "~1.1.2", - "@types/react-slick": "^0.23.3", - "array-tree-filter": "^2.1.0", - "babel-runtime": "6.x", - "classnames": "~2.2.6", - "copy-to-clipboard": "^3.0.8", - "create-react-class": "^15.6.3", - "create-react-context": "0.2.2", - "css-animation": "^1.5.0", - "dom-closest": "^0.2.0", - "enquire.js": "^2.1.6", - "lodash": "^4.17.11", - "moment": "^2.24.0", - "omit.js": "^1.0.0", - "prop-types": "^15.6.2", - "raf": "^3.4.0", - "rc-animate": "^2.5.4", - "rc-calendar": "~9.12.1", - "rc-cascader": "~0.17.0", - "rc-checkbox": "~2.1.5", - "rc-collapse": "~1.11.1", - "rc-dialog": "~7.3.0", - "rc-drawer": "~1.7.6", - "rc-dropdown": "~2.4.1", - "rc-editor-mention": "^1.1.7", - "rc-form": "^2.4.0", - "rc-input-number": "~4.4.0", - "rc-menu": "~7.4.12", - "rc-notification": "~3.3.0", - "rc-pagination": "~1.17.7", - "rc-progress": "~2.3.0", - "rc-rate": "~2.5.0", - "rc-select": "~9.0.0", - "rc-slider": "~8.6.5", - "rc-steps": "~3.3.0", - "rc-switch": "~1.9.0", - "rc-table": "~6.4.0", - "rc-tabs": "~9.6.0", - "rc-time-picker": "~3.6.1", - "rc-tooltip": "~3.7.3", - "rc-tree": "~1.15.2", - "rc-tree-select": "~2.6.0", - "rc-trigger": "^2.6.2", - "rc-upload": "~2.6.0", - "rc-util": "^4.5.1", - "react-lazy-load": "^3.0.13", - "react-lifecycles-compat": "^3.0.4", - "react-slick": "~0.23.2", - "resize-observer-polyfill": "^1.5.0", - "shallowequal": "^1.1.0", - "warning": "~4.0.2" - }, - "dependencies": { - "rc-select": { - "version": "9.0.2", - "resolved": "http://registry.npm.taobao.org/rc-select/download/rc-select-9.0.2.tgz", - "integrity": "sha1-zg0pfbX4pcfou8P8JNntW6ZIASw=", - "requires": { - "babel-runtime": "^6.23.0", - "classnames": "2.x", - "component-classes": "1.x", - "dom-scroll-into-view": "1.x", - "prop-types": "^15.5.8", - "raf": "^3.4.0", - "rc-animate": "2.x", - "rc-menu": "^7.3.0", - "rc-trigger": "^2.5.4", - "rc-util": "^4.0.4", - "react-lifecycles-compat": "^3.0.2", - "warning": "^4.0.2" - } - }, - "warning": { - "version": "4.0.3", - "resolved": "http://registry.npm.taobao.org/warning/download/warning-4.0.3.tgz", - "integrity": "sha1-Fungd+uKhtavfWSqHgX9hbRnjKM=", - "requires": { - "loose-envify": "^1.0.0" - } - } - } - }, "anymatch": { "version": "1.3.2", "resolved": "http://registry.npm.taobao.org/anymatch/download/anymatch-1.3.2.tgz", @@ -520,11 +397,6 @@ "resolved": "http://registry.npm.taobao.org/array-reduce/download/array-reduce-0.0.0.tgz", "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=" }, - "array-tree-filter": { - "version": "2.1.0", - "resolved": "http://registry.npm.taobao.org/array-tree-filter/download/array-tree-filter-2.1.0.tgz", - "integrity": "sha1-hzrAD+yDdJ8lWsjdCDgUtPYykZA=" - }, "array-union": { "version": "1.0.2", "resolved": "http://registry.npm.taobao.org/array-union/download/array-union-1.0.2.tgz", @@ -629,12 +501,9 @@ "dev": true }, "async-validator": { - "version": "1.11.0", - "resolved": "http://registry.npm.taobao.org/async-validator/download/async-validator-1.11.0.tgz", - "integrity": "sha1-9i/RS8yjNvzalubdU9vR3dP8MZg=", - "requires": { - "babel-runtime": "6.x" - } + "version": "1.12.2", + "resolved": "https://registry.npm.taobao.org/async-validator/download/async-validator-1.12.2.tgz", + "integrity": "sha1-vq5nHnF00pOLe0tp0vt+cit/1yw=" }, "asynckit": { "version": "0.4.0", @@ -2825,14 +2694,6 @@ "resolved": "http://registry.npm.taobao.org/copy-descriptor/download/copy-descriptor-0.1.1.tgz", "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" }, - "copy-to-clipboard": { - "version": "3.1.0", - "resolved": "http://registry.npm.taobao.org/copy-to-clipboard/download/copy-to-clipboard-3.1.0.tgz", - "integrity": "sha1-CigUGJnmvSF7ncE/0WibOziCC0Q=", - "requires": { - "toggle-selection": "^1.0.6" - } - }, "core-js": { "version": "2.6.5", "resolved": "http://registry.npm.taobao.org/core-js/download/core-js-2.6.5.tgz", @@ -2916,18 +2777,9 @@ "object-assign": "^4.1.1" } }, - "create-react-context": { - "version": "0.2.2", - "resolved": "http://registry.npm.taobao.org/create-react-context/download/create-react-context-0.2.2.tgz", - "integrity": "sha1-mDZUL5qqIoaM19Sm+CZn3zgBnco=", - "requires": { - "fbjs": "^0.8.0", - "gud": "^1.0.0" - } - }, "cropperjs": { "version": "0.7.2", - "resolved": "http://registry.npm.taobao.org/cropperjs/download/cropperjs-0.7.2.tgz", + "resolved": "https://registry.npm.taobao.org/cropperjs/download/cropperjs-0.7.2.tgz", "integrity": "sha1-atinHbAGKbqULZzt5lKyeXXp50o=" }, "cross-spawn": { @@ -3494,14 +3346,6 @@ "resolved": "http://registry.npm.taobao.org/dom-align/download/dom-align-1.8.2.tgz", "integrity": "sha1-/c02vOJbqNNP41gu/Vesdn30kL0=" }, - "dom-closest": { - "version": "0.2.0", - "resolved": "http://registry.npm.taobao.org/dom-closest/download/dom-closest-0.2.0.tgz", - "integrity": "sha1-69n5HRvyLo1vR3h2u80+yQIWwM8=", - "requires": { - "dom-matches": ">=1.0.1" - } - }, "dom-converter": { "version": "0.2.0", "resolved": "http://registry.npm.taobao.org/dom-converter/download/dom-converter-0.2.0.tgz", @@ -3533,11 +3377,6 @@ } } }, - "dom-matches": { - "version": "2.0.0", - "resolved": "http://registry.npm.taobao.org/dom-matches/download/dom-matches-2.0.0.tgz", - "integrity": "sha1-0nKLQWqHUzmA6wibhI0lPPI6dYw=" - }, "dom-scroll-into-view": { "version": "1.2.1", "resolved": "http://registry.npm.taobao.org/dom-scroll-into-view/download/dom-scroll-into-view-1.2.1.tgz", @@ -3610,23 +3449,6 @@ "resolved": "http://registry.npm.taobao.org/dotenv-expand/download/dotenv-expand-4.2.0.tgz", "integrity": "sha1-3vHxyl1gWdJKdm5YeULCEQbOEnU=" }, - "draft-js": { - "version": "0.10.5", - "resolved": "http://registry.npm.taobao.org/draft-js/download/draft-js-0.10.5.tgz", - "integrity": "sha1-v6m+sBj+BTPbsI1mdcNxprCPp0I=", - "requires": { - "fbjs": "^0.8.15", - "immutable": "~3.7.4", - "object-assign": "^4.1.0" - }, - "dependencies": { - "immutable": { - "version": "3.7.6", - "resolved": "http://registry.npm.taobao.org/immutable/download/immutable-3.7.6.tgz", - "integrity": "sha1-E7TTyxK++hVIKib+Gy665kAHHks=" - } - } - }, "duplexer": { "version": "0.1.1", "resolved": "http://registry.npm.taobao.org/duplexer/download/duplexer-0.1.1.tgz", @@ -4220,11 +4042,6 @@ "resolved": "http://registry.npm.taobao.org/eventemitter3/download/eventemitter3-3.1.0.tgz", "integrity": "sha1-CQtNbNvWRe0Qv3UNS1QHlC17oWM=" }, - "eventlistener": { - "version": "0.0.1", - "resolved": "http://registry.npm.taobao.org/eventlistener/download/eventlistener-0.0.1.tgz", - "integrity": "sha1-7Suqu4UiJ68rz4iRUscsY8pTLrg=" - }, "events": { "version": "3.0.0", "resolved": "http://registry.npm.taobao.org/events/download/events-3.0.0.tgz", @@ -5306,11 +5123,6 @@ "resolved": "http://registry.npm.taobao.org/growly/download/growly-1.3.0.tgz", "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=" }, - "gud": { - "version": "1.0.0", - "resolved": "http://registry.npm.taobao.org/gud/download/gud-1.0.0.tgz", - "integrity": "sha1-pIlYGxfmpwvsqavjrlfeekmYUsA=" - }, "gzip-size": { "version": "3.0.0", "resolved": "http://registry.npm.taobao.org/gzip-size/download/gzip-size-3.0.0.tgz", @@ -5319,11 +5131,6 @@ "duplexer": "^0.1.1" } }, - "hammerjs": { - "version": "2.0.8", - "resolved": "http://registry.npm.taobao.org/hammerjs/download/hammerjs-2.0.8.tgz", - "integrity": "sha1-BO93hiz/K7edMPdpIJWTAiK/YPE=" - }, "handle-thing": { "version": "1.2.5", "resolved": "http://registry.npm.taobao.org/handle-thing/download/handle-thing-1.2.5.tgz", @@ -6713,14 +6520,6 @@ "resolved": "http://registry.npm.taobao.org/json-stringify-safe/download/json-stringify-safe-5.0.1.tgz", "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, - "json2mq": { - "version": "0.2.0", - "resolved": "http://registry.npm.taobao.org/json2mq/download/json2mq-0.2.0.tgz", - "integrity": "sha1-tje9O6nqvhIsg+lyBIOusQ0skEo=", - "requires": { - "string-convert": "^0.2.0" - } - }, "json3": { "version": "3.3.2", "resolved": "http://registry.npm.taobao.org/json3/download/json3-3.3.2.tgz", @@ -7100,11 +6899,6 @@ "lodash._reinterpolate": "~3.0.0" } }, - "lodash.throttle": { - "version": "4.1.1", - "resolved": "http://registry.npm.taobao.org/lodash.throttle/download/lodash.throttle-4.1.1.tgz", - "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ=" - }, "lodash.uniq": { "version": "4.5.0", "resolved": "http://registry.npm.taobao.org/lodash.uniq/download/lodash.uniq-4.5.0.tgz", @@ -7808,14 +7602,6 @@ "resolved": "http://registry.npm.taobao.org/obuf/download/obuf-1.1.2.tgz", "integrity": "sha1-Cb6jND1BhZ69RGKS0RydTbYZCE4=" }, - "omit.js": { - "version": "1.0.2", - "resolved": "http://registry.npm.taobao.org/omit.js/download/omit.js-1.0.2.tgz", - "integrity": "sha1-kaFPDrqEBm36AVvzDkdMR/MLyFg=", - "requires": { - "babel-runtime": "^6.23.0" - } - }, "on-finished": { "version": "2.3.0", "resolved": "http://registry.npm.taobao.org/on-finished/download/on-finished-2.3.0.tgz", @@ -9333,11 +9119,6 @@ "resolved": "http://registry.npm.taobao.org/preserve/download/preserve-0.2.0.tgz", "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=" }, - "prettier": { - "version": "1.17.0", - "resolved": "http://registry.npm.taobao.org/prettier/download/prettier-1.17.0.tgz", - "integrity": "sha1-U7MDZ27tIswUqfDOwJtHezAmwAg=" - }, "pretty-bytes": { "version": "4.0.2", "resolved": "http://registry.npm.taobao.org/pretty-bytes/download/pretty-bytes-4.0.2.tgz", @@ -9603,130 +9384,6 @@ "react-lifecycles-compat": "^3.0.4" } }, - "rc-calendar": { - "version": "9.12.4", - "resolved": "http://registry.npm.taobao.org/rc-calendar/download/rc-calendar-9.12.4.tgz", - "integrity": "sha1-aO46hXtTQdeA2Uc1QZJs/gtEkVQ=", - "requires": { - "babel-runtime": "6.x", - "classnames": "2.x", - "moment": "2.x", - "prop-types": "^15.5.8", - "rc-trigger": "^2.2.0", - "rc-util": "^4.1.1", - "react-lifecycles-compat": "^3.0.4" - } - }, - "rc-cascader": { - "version": "0.17.1", - "resolved": "http://registry.npm.taobao.org/rc-cascader/download/rc-cascader-0.17.1.tgz", - "integrity": "sha1-kUSBwzcLX9j4Lk+d+bZZbf7aFNU=", - "requires": { - "array-tree-filter": "^2.1.0", - "prop-types": "^15.5.8", - "rc-trigger": "^2.2.0", - "rc-util": "^4.0.4", - "react-lifecycles-compat": "^3.0.4", - "shallow-equal": "^1.0.0", - "warning": "^4.0.1" - }, - "dependencies": { - "warning": { - "version": "4.0.3", - "resolved": "http://registry.npm.taobao.org/warning/download/warning-4.0.3.tgz", - "integrity": "sha1-Fungd+uKhtavfWSqHgX9hbRnjKM=", - "requires": { - "loose-envify": "^1.0.0" - } - } - } - }, - "rc-checkbox": { - "version": "2.1.6", - "resolved": "http://registry.npm.taobao.org/rc-checkbox/download/rc-checkbox-2.1.6.tgz", - "integrity": "sha1-XcAGU+UncBjEMf7FXji5HB+XbpA=", - "requires": { - "babel-runtime": "^6.23.0", - "classnames": "2.x", - "prop-types": "15.x", - "rc-util": "^4.0.4" - } - }, - "rc-collapse": { - "version": "1.11.1", - "resolved": "http://registry.npm.taobao.org/rc-collapse/download/rc-collapse-1.11.1.tgz", - "integrity": "sha1-SqCXetv1Ip19tYIFZGsTkFrdcq0=", - "requires": { - "classnames": "2.x", - "css-animation": "1.x", - "prop-types": "^15.5.6", - "rc-animate": "2.x", - "react-is": "^16.7.0", - "shallowequal": "^1.1.0" - } - }, - "rc-dialog": { - "version": "7.3.1", - "resolved": "http://registry.npm.taobao.org/rc-dialog/download/rc-dialog-7.3.1.tgz", - "integrity": "sha1-RQQew1v8jjN8kbZLUs6+9upc1KI=", - "requires": { - "babel-runtime": "6.x", - "rc-animate": "2.x", - "rc-util": "^4.4.0" - } - }, - "rc-drawer": { - "version": "1.7.7", - "resolved": "http://registry.npm.taobao.org/rc-drawer/download/rc-drawer-1.7.7.tgz", - "integrity": "sha1-sBTR3lJFfIXE8+Hw1kelQDHdJgw=", - "requires": { - "babel-runtime": "6.x", - "classnames": "^2.2.5", - "prop-types": "^15.5.0", - "rc-util": "^4.5.1" - } - }, - "rc-dropdown": { - "version": "2.4.1", - "resolved": "http://registry.npm.taobao.org/rc-dropdown/download/rc-dropdown-2.4.1.tgz", - "integrity": "sha1-qu9us6UVLN2ZgolcKnjZtfBGzew=", - "requires": { - "babel-runtime": "^6.26.0", - "classnames": "^2.2.6", - "prop-types": "^15.5.8", - "rc-trigger": "^2.5.1", - "react-lifecycles-compat": "^3.0.2" - } - }, - "rc-editor-core": { - "version": "0.8.9", - "resolved": "http://registry.npm.taobao.org/rc-editor-core/download/rc-editor-core-0.8.9.tgz", - "integrity": "sha1-9hGVLI7tll4+NI2ErnvohdrrIhw=", - "requires": { - "babel-runtime": "^6.26.0", - "classnames": "^2.2.5", - "draft-js": "^0.10.0", - "immutable": "^3.7.4", - "lodash": "^4.16.5", - "prop-types": "^15.5.8", - "setimmediate": "^1.0.5" - } - }, - "rc-editor-mention": { - "version": "1.1.12", - "resolved": "http://registry.npm.taobao.org/rc-editor-mention/download/rc-editor-mention-1.1.12.tgz", - "integrity": "sha1-iWvLFyES8YgS6W/dM7pgPA/HMGo=", - "requires": { - "babel-runtime": "^6.23.0", - "classnames": "^2.2.5", - "dom-scroll-into-view": "^1.2.0", - "draft-js": "~0.10.0", - "immutable": "^3.7.4", - "prop-types": "^15.5.8", - "rc-animate": "^2.3.0", - "rc-editor-core": "~0.8.3" - } - }, "rc-form": { "version": "2.4.4", "resolved": "http://registry.npm.taobao.org/rc-form/download/rc-form-2.4.4.tgz", @@ -9759,28 +9416,6 @@ } } }, - "rc-hammerjs": { - "version": "0.6.9", - "resolved": "http://registry.npm.taobao.org/rc-hammerjs/download/rc-hammerjs-0.6.9.tgz", - "integrity": "sha1-mk3b2hsuyPm5WWCRpqmJhCokOQc=", - "requires": { - "babel-runtime": "6.x", - "hammerjs": "^2.0.8", - "prop-types": "^15.5.9" - } - }, - "rc-input-number": { - "version": "4.4.1", - "resolved": "http://registry.npm.taobao.org/rc-input-number/download/rc-input-number-4.4.1.tgz", - "integrity": "sha1-FjbPKBzejXjqTIuf/P/Xe4A1BnU=", - "requires": { - "babel-runtime": "6.x", - "classnames": "^2.2.0", - "prop-types": "^15.5.7", - "rc-util": "^4.5.1", - "rmc-feedback": "^2.0.0" - } - }, "rc-menu": { "version": "7.4.22", "resolved": "http://registry.npm.taobao.org/rc-menu/download/rc-menu-7.4.22.tgz", @@ -9799,18 +9434,6 @@ "resize-observer-polyfill": "^1.5.0" } }, - "rc-notification": { - "version": "3.3.1", - "resolved": "http://registry.npm.taobao.org/rc-notification/download/rc-notification-3.3.1.tgz", - "integrity": "sha1-C6o+cPjUCrAVzo+njCYMSQ/HvrQ=", - "requires": { - "babel-runtime": "6.x", - "classnames": "2.x", - "prop-types": "^15.5.8", - "rc-animate": "2.x", - "rc-util": "^4.0.4" - } - }, "rc-pagination": { "version": "1.17.14", "resolved": "http://registry.npm.taobao.org/rc-pagination/download/rc-pagination-1.17.14.tgz", @@ -9821,15 +9444,6 @@ "react-lifecycles-compat": "^3.0.4" } }, - "rc-progress": { - "version": "2.3.0", - "resolved": "http://registry.npm.taobao.org/rc-progress/download/rc-progress-2.3.0.tgz", - "integrity": "sha1-z70H/5AmxFAQCYDeIJqSZQ4k8xM=", - "requires": { - "babel-runtime": "6.x", - "prop-types": "^15.5.8" - } - }, "rc-rate": { "version": "2.5.0", "resolved": "http://registry.npm.taobao.org/rc-rate/download/rc-rate-2.5.0.tgz", @@ -9870,116 +9484,6 @@ } } }, - "rc-slider": { - "version": "8.6.9", - "resolved": "http://registry.npm.taobao.org/rc-slider/download/rc-slider-8.6.9.tgz", - "integrity": "sha1-syFIpJjJJ8k/INwflehoLEkkv44=", - "requires": { - "babel-runtime": "6.x", - "classnames": "^2.2.5", - "prop-types": "^15.5.4", - "rc-tooltip": "^3.7.0", - "rc-util": "^4.0.4", - "shallowequal": "^1.0.1", - "warning": "^4.0.3" - }, - "dependencies": { - "warning": { - "version": "4.0.3", - "resolved": "http://registry.npm.taobao.org/warning/download/warning-4.0.3.tgz", - "integrity": "sha1-Fungd+uKhtavfWSqHgX9hbRnjKM=", - "requires": { - "loose-envify": "^1.0.0" - } - } - } - }, - "rc-steps": { - "version": "3.3.1", - "resolved": "http://registry.npm.taobao.org/rc-steps/download/rc-steps-3.3.1.tgz", - "integrity": "sha1-SHfiiXMx47/ba3ieiK6nj08V9zI=", - "requires": { - "babel-runtime": "^6.23.0", - "classnames": "^2.2.3", - "lodash": "^4.17.5", - "prop-types": "^15.5.7" - } - }, - "rc-switch": { - "version": "1.9.0", - "resolved": "http://registry.npm.taobao.org/rc-switch/download/rc-switch-1.9.0.tgz", - "integrity": "sha1-qyuHjycTxoE1ikUzkZdsm5WykPc=", - "requires": { - "classnames": "^2.2.1", - "prop-types": "^15.5.6", - "react-lifecycles-compat": "^3.0.4" - } - }, - "rc-table": { - "version": "6.4.4", - "resolved": "http://registry.npm.taobao.org/rc-table/download/rc-table-6.4.4.tgz", - "integrity": "sha1-fOS4VuooFIRKAWQeyKzy1y7jpao=", - "requires": { - "babel-runtime": "6.x", - "classnames": "^2.2.5", - "component-classes": "^1.2.6", - "lodash": "^4.17.5", - "mini-store": "^2.0.0", - "prop-types": "^15.5.8", - "rc-util": "^4.0.4", - "react-lifecycles-compat": "^3.0.2", - "shallowequal": "^1.0.2", - "warning": "^3.0.0" - } - }, - "rc-tabs": { - "version": "9.6.3", - "resolved": "http://registry.npm.taobao.org/rc-tabs/download/rc-tabs-9.6.3.tgz", - "integrity": "sha1-XuAoFlIXafkuKNwDYKLrEhS1MHU=", - "requires": { - "babel-runtime": "6.x", - "classnames": "2.x", - "create-react-context": "0.2.2", - "lodash": "^4.17.5", - "prop-types": "15.x", - "raf": "^3.4.1", - "rc-hammerjs": "~0.6.0", - "rc-util": "^4.0.4", - "resize-observer-polyfill": "^1.5.1", - "warning": "^3.0.0" - }, - "dependencies": { - "raf": { - "version": "3.4.1", - "resolved": "http://registry.npm.taobao.org/raf/download/raf-3.4.1.tgz", - "integrity": "sha1-B0LpmkplUvRF1z4+4DKK8P8e3jk=", - "requires": { - "performance-now": "^2.1.0" - } - } - } - }, - "rc-time-picker": { - "version": "3.6.3", - "resolved": "http://registry.npm.taobao.org/rc-time-picker/download/rc-time-picker-3.6.3.tgz", - "integrity": "sha1-kV2R1oAWcknTJIcZ4IoxzqpcOwE=", - "requires": { - "classnames": "2.x", - "moment": "2.x", - "prop-types": "^15.5.8", - "rc-trigger": "^2.2.0" - } - }, - "rc-tooltip": { - "version": "3.7.3", - "resolved": "http://registry.npm.taobao.org/rc-tooltip/download/rc-tooltip-3.7.3.tgz", - "integrity": "sha1-KArsavyqROjf8EgPuv+eh/wArsw=", - "requires": { - "babel-runtime": "6.x", - "prop-types": "^15.5.8", - "rc-trigger": "^2.2.2" - } - }, "rc-tree": { "version": "1.15.2", "resolved": "http://registry.npm.taobao.org/rc-tree/download/rc-tree-1.15.2.tgz", @@ -10011,63 +9515,6 @@ } } }, - "rc-tree-select": { - "version": "2.6.2", - "resolved": "http://registry.npm.taobao.org/rc-tree-select/download/rc-tree-select-2.6.2.tgz", - "integrity": "sha1-eDuvvzq9D8ZFoHaXVjA47aYwLyk=", - "requires": { - "classnames": "^2.2.1", - "dom-scroll-into-view": "^1.2.1", - "prop-types": "^15.5.8", - "raf": "^3.4.0", - "rc-animate": "^3.0.0-rc.4", - "rc-tree": "~1.15.0", - "rc-trigger": "^3.0.0-rc.2", - "rc-util": "^4.5.0", - "react-lifecycles-compat": "^3.0.4", - "shallowequal": "^1.0.2", - "warning": "^4.0.1" - }, - "dependencies": { - "rc-animate": { - "version": "3.0.0-rc.6", - "resolved": "http://registry.npm.taobao.org/rc-animate/download/rc-animate-3.0.0-rc.6.tgz", - "integrity": "sha1-BCiO76EY4MriFFNsipA/+qwbw/s=", - "requires": { - "babel-runtime": "6.x", - "classnames": "^2.2.5", - "component-classes": "^1.2.6", - "fbjs": "^0.8.16", - "prop-types": "15.x", - "raf": "^3.4.0", - "rc-util": "^4.5.0", - "react-lifecycles-compat": "^3.0.4" - } - }, - "rc-trigger": { - "version": "3.0.0-rc.3", - "resolved": "http://registry.npm.taobao.org/rc-trigger/download/rc-trigger-3.0.0-rc.3.tgz", - "integrity": "sha1-NYQt8WdNJTFeFCakSIKkyXZSJYs=", - "requires": { - "babel-runtime": "6.x", - "classnames": "^2.2.6", - "prop-types": "15.x", - "raf": "^3.4.0", - "rc-align": "^2.4.1", - "rc-animate": "^3.0.0-rc.1", - "rc-util": "^4.4.0" - } - }, - "warning": { - "version": "4.0.3", - "resolved": "http://registry.npm.taobao.org/warning/download/warning-4.0.3.tgz", - "integrity": "sha1-Fungd+uKhtavfWSqHgX9hbRnjKM=", - "requires": { - "loose-envify": "^1.0.0" - } - } - } - }, "rc-trigger": { "version": "2.6.2", "resolved": "http://registry.npm.taobao.org/rc-trigger/download/rc-trigger-2.6.2.tgz", @@ -10181,17 +9628,6 @@ "text-table": "0.2.0" } }, - "react-dom": { - "version": "16.8.6", - "resolved": "http://registry.npm.taobao.org/react-dom/download/react-dom-16.8.6.tgz", - "integrity": "sha1-cdYwP2MeiwCX9WFl72CPBR/24Q8=", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2", - "scheduler": "^0.13.6" - } - }, "react-error-overlay": { "version": "4.0.1", "resolved": "http://registry.npm.taobao.org/react-error-overlay/download/react-error-overlay-4.0.1.tgz", @@ -10274,17 +9710,6 @@ } } }, - "react-lazy-load": { - "version": "3.0.13", - "resolved": "http://registry.npm.taobao.org/react-lazy-load/download/react-lazy-load-3.0.13.tgz", - "integrity": "sha1-OwqS0zbUPT8Nc8vm81sXBQsIuCQ=", - "requires": { - "eventlistener": "0.0.1", - "lodash.debounce": "^4.0.0", - "lodash.throttle": "^4.0.0", - "prop-types": "^15.5.8" - } - }, "react-lifecycles-compat": { "version": "3.0.4", "resolved": "http://registry.npm.taobao.org/react-lifecycles-compat/download/react-lifecycles-compat-3.0.4.tgz", @@ -10390,22 +9815,9 @@ "stifle": "^1.0.2" } }, - "react-slick": { - "version": "0.23.2", - "resolved": "http://registry.npm.taobao.org/react-slick/download/react-slick-0.23.2.tgz", - "integrity": "sha1-jYvbx3pmeOitNvUMMleMfA8cVPY=", - "requires": { - "classnames": "^2.2.5", - "enquire.js": "^2.1.6", - "json2mq": "^0.2.0", - "lodash.debounce": "^4.0.8", - "prettier": "^1.14.3", - "resize-observer-polyfill": "^1.5.0" - } - }, "react-transition-group": { "version": "1.2.1", - "resolved": "http://registry.npm.taobao.org/react-transition-group/download/react-transition-group-1.2.1.tgz", + "resolved": "https://registry.npm.taobao.org/react-transition-group/download/react-transition-group-1.2.1.tgz", "integrity": "sha1-4R9yslf5IbITIpp3TfRmEjRsfKY=", "requires": { "chain-function": "^1.0.0", @@ -11135,15 +10547,6 @@ "inherits": "^2.0.1" } }, - "rmc-feedback": { - "version": "2.0.0", - "resolved": "http://registry.npm.taobao.org/rmc-feedback/download/rmc-feedback-2.0.0.tgz", - "integrity": "sha1-y8bLOuY8emNe7w4l5PuvWsNm7qo=", - "requires": { - "babel-runtime": "6.x", - "classnames": "^2.2.5" - } - }, "run-async": { "version": "2.3.0", "resolved": "http://registry.npm.taobao.org/run-async/download/run-async-2.3.0.tgz", @@ -11225,15 +10628,6 @@ "resolved": "http://registry.npm.taobao.org/sax/download/sax-1.2.4.tgz", "integrity": "sha1-KBYjTiN4vdxOU1T6tcqold9xANk=" }, - "scheduler": { - "version": "0.13.6", - "resolved": "http://registry.npm.taobao.org/scheduler/download/scheduler-0.13.6.tgz", - "integrity": "sha1-RmpOwzJGezGpG5v3TlNHBy5M2Ik=", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, "schema-utils": { "version": "0.3.0", "resolved": "http://registry.npm.taobao.org/schema-utils/download/schema-utils-0.3.0.tgz", @@ -11406,11 +10800,6 @@ "safe-buffer": "^5.0.1" } }, - "shallow-equal": { - "version": "1.1.0", - "resolved": "http://registry.npm.taobao.org/shallow-equal/download/shallow-equal-1.1.0.tgz", - "integrity": "sha1-zAIvAw3LoNHBmKv2WKPGx0Thcco=" - }, "shallowequal": { "version": "1.1.0", "resolved": "http://registry.npm.taobao.org/shallowequal/download/shallowequal-1.1.0.tgz", @@ -11934,11 +11323,6 @@ "resolved": "http://registry.npm.taobao.org/strict-uri-encode/download/strict-uri-encode-1.1.0.tgz", "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" }, - "string-convert": { - "version": "0.2.1", - "resolved": "http://registry.npm.taobao.org/string-convert/download/string-convert-0.2.1.tgz", - "integrity": "sha1-aYLMMEn7tM2F+LJFaLnZvznu/5c=" - }, "string-length": { "version": "1.0.1", "resolved": "http://registry.npm.taobao.org/string-length/download/string-length-1.0.1.tgz", @@ -12248,11 +11632,6 @@ "resolved": "http://registry.npm.taobao.org/tiny-warning/download/tiny-warning-1.0.2.tgz", "integrity": "sha1-Hfrnce4aBDlr394no63OvGtkiyg=" }, - "tinycolor2": { - "version": "1.4.1", - "resolved": "http://registry.npm.taobao.org/tinycolor2/download/tinycolor2-1.4.1.tgz", - "integrity": "sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g=" - }, "tmp": { "version": "0.0.33", "resolved": "http://registry.npm.taobao.org/tmp/download/tmp-0.0.33.tgz", @@ -12314,11 +11693,6 @@ } } }, - "toggle-selection": { - "version": "1.0.6", - "resolved": "http://registry.npm.taobao.org/toggle-selection/download/toggle-selection-1.0.6.tgz", - "integrity": "sha1-bkWxJj8gF/oKzH2J14sVuL932jI=" - }, "toposort": { "version": "1.0.7", "resolved": "http://registry.npm.taobao.org/toposort/download/toposort-1.0.7.tgz", diff --git a/public/react/public/css/edu-all.css b/public/react/public/css/edu-all.css index 425255048..cb78f8e00 100644 --- a/public/react/public/css/edu-all.css +++ b/public/react/public/css/edu-all.css @@ -3048,7 +3048,7 @@ a.singlepublishtwo{ /*工程认证*/ /*首页*/ .authMainImg{width: 100%;height: 240px;background:url("/images/educoder/auth/banner1.jpg") no-repeat top center;background-size: 100% 100%;justify-content: center;align-items: center;display: -webkit-flex;} -.ListTableLine>p,.ListTableLine>.ListTableTitle{padding: 0px 30px;background-color: #F5F5F5;line-height: 40px;height: 56px;padding-top: 8px;box-sizing: border-box;} +.ListTableLine>p,.ListTableLine>.ListTableTitle{margin-bottom: 0px;padding: 0px 30px;background-color: #F5F5F5;line-height: 40px;height: 56px;padding-top: 8px;box-sizing: border-box;} .ListTableLine>p span,.ListTableTitle span{float: left;color: #666;box-sizing: border-box} .ListTableLine li{min-height: 48px;padding: 10px 0px;box-sizing: border-box;margin:0px 30px;border-bottom: 1px solid #eaeaea;} .ListTableLine li>span{float: left;box-sizing: border-box;} diff --git a/public/react/public/index.html b/public/react/public/index.html index 0e20a982a..a2d09dedc 100755 --- a/public/react/public/index.html +++ b/public/react/public/index.html @@ -5,13 +5,9 @@ <!-- width=device-width, initial-scale=1 , shrink-to-fit=no --> <!-- <meta name="viewport" content=""> --> <meta name="theme-color" content="#000000"> - <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests"> + <!--<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">--> + <!--<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">--> - - <!-- - manifest.json provides metadata used when your web app is added to the - homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/ - --> <link rel="manifest" href="%PUBLIC_URL%/manifest.json"> <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico"> <!-- diff --git a/public/react/src/modules/courses/Index.js b/public/react/src/modules/courses/Index.js index 95927893d..f9f80a9da 100644 --- a/public/react/src/modules/courses/Index.js +++ b/public/react/src/modules/courses/Index.js @@ -315,9 +315,33 @@ class CoursesIndex extends Component{ if(isNaN(id)){ return } + + const querys = this.props.location.search; + var dataqueryss={} + try { + var foqus=this.foo(querys); + if(JSON.stringify(foqus) ==="{}"){ + this.setState({ + dataquerys:{}, + }); + }else{ + this.setState({ + dataquerys:foqus, + }); + dataqueryss=foqus; + } + }catch (e) { + this.setState({ + dataquerys:{}, + }) + } // let id=this.props.match.params.coursesId; let url ="/courses/"+id+"/left_banner.json" - axios.get(url).then((response) => { + axios.get(url, + {params: + dataqueryss + } + ).then((response) => { if(response!=undefined){ if(response.data&&response.data){ this.setState({ @@ -330,7 +354,28 @@ class CoursesIndex extends Component{ } } }) - } + }; + foo=(url)=> { + var json = {}; + var regExp = /[\?\&](\w+)(=?)(\w*)/g; + var arr; + do { + arr = regExp.exec(url); + // console.log(arr); // arr = [完整的字符串, key, 等号或'', value或''] + + if (arr) { + var key = arr[1]; + var value = arr[3]; + // arr[2] === ''时, value = undefined + if (!arr[2]) + value = undefined; + + json[key] = value; + } + } while (arr); + + return json; + }; locationNav=(list)=>{ if(list){ diff --git a/public/react/src/modules/courses/busyWork/CommonWorkDetailIndex.js b/public/react/src/modules/courses/busyWork/CommonWorkDetailIndex.js index b5fb8b047..8985aa07e 100644 --- a/public/react/src/modules/courses/busyWork/CommonWorkDetailIndex.js +++ b/public/react/src/modules/courses/busyWork/CommonWorkDetailIndex.js @@ -286,8 +286,8 @@ class CommonWorkDetailIndex extends Component{ seeworks={undefined} reviseAttachmentUrl={`/student_works/${work_id || studentWorkId}/revise_attachment.json`} />:""} - <a className={"fr color-blue font-16 mt7"} href={"javascript:void(0)"} - onClick={this.addAccessory} + <a className={"fr color-blue font-16 "} href={"javascript:void(0)"} + onClick={this.addAccessory} style={{ 'marginTop': '-4px' }} >补交附件</a> </React.Fragment> diff --git a/public/react/src/modules/courses/busyWork/CommonWorkList.js b/public/react/src/modules/courses/busyWork/CommonWorkList.js index a489e7c3d..56ae40e2d 100644 --- a/public/react/src/modules/courses/busyWork/CommonWorkList.js +++ b/public/react/src/modules/courses/busyWork/CommonWorkList.js @@ -640,6 +640,8 @@ class CommonWorkList extends Component{ } else if (time_status === 4) { timeMsg = '申诉剩余时间' } + + const hasData = student_works && !!student_works.length && page == 1 // console.log(StudentData) // console.log(student_works) @@ -691,7 +693,7 @@ class CommonWorkList extends Component{ } `}</style> <div style={{ background: '#fff'}} className="workListContent"> - { isAdmin && <ul className="clearfix" style={{padding: "20px 40px 10px", position: 'relative', paddingLeft: '24px'}}> + { isAdmin && hasData && <ul className="clearfix" style={{padding: "20px 40px 10px", position: 'relative', paddingLeft: '24px'}}> <CheckAllGroup options={options_teacher_comment} label={'你的评阅:'} onChange={this.teacherCommentOptionChange}></CheckAllGroup> <CheckAllGroup options={options_status} label={'作品状态:'} onChange={this.statusOptionChange}></CheckAllGroup> @@ -713,7 +715,7 @@ class CommonWorkList extends Component{ { <div id="graduation_work_list" style={{padding: isStudent ? '10px 24px 10px 24px' : '0px 24px 10px 24px'}}> <div className="clearfix"> - <span className="fl color-grey-6 font-12"> + {hasData && <span className="fl color-grey-6 font-12"> { isAdmin ? (!!all_member_count) && <React.Fragment> <span className="color-orange-tip">{work_count || '0'}</span>个检索结果({all_member_count} 学生) @@ -725,7 +727,7 @@ class CommonWorkList extends Component{ <span className="color-orange-tip">{left_time.time}</span> </React.Fragment> } - </span> + </span>} {/* { isAdminOrStudent && student_works && !!student_works.length && <div className="fr color-grey-6 edu-menu-panel"> <p style={{color: '#989898'}} className="color-grey-6"><a data-remote="true" className="font-12"> diff --git a/public/react/src/modules/courses/busyWork/common/WorkDetailPageHeader.js b/public/react/src/modules/courses/busyWork/common/WorkDetailPageHeader.js index c9d99696a..cccaa3ca4 100644 --- a/public/react/src/modules/courses/busyWork/common/WorkDetailPageHeader.js +++ b/public/react/src/modules/courses/busyWork/common/WorkDetailPageHeader.js @@ -125,8 +125,8 @@ class WorkDetailPageHeader extends Component{ seeworks={undefined} reviseAttachmentUrl={`/student_works/${work_id || studentWorkId}/revise_attachment.json`} />:""} - <a className={"fr color-blue font-16 mt7"} href={"javascript:void(0)"} - onClick={this.addAccessory} + <a className={"fr color-blue font-16 "} href={"javascript:void(0)"} + onClick={this.addAccessory} style={{ 'marginTop': '-4px' }} >补交附件</a> </React.Fragment> diff --git a/public/react/src/modules/courses/common/comments/CCommentItem.js b/public/react/src/modules/courses/common/comments/CCommentItem.js index 2415dd0b0..5d904a36b 100644 --- a/public/react/src/modules/courses/common/comments/CCommentItem.js +++ b/public/react/src/modules/courses/common/comments/CCommentItem.js @@ -238,7 +238,8 @@ class CCommentItem extends Component{ <div className="comment_content clearfix" id={`reply_content_${item.id}`}> <div className="color-grey-3" id={`reply_content_${item.id}`}> - <div className={"break_word_comments markdown-body"} dangerouslySetInnerHTML={{__html: item.content}}></div> + <div className={"break_word_comments markdown-body"} + dangerouslySetInnerHTML={{__html: this.parseCommentContent(item.content)}}></div> <div className="cl"></div> </div> </div> @@ -373,8 +374,8 @@ class CCommentItem extends Component{ </Tooltip> : ''} */} </div> - {/* style={{ height: '130px'}} */} - <p className="orig_reply" > + {/* 去掉了orig_reply 影响到i标签 */} + <p className="" > {/* 第二排右侧按钮区域 */} {/* ${this.state.show_reply ? '回复' : '申诉'} */} {(show_reply || show_appeal) && diff --git a/public/react/src/modules/courses/coursesDetail/CoursesBanner.js b/public/react/src/modules/courses/coursesDetail/CoursesBanner.js index 21ac26727..437471436 100644 --- a/public/react/src/modules/courses/coursesDetail/CoursesBanner.js +++ b/public/react/src/modules/courses/coursesDetail/CoursesBanner.js @@ -94,9 +94,30 @@ class CoursesBanner extends Component { this.updatabanner() } updatabanner=()=>{ + const query = this.props.location.search; + var dataqueryss={} + try { + var foqus=this.foo(query); + if(JSON.stringify(foqus) ==="{}"){ + this.setState({ + dataquerys:{}, + }); + }else{ + this.setState({ + dataquerys:foqus, + }); + dataqueryss=foqus; + } + }catch (e) { + this.setState({ + dataquerys:{}, + }) + } let courseId = this.props.match.params.coursesId; let url = "/courses/" + courseId + "/top_banner.json" - axios.get(url).then((result) => { + axios.get(url,{params: + dataqueryss + }).then((result) => { if( result!=undefined){ let data = result.data; this.setState({ @@ -107,7 +128,28 @@ class CoursesBanner extends Component { this.onloadupdatabanner() } }) - } + }; + foo=(url)=> { + var json = {}; + var regExp = /[\?\&](\w+)(=?)(\w*)/g; + var arr; + do { + arr = regExp.exec(url); + // console.log(arr); // arr = [完整的字符串, key, 等号或'', value或''] + + if (arr) { + var key = arr[1]; + var value = arr[3]; + // arr[2] === ''时, value = undefined + if (!arr[2]) + value = undefined; + + json[key] = value; + } + } while (arr); + + return json; + }; showeditmenu = () => { this.setState({ show: true, diff --git a/public/react/src/modules/courses/gradinforms/myysleduinforms.css b/public/react/src/modules/courses/gradinforms/myysleduinforms.css index b1efc783f..8376c63c8 100644 --- a/public/react/src/modules/courses/gradinforms/myysleduinforms.css +++ b/public/react/src/modules/courses/gradinforms/myysleduinforms.css @@ -58,7 +58,7 @@ float: left; padding-top: 31px; padding-left: 25px; - font-size: 16px; + font-size: 21px; color: #05101A; text-align: left; font-weight:bold; diff --git a/public/react/src/modules/courses/shixunHomework/ShixunWorkReport.js b/public/react/src/modules/courses/shixunHomework/ShixunWorkReport.js index bb8ccae4a..2667f1dd9 100644 --- a/public/react/src/modules/courses/shixunHomework/ShixunWorkReport.js +++ b/public/react/src/modules/courses/shixunHomework/ShixunWorkReport.js @@ -349,7 +349,7 @@ class ShixunWorkReport extends Component { <span className={"color-grey-9"}> {data&&data.course_name}</span> </a> <span className="color-grey-9 fl ml3 mr3">></span> - <a className="btn colorgrey fl hovercolorblue " to={"/courses/"+this.props.match.params.coursesId+"/"+this.state.shixuntypes+"/"+category_id}> + <a className="btn colorgrey fl hovercolorblue " href={"/courses/"+this.props.match.params.coursesId+"/"+this.state.shixuntypes+"/"+category_id}> <span className={"color-grey-9"}>{data===undefined?"":data.category===null?"":data.category.category_name}</span> </a> <span className="color-grey-9 fl ml3 mr3">></span> diff --git a/public/react/src/modules/ecs/EcSetting/CourseSupports/ecCourseSupports.css b/public/react/src/modules/ecs/EcSetting/CourseSupports/ecCourseSupports.css index 7f497b28e..87f87fc8e 100644 --- a/public/react/src/modules/ecs/EcSetting/CourseSupports/ecCourseSupports.css +++ b/public/react/src/modules/ecs/EcSetting/CourseSupports/ecCourseSupports.css @@ -355,4 +355,10 @@ input{ .editlybuttonbox{ margin-bottom: 30px; margin-right: 3%; +} + +.Importclassroomdata{ + top: 30px; + position: absolute; + right: 0px; } \ No newline at end of file diff --git a/public/react/src/modules/ecs/EcSetting/CourseSupports/index.js b/public/react/src/modules/ecs/EcSetting/CourseSupports/index.js index bc848b209..511a0da64 100644 --- a/public/react/src/modules/ecs/EcSetting/CourseSupports/index.js +++ b/public/react/src/modules/ecs/EcSetting/CourseSupports/index.js @@ -34,7 +34,13 @@ class CourseSupports extends Component { Supportslist:'', Supportssum:false, Supportsclass:false, - Supportsclasskey:undefined + Supportsclasskey:undefined, + neweditcourse:[{"weights": 0, + "ec_course_name":'', + "top_relation": false, + "ec_course_id":'' + }], + max_support_count:0 } } @@ -58,15 +64,25 @@ class CourseSupports extends Component { axios.get(url) .then((response) => { if(response.status===200){ - this.setState({ - data:response.data - }) - console.log(response.data.graduation_subitems.length) if(response.data.graduation_subitems.length===0){ this.setState({ Supportstype:true, + data:response.data, Supportslist:'数据为空,请去毕业要求——>毕业要求指标点分解列表配置数据' }) + }else{ + let datas=response.data.graduation_subitems; + let listlength=[] + datas.map((item,key)=>{ + listlength.push(item.course_supports.length) + }) + + let max_support_count=Math.max(...listlength); + + this.setState({ + max_support_count:max_support_count, + data:response.data + }) } } @@ -108,7 +124,7 @@ class CourseSupports extends Component { id=parseInt(id); let subindex =e.target.getAttribute("subindex"); - debugger + // const url = `/ec_course_supports/edit_require_vs_course?subitem_id=`+id // axios.get(url) // .then((response) => { @@ -155,14 +171,18 @@ class CourseSupports extends Component { if(item.course_supports.length>0){ this.setState({ editcourse:item.course_supports, + neweditcourse:item.course_supports, Editkey:key, index:subindex, + ec_graduation_subitem_id:id, }) }else if(item.course_supports.length===0){ this.setState({ editcourse:[{weights: 0,top_relation: false,ec_course_name:'',ec_course_id:''}], + neweditcourse:[{weights: 0,top_relation: false,ec_course_name:'',ec_course_id:''}], Editkey:key, index:subindex, + ec_graduation_subitem_id:id, }) } @@ -197,7 +217,12 @@ class CourseSupports extends Component { Addcourse=(e)=>{ let {editcourse} =this.state; - let neweditcourse=editcourse; + let arr=new Array(); + editcourse.map((item,key)=>{ + arr.push(item) + }) + + let neweditcourse=arr; let newadd = {weights: 0,top_relation: false,ec_course_name:'',ec_course_id:''}; neweditcourse.push(newadd); this.setState({ @@ -215,29 +240,49 @@ class CourseSupports extends Component { // 删除 // let id =e.target.getAttribute("index"); let {editcourse} = this.state; - let neweditcourse=editcourse; - neweditcourse.splice(e,1); - let newnum=0; - for(var j=0;j<neweditcourse.length;j++){ - if(neweditcourse[j].weights===undefined){ - newnum=0 - }else{ - newnum=newnum+neweditcourse[j].weights; - } - } - newnum= Math.round(newnum*100)/100; - this.setState({ - Supportstype:false, - supportid:null, - Supportslist:"", - editcourse:neweditcourse, - editnum:newnum - }) + let arr=new Array(); + editcourse.map((item,key)=>{ + arr.push(item) + }) + + let neweditcourse=arr; + if(neweditcourse.length>1){ + neweditcourse.splice(e,1); + let newnum=0; + for(var j=0;j<neweditcourse.length;j++){ + if(neweditcourse[j].weights===undefined){ + newnum=0 + }else{ + newnum=newnum+neweditcourse[j].weights; + } + } + newnum= Math.round(newnum*100)/100; + + this.setState({ + Supportstype:false, + supportid:null, + Supportslist:"", + editcourse:neweditcourse, + editnum:newnum + }) + }else{ + this.setState({ + // Supportstype:true, + Supportslist:'删除失败,至少保留一个课程', + }) + } + + } enterweight=(e)=>{ let {editcourse} = this.state; - let neweditcourse=editcourse; + let arr=new Array(); + editcourse.map((item,key)=>{ + arr.push(item) + }) + + let neweditcourse=arr; var id=e.target.id; var value=parseFloat(e.target.value); if(isNaN(value)){ @@ -301,9 +346,15 @@ class CourseSupports extends Component { handleChange=(e)=> { let {editcourse} = this.state; - let value=`${e[0]}`; - value=parseInt(value) - let neweditcourse=editcourse; + + let arr=new Array(); + editcourse.map((item,key)=>{ + arr.push(item) + }) + let neweditcourse=arr; + + let value=`${e[0]}`; + value=parseInt(value) let num=`${e[1]}`; num=parseInt(num) @@ -327,7 +378,13 @@ class CourseSupports extends Component { relevancetop=(e)=>{ let {editcourse} = this.state; - let neweditcourse=editcourse; + + let arr=new Array(); + editcourse.map((item,key)=>{ + arr.push(item) + }) + + let neweditcourse=arr; let id =e.target.getAttribute("itindex"); for(var i=0;i<1;i++){ neweditcourse[id].top_relation=false; @@ -339,7 +396,11 @@ class CourseSupports extends Component { relevancebottom=(e)=>{ let {editcourse} = this.state; - let neweditcourse=editcourse; + let arr=new Array(); + editcourse.map((item,key)=>{ + arr.push(item) + }) + let neweditcourse=arr; let id =e.target.getAttribute("itindex"); for(var i=0;i<1;i++){ neweditcourse[id].top_relation=true; @@ -355,14 +416,20 @@ class CourseSupports extends Component { this.inputNumberRef.blur(); } CancelSupports=()=>{ + let{editcourse,neweditcourse}=this.state; + // + // console.log(editcourse) + // console.log(neweditcourse) + this.setState({ Editkey:null, Supportssum:false, Supportsclass:false, + editcourse:neweditcourse }) } SubmitClassData=()=>{ - let {editcourse,editnum,ec_graduation_subitem_id,ec_year_id} = this.state; + let {editcourse,editnum,ec_graduation_subitem_id} = this.state; if(editcourse.length===0){ this.setState({ // Supportstype:true, @@ -409,35 +476,39 @@ class CourseSupports extends Component { } }) - var Url = '/ec_course_supports'; + + + + var Url = `/ec_years/${this.props.match.params.ec_year_id}/graduation_course_supports.json`; axios.post(Url, { - ec_year_id: ec_year_id, - ec_graduation_subitem_id:ec_graduation_subitem_id, - course: editcourse - }, - { - withCredentials: true + graduation_subitem_id :ec_graduation_subitem_id, + course_supports: editcourse } ).then((response) => { - - if(response.data.status===0){ - this.setState({ - Editkey:null, - Supportslist:response.data.messsage, - Supportstype:true, - Supportssum:false, - Supportsclass:false, - Supportsclasskey:undefined, - }) - this.UpdateClassData(); + if(response.data.id===ec_graduation_subitem_id){ + + // this.setState({ + // Editkey:null, + // Supportslist:"保存成功", + // Supportstype:true, + // Supportssum:false, + // Supportsclass:false, + // Supportsclasskey:undefined, + // }) + this.UpdateClassData(); + this.setState({ + Editkey:null, + Supportssum:false, + Supportsclass:false, + }) }else if(response.data.status===-1){ - this.setState({ - Supportslist:"参数错误", - Supportstype:true, - Supportssum:false, - Supportsclass:false, - Supportsclasskey:undefined, - }) + // this.setState({ + // Supportslist:"参数错误", + // Supportstype:true, + // Supportssum:false, + // Supportsclass:false, + // Supportsclasskey:undefined, + // }) } }).catch((error) => { console.log(error) @@ -457,9 +528,41 @@ class CourseSupports extends Component { Supportslist:"", }) } + + confirmysl(url){ + axios.get(url + '?export=true').then((response) => { + if(response.data.status&&response.data.status===-1){ + + }else if(response.data.status&&response.data.status===-2){ + if(response.data.message === "100"){ + // 已超出文件导出的上限数量(100 ),建议: + + this.setState({ + DownloadType:true, + DownloadMessageval:100 + }) + }else { + //因附件资料超过500M + this.setState({ + DownloadType:true, + DownloadMessageval:500 + }) + } + }else { + this.props.showNotification(`正在下载中`); + window.open("/api"+url, '_blank'); + } + }).catch((error) => { + console.log(error) + }); + } + + toforums=(url)=>{ + window.open( url, '_blank'); + } render() { const Option = Select.Option; - let {data,ec_courses_list,editcourse,editnum,index,ec_year_id,Supportsclasskey,ecComponentState,hidesupport,supportid,Editkey,titlemessage,Supportstype,Supportslist,Supportssum,Supportsclass,major_school_id} = this.state; + let {max_support_count,data,ec_courses_list,editcourse,editnum,index,ec_year_id,Supportsclasskey,ecComponentState,hidesupport,supportid,Editkey,titlemessage,Supportstype,Supportslist,Supportssum,Supportsclass,major_school_id} = this.state; var list = (length) => { var res = []; for(var i = 0; i < length; i++) { @@ -472,6 +575,11 @@ class CourseSupports extends Component { return res } + let toptiebox={width: 126.6*max_support_count+"px"}; + + let ismidbox={width:123.82*max_support_count+"px",margin:'0px 0px'}; + + // console.log(this.props.year&&this.props.year.can_manager) return ( <div className="newMain clearfix"> <Modal @@ -497,7 +605,7 @@ class CourseSupports extends Component { </Modal> - <div className="educontent mb290"> + <div className="educontent mb20"> @@ -506,24 +614,26 @@ class CourseSupports extends Component { <div className="clearfix padding20-30 bor-bottom-greyE" style={{position:'relative'}}> <span className="font-18 courseSystem">课程体系对毕业要求的支撑</span> {/* <a href="javascript:void(0)" className="fr white-btn edu-blueback-btn mt4">导出培养目标</a> */} - <span className={data.is_manager===false?"none":"Importclassroomdata"} style={{top: '29px'}}> - <a className="white-btn edu-blueback-btn fr mb10 mr10" target="_blank" href={'/ec_major_schools/'+major_school_id+'/academic_years/'+ec_year_id+'/export_course_requirements?format=xls'}>导出课程体系支撑矩阵</a> + + + <span className={this.props.year&&this.props.year.can_manager===false?"none":"Importclassroomdata"} style={{top: '29px'}}> + <a className="white-btn edu-blueback-btn fr mb10 mr10" onClick={()=>this.confirmysl(`/ec_years/${this.props.match.params.ec_year_id}/graduation_course_supports.xlsx`)}>导出课程体系支撑矩阵</a> </span> - <div className="color-grey-9 mr10">用矩阵图的形式说明本专业课程体系对毕业要求的支撑关系 <a className={"color-blue"} onClick={() => window.elasticLayer(3534)} >查看详情</a></div> + <div className="color-grey-9 mr10">用矩阵图的形式说明本专业课程体系对毕业要求的支撑关系 <a className={"color-blue"} onClick={() => this.toforums(`/forums/${3534}`)} >查看详情</a></div> </div> <div className="padding20-30" id="training_objective_contents"> - <span className="fl SystemParameters" >毕业要求指标点(<a href={data.subitems_url}><span className="Systemnum">{data.count}</span></a>)</span> - <span className="fl ml20 SystemParameters">课程体系(<a href={data.course_url}><span className="Systemnum">{data.course_count}</span></a>)</span> + <span className="fl SystemParameters" >毕业要求指标点(<Link to={`/ecs/major_schools/${this.props.match.params.major_school_id}/years/${this.props.match.params.ec_year_id}/graduation_requirement`}><span className="Systemnum">{data.count}</span></Link>)</span> + <span className="fl ml20 SystemParameters">课程体系(<Link to={`/ecs/major_schools/${this.props.match.params.major_school_id}/years/${this.props.match.params.ec_year_id}/courses/ec_course_support_setting/1`}><span className="Systemnum">{data.course_count}</span></Link>)</span> </div> </div> <div className="ListTableLine" id="school_major_list" style={{overflow:'auto'}}> - <p className="clearfix" style={{width: 120*data.max_support_count>1200? 140*data.max_support_count : 1200+"px"}}> + <p className="clearfix" style={toptiebox}> <span className="color-666 finishtarget">毕业要求指标点</span> - {list(data.max_support_count<5||data.max_support_count===undefined?5:data.max_support_count)} + {data.graduation_subitems===undefined?"":list(max_support_count<5||max_support_count===undefined?5:max_support_count)} <span className="column-1 operationright color-666" style={{ paddingLeft: '28px' @@ -535,7 +645,7 @@ class CourseSupports extends Component { data.graduation_subitems===undefined? <Spin delay={500} className="Spinlarge" indicator={<Icon type="loading" style={{ fontSize: 30 }} spin />}/>:data.graduation_subitems.map((item,key)=>{ return ( - <li className={data.graduation_subitems.length===key+1?"clearfix mb10":"clearfix"} key={key} style={{width: 120*data.max_support_count > 1134 ? 136*data.max_support_count : 1134+"px",margin: '0px 0px'}}> + <li className={data.graduation_subitems.length===key+1?"clearfix mb10":"clearfix"} key={key} style={ismidbox}> <Tooltip placement="bottom" title={item.sequence_title}> <span className="column-1 columnlocation" style={{display:Editkey!=key?"block":'none',width: '95px', paddingLeft: '23px'}}>{item.graduation_requirement_position+"-"+item.position}</span> </Tooltip> @@ -550,7 +660,7 @@ class CourseSupports extends Component { display:Editkey!=key?"block":'none', marginRight: '-1px' }}> - <div data-tip-down={t.ec_course_name} className={t.top_relation===true?"DDred columnbox":"columnbox"} + <div title={t.ec_course_name} className={t.top_relation===true?"DDred columnbox":"columnbox"} style={{textAlign: 'center'}} >{t.ec_course_name.length>12?t.ec_course_name.substring(0, 10)+"...":t.ec_course_name}</div> <div className={t.top_relation===true?"DDred":""} @@ -569,27 +679,34 @@ class CourseSupports extends Component { <div className="width20">{Math.round(item.weights_total*100)/100===0?0:(Math.round(item.weights_total*100)/100)}</div> </div> <div className="left operationalter"> - {data.is_manager===false?"":<a className="editSubentry" data-tip-down="编辑"> - <i className="iconfont icon-bianjidaibeijing color-green" id={item.ec_graduation_subitem_id} subindex={item.graduation_requirement_position+"-"+item.position} onClick={this.EditSupportCourse.bind(this,key)}></i> + {this.props.year&&this.props.year.can_manager===false?"":<a className="editSubentry" title="编辑"> + <i className="iconfont icon-bianjidaibeijing color-green" id={item.id} subindex={item.graduation_requirement_position+"-"+item.position} onClick={this.EditSupportCourse.bind(this,key)}></i> </a>} </div> </div> </span> - - <p className="ListTableLine" id="school_ListTableLine" style={{width: '1134px',display:Editkey===key?"block":'none'}} > - - <p className="clearfix SystemModifythelist"> - <span className="ml6" style={{width:'77px'}}>指标点 {index}</span> - <span className="column-4">支撑课程</span> - <span className="column-2 ml93"> + <style> + { + ` + .ListTableLine li{ background: rgb(255, 255, 255);} + ` + } + </style> + {Editkey===key? + <p className="ListTableLine" id="school_ListTableLine" style={ismidbox} > + <div style={{width: '1134px'}}> + <p className="clearfix SystemModifythelist"> + <span className="ml6" style={{width:'77px'}}>指标点 {index}</span> + <span className="column-4">支撑课程</span> + <span className="column-2 ml93"> <span> 权重(∑=1)</span> <span className="Systempoint">(精确到两位小数)</span> </span> - <span className="column-1 ml50">关联度最高</span> - </p> + <span className="column-1 ml50">关联度最高</span> + </p> - <div className="clearfix editorModify"> + <div className="clearfix editorModify"> {Supportsclass===true?<style> { ` @@ -599,77 +716,75 @@ class CourseSupports extends Component { ` } </style>:""} - { - editcourse.map((it,key)=>{ - - return( - <div className="mb15" key={key}> - - <Select className={Supportsclasskey===key?"showredfont heightimportant":"heightimportant"} showSearch value={it.ec_course_name} onChange={this.handleChange}> - { - ec_courses_list.map((qva,qk)=>{ - return( - <Option value={[qva.id,key,qva.name]} key={[qva.id,key,qva.name]}>{qva.name}</Option> - ) - }) - - } - </Select> - <Input - type="number" - size="large" - className={Supportssum===true?"inputWeight bor-red":"inputWeight"} - id={key} - value={it.weights} - onInput={this.enterweight.bind(this)} - /> - - <div className="SetTheAssociated"> - - <div className="SetTheAssociatedchild"> - - <i className="iconfont icon-gouxuan gouxuanbule" style={{display:it.top_relation===false?'none':'block'}} itindex={key} onClick={this.relevancetop.bind(this)}></i> - <i className="iconfont icon-gouxuan gouxuanwhite" style={{display:it.top_relation===false?'block':'none'}} itindex={key} onClick={this.relevancebottom.bind(this)}></i> - - </div> - - <div className="left operatebutton"> - <a className="mr15 delSubentry" data-tip-down="删除"> - <i className="iconfont icon-shanchu color-grey-c font-15" onClick={()=>this.Deletcourses(key)}></i> - </a> - <a className="newAddSubentry" data-tip-down="添加" - style={{display:key===editcourse.length-1?"inline-block":'none'}} - ><i className="iconfont icon-tianjiafangda color-green" onClick={this.Addcourse}></i></a> - </div> - - </div> - - </div> - ) - }) - } - - </div> - <span className="c_red none ml35 color-red" id="error_tip" style={{display:Supportssum===true||Supportsclass===true?'inline':'none'}}>{Supportslist}</span> - <div className="clearfix editorModify"> + { + editcourse.map((it,key)=>{ + + return( + <div className="mb15" key={key}> + + <Select className={Supportsclasskey===key?"showredfont heightimportant":"heightimportant"} showSearch value={it.ec_course_name} onChange={this.handleChange}> + { + ec_courses_list.map((qva,qk)=>{ + return( + <Option value={[qva.id,key,qva.name]} key={[qva.id,key,qva.name]}>{qva.name}</Option> + ) + }) + + } + </Select> + <Input + type="number" + size="large" + className={Supportssum===true?"inputWeight bor-red":"inputWeight"} + id={key} + value={it.weights} + onInput={this.enterweight.bind(this)} + /> + + <div className="SetTheAssociated"> + + <div className="SetTheAssociatedchild"> + + <i className="iconfont icon-gouxuan gouxuanbule" style={{display:it.top_relation===false?'none':'block'}} itindex={key} onClick={this.relevancetop.bind(this)}></i> + <i className="iconfont icon-gouxuan gouxuanwhite" style={{display:it.top_relation===false?'block':'none'}} itindex={key} onClick={this.relevancebottom.bind(this)}></i> + + </div> + + <div className="left operatebutton"> + {editcourse.length===1?"":<a className="mr15 delSubentry" title="删除"> + <i className="iconfont icon-shanchu color-grey-c font-15" onClick={()=>this.Deletcourses(key)}></i> + </a>} + <a className="newAddSubentry" title="添加" + style={{display:key===editcourse.length-1?"inline-block":'none'}} + ><i className="iconfont icon-tianjiafangda color-green" onClick={this.Addcourse}></i></a> + </div> + + </div> + + </div> + ) + }) + } + + </div> + <span className="c_red none ml35 color-red" id="error_tip" style={{display:Supportssum===true||Supportsclass===true?'inline':'none'}}>{Supportslist}</span> + <div className="clearfix editorModify"> <span className="column-1" - style={{ - width: '580px', - paddingLeft: '37px', - display: 'inline-block' - }} - >合计: <span>{editcourse.length}</span></span> - <span className="ml30">合计: <span>{editnum}</span></span> - </div> - - <div className="right editlybuttonbox"> - <div className="defalutSubmitbtn fr" onClick={this.SubmitClassData}>保存</div> - <div className="defalutCancelbtn fr mr20" onClick={this.CancelSupports}>取消</div> - </div> - - </p> - - + style={{ + width: '580px', + paddingLeft: '37px', + display: 'inline-block' + }} + >合计: <span>{editcourse.length}</span></span> + <span className="ml30">合计: <span>{editnum}</span></span> + </div> + + <div className="right editlybuttonbox"> + <div className="defalutSubmitbtn fr" onClick={this.SubmitClassData}>保存</div> + <div className="defalutCancelbtn fr mr20" onClick={this.CancelSupports}>取消</div> + </div> + </div> + </p>:""} </li> ) }) diff --git a/public/react/src/modules/home/shixunsHome.js b/public/react/src/modules/home/shixunsHome.js index 5677193d5..bad776b89 100644 --- a/public/react/src/modules/home/shixunsHome.js +++ b/public/react/src/modules/home/shixunsHome.js @@ -14,13 +14,7 @@ import UpgradeModals from '../modals/UpgradeModals'; import { SnackbarHOC , getImageUrl, configShareForIndex} from 'educoder'; -import Slider from '@icedesign/base/lib/slider'; - -import '@icedesign/base/lib/slider/style.js'; - -import Rating from '@icedesign/base/lib/rating'; - -import '@icedesign/base/lib/rating/style.js'; +import { Slider ,Rating} from "@icedesign/base"; import './home.css'; @@ -115,7 +109,15 @@ class ShixunsHome extends Component { homedatalistreps.push(homedatalist.reps[homedatalist.reps.length-i-1]) } } - + const MyRate = ({ defaultValue, ...rest }) => { + let myValue = defaultValue; + console.log(myValue-Math.floor(myValue)) + // if (myValue < Math.ceil(myValue)) { + // myValue = Math.floor(myValue) + 0.5; + // } + + return <Rating {...rest} value={myValue} />; + }; return ( <div className="newMain clearfix backFAFAFA shixunsHome"> {this.state.updata===undefined?"":<UpgradeModals @@ -349,7 +351,7 @@ class ShixunsHome extends Component { <p className="clearfix mt8 ml-3"> <span className="rateYoStar fl" style={{padding: '0px',height: '20px',lineHeight: '19px',cursor: 'default'}} title=""> - <Rating key={key} value={item.score_info===null?5:item.score_info} disabled allowHalf /> + <MyRate key={key} allowHalf defaultValue={item.score_info===null?5:item.score_info} disabled/> </span> <span className="fl ml25 font-12 color-grey-9 lineh-12 mt4">{item.score_info===null?"5分":item.score_info+"分"}</span> </p> diff --git a/public/react/src/modules/page/VNCContainer.js b/public/react/src/modules/page/VNCContainer.js index 3a85976bb..6ef10888a 100644 --- a/public/react/src/modules/page/VNCContainer.js +++ b/public/react/src/modules/page/VNCContainer.js @@ -85,7 +85,7 @@ class VNCContainer extends Component { }) } onTreeSelect = (selectedKeys, info) => { - const isLeaf = info.node.props.isLeaf; + const isLeaf = info.node.isLeaf(); if (isLeaf) { // 叶子节点 selectedKeys.length && this.setState({ fileTreeSelectedKeys: selectedKeys diff --git a/public/react/src/modules/page/component/repo/RepoTree.js b/public/react/src/modules/page/component/repo/RepoTree.js index fbf1286c3..102f797ef 100644 --- a/public/react/src/modules/page/component/repo/RepoTree.js +++ b/public/react/src/modules/page/component/repo/RepoTree.js @@ -7,7 +7,7 @@ import 'rc-tree/assets/index.css'; const $ = window.$; export default function RepoTree(props) { - const { fileTreeData, onLoadData, onTreeSelect, fileTreeSelectedKeys, loadRepoFiles } = props; + const { fileTreeData, onLoadData, fileTreeSelectedKeys, loadRepoFiles } = props; const [expandedKeys, setExpandedKeys] = useState([]) useEffect(() => { loadRepoFiles() @@ -36,7 +36,19 @@ export default function RepoTree(props) { }; const treeNodes = loop(fileTreeData); - + function onTreeSelect(selectedKeys, info) { + if (!info.node.isLeaf()) { + const _expandedKeys = expandedKeys.slice(0) + const _index = _expandedKeys.indexOf(selectedKeys[0]); + if (_index == -1) { + _expandedKeys.push(selectedKeys[0]) + } else { + _expandedKeys.splice( _index, 1) + } + setExpandedKeys( _expandedKeys ) + } + props.onTreeSelect(selectedKeys, info) + } // selectable={false} return ( <Tree diff --git a/public/react/src/modules/page/main/CodeRepositoryView.css b/public/react/src/modules/page/main/CodeRepositoryView.css index 1ed76a02f..b0f8eb939 100644 --- a/public/react/src/modules/page/main/CodeRepositoryView.css +++ b/public/react/src/modules/page/main/CodeRepositoryView.css @@ -147,4 +147,8 @@ } .xterm .xterm-viewport { overflow-y: auto !important; +} + +.repoFilesDrawer .rc-tree { + user-select: none; } \ No newline at end of file diff --git a/public/react/src/modules/page/main/CodeRepositoryView.js b/public/react/src/modules/page/main/CodeRepositoryView.js index 6da34c541..fc10a31dd 100644 --- a/public/react/src/modules/page/main/CodeRepositoryView.js +++ b/public/react/src/modules/page/main/CodeRepositoryView.js @@ -65,6 +65,7 @@ class CodeRepositoryView extends Component { expandedKeys.push( index === 0 ? item : expandedKeys[index - 1] + '/' + item) }) } + expandedKeys.length = 1 // 没办法做到多级初始化 // 初始化时无法展开到根节点 https://github.com/fis-components/rc-tree/issues/3 expandedKeys.length && this.setState({ expandedKeys, @@ -110,10 +111,23 @@ class CodeRepositoryView extends Component { // $('#codetab_con_1 .codemirrorBackground').hide() } - + onTreeSelect = (selectedKeys, info) => { + if (!info.node.isLeaf()) { + const expandedKeys = this.state.expandedKeys.slice(0) + const _index = expandedKeys.indexOf(selectedKeys[0]); + if (_index == -1) { + expandedKeys.push(selectedKeys[0]) + } else { + expandedKeys.splice( _index, 1) + } + this.setState({ expandedKeys }) + } + + this.props.onTreeSelect(selectedKeys, info) + } buildTree() { // TODO http://localhost:3007/tasks/xgffnuomytpj 这个实训没有文件树 - const { fileTreeData, onLoadData, onTreeSelect, fileTreeSelectedKeys } = this.props; + const { fileTreeData, onLoadData, fileTreeSelectedKeys } = this.props; if (!fileTreeData || fileTreeData.length === 0) { return "" } @@ -136,7 +150,7 @@ class CodeRepositoryView extends Component { return ( <Tree selectedKeys={fileTreeSelectedKeys} - onSelect={onTreeSelect} + onSelect={this.onTreeSelect} onExpand={this.onExpand} expandedKeys={this.state ? this.state.expandedKeys : []} autoExpandParent={this.state.autoExpandParent} diff --git a/public/react/src/modules/page/main/CodeRepositoryViewContainer.js b/public/react/src/modules/page/main/CodeRepositoryViewContainer.js index 111ccd253..b4d9c4fcf 100644 --- a/public/react/src/modules/page/main/CodeRepositoryViewContainer.js +++ b/public/react/src/modules/page/main/CodeRepositoryViewContainer.js @@ -223,7 +223,7 @@ class CodeRepositoryViewContainer extends Component { }); } onTreeSelect = (selectedKeys, info) => { - const isLeaf = info.node.props.isLeaf; + const isLeaf = info.node.isLeaf(); if (isLeaf) { // 叶子节点 selectedKeys.length && this.setState({ fileTreeSelectedKeys: selectedKeys diff --git a/public/react/src/modules/tpm/TPMBanner.js b/public/react/src/modules/tpm/TPMBanner.js index 997786db2..7b094a642 100644 --- a/public/react/src/modules/tpm/TPMBanner.js +++ b/public/react/src/modules/tpm/TPMBanner.js @@ -6,7 +6,9 @@ import {BrowserRouter as Router, Route, Link, Switch} from "react-router-dom"; import PropTypes from 'prop-types'; -import {Modal,Input,Radio,Pagination,message,Spin,Icon,Tooltip} from 'antd'; +import { Rating ,Progress} from "@icedesign/base"; + +import {Modal,Input,Radio,Pagination,message,Spin,Icon,Tooltip,Rate} from 'antd'; import AccountProfile from"../user/AccountProfile"; @@ -16,17 +18,6 @@ import axios from 'axios' import Modals from '../modals/Modals'; -// import { Rating,Progress } from '@icedesign/base'; - -import Rating from '@icedesign/base/lib/rating'; - -import Progress from '@icedesign/base/lib/progress'; - -// 引入业务组件样式 -import '@icedesign/base/lib/rating/style.js'; - -import '@icedesign/base/lib/progress/style.js'; - import './shixuns/css/TPMBanner.css'; let $ = window.$; @@ -578,6 +569,15 @@ class TPMBanner extends Component { }; const antIcon = <Icon type="loading" style={{ fontSize: 24 }} spin />; + const MyRate = ({ defaultValue, ...rest }) => { + let myValue = defaultValue; + console.log(myValue-Math.floor(myValue)) + // if (myValue < Math.ceil(myValue)) { + // myValue = Math.floor(myValue) + 0.5; + // } + + return <Rating {...rest} value={myValue} />; + }; return ( shixunsDetails===undefined?"": @@ -616,7 +616,22 @@ class TPMBanner extends Component { </p> <div className="clearfix mt50"> - <ul className="fl color-grey-c pathInfo"> + {/*<style>*/} + {/*{*/} + {/*`*/} + {/*.anticon-star{*/} + {/*font-size:14px;*/} + {/*}*/} + {/*.pathInfo{*/} + {/*margin-right:-5px;*/} + {/*}*/} + {/*.ant-rate{*/} + {/*color: #FFA800;*/} + {/*}*/} + {/*`*/} + {/*}*/} + {/*</style>*/} + <ul className="fl color-grey-c pathInfo" > <li> <span>学习人数</span> <span className="mt10">{shixunsDetails.stu_num}</span> @@ -633,11 +648,11 @@ class TPMBanner extends Component { </ul> <div className="pr fl" id="commentsStar" onMouseOver={()=>this.showonMouseOver()} onMouseOut={()=>this.hideonMouseOut()}> - <div className={"color-grey-c mb11"} style={{color: "#Fff",textAlign: "center"}}>学员评分</div> + <div className={"color-grey-c ml15"} style={{color: "#Fff",textAlign: "center"}}>学员评分</div> <div className="rateYo"> - <Rating value={star_info[0]} disabled allowHalf/> + <MyRate allowHalf defaultValue={star_info[0]} disabled/> </div> - <div id="ratePanel" className="showratePanel" style={{"width":"512px"}} onMouseOut={()=>this.hideonMouseOut()}> + <div id="ratePanel" className="showratePanel" style={{"width":"530px"}} onMouseOut={()=>this.hideonMouseOut()}> <div className="pr"> <span className="rateTrangle"></span> <div className="pr clearfix ratePanelContent" style={{height: '177px'}}> @@ -648,16 +663,16 @@ class TPMBanner extends Component { <span className="displayblock">总评分</span> <div className="rateYo"> {showradios === true ? - <Rating value={star_info[0]} allowHalf/> + <MyRate allowHalf defaultValue={star_info[0]} disabled/> : ""} </div> </div> </div> - <div className="fr width360"> + <div className="fr"> <div className="clearfix"> <div className="rateYo fl mt3"> {showradios === true ? - <Rating value={5} disabled allowHalf/> + <MyRate allowHalf defaultValue={5} disabled/> : ""} </div> <Progress percent={star_infos[1]} showInfo={false}></Progress> @@ -666,7 +681,7 @@ class TPMBanner extends Component { <div className="clearfix"> <div className="rateYo fl mt3"> {showradios === true ? - <Rating value={4} disabled allowHalf/> + <MyRate allowHalf defaultValue={4} disabled/> : ""} </div> <Progress percent={star_infos[2]} showInfo={false}></Progress> @@ -675,7 +690,7 @@ class TPMBanner extends Component { <div className="clearfix"> <div className="rateYo fl mt3"> {showradios === true ? - <Rating value={3} disabled allowHalf/> + <MyRate allowHalf defaultValue={3} disabled/> : ""} </div> <Progress percent={star_infos[3]} showInfo={false}></Progress> @@ -684,7 +699,7 @@ class TPMBanner extends Component { <div className="clearfix"> <div className="rateYo fl mt3"> {showradios === true ? - <Rating value={2} disabled allowHalf/> + <MyRate allowHalf defaultValue={2} disabled/> : ""} </div> <Progress percent={star_infos[4]} showInfo={false}></Progress> @@ -693,7 +708,7 @@ class TPMBanner extends Component { <div className="clearfix"> <div className="rateYo fl mt3"> {showradios === true ? - <Rating value={1} disabled allowHalf/> + <MyRate allowHalf defaultValue={1} disabled/> : ""} </div> <Progress percent={star_infos[5]} showInfo={false}></Progress> diff --git a/public/react/src/modules/tpm/TPMFork/TPMForklist.js b/public/react/src/modules/tpm/TPMFork/TPMForklist.js index bbe3509a6..8cb5d2378 100644 --- a/public/react/src/modules/tpm/TPMFork/TPMForklist.js +++ b/public/react/src/modules/tpm/TPMFork/TPMForklist.js @@ -6,7 +6,7 @@ import {BrowserRouter as Router, Route, Link, Switch} from "react-router-dom"; // import "antd/dist/antd.css"; -import Rating from '@icedesign/base/lib/rating'; +import { Rating } from "@icedesign/base"; import axios from 'axios'; @@ -88,7 +88,15 @@ export default class TPMFork_listComponent extends Component { let {shixuns, total_count, shixunsID, Forkvisible, Forkcurrent} = this.state; + const MyRate = ({ defaultValue, ...rest }) => { + let myValue = defaultValue; + console.log(myValue-Math.floor(myValue)) + // if (myValue < Math.ceil(myValue)) { + // myValue = Math.floor(myValue) + 0.5; + // } + return <Rating {...rest} value={myValue} />; + }; return ( <React.Fragment> <div className="educontent mb20"> @@ -141,9 +149,9 @@ export default class TPMFork_listComponent extends Component { </p> <p className="clearfix mt8 ml-3"> - <span className="rateYoStar fl" style={{padding: '0px',height: '20px',lineHeight: '19px',cursor: 'default'}} title=""> - <Rating key={key} value={item.score_info===null?5:item.score_info} disabled allowHalf /> - </span> + <span className="rateYoStar fl" style={{padding: '0px',height: '20px',lineHeight: '19px',cursor: 'default'}} title=""> + <MyRate key={key} allowHalf defaultValue={item.score_info===null?5:item.score_info} disabled/> + </span> <span className="fl ml25 font-12 color-grey-9 lineh-12 mt4">{item.score_info===null?"5分":item.score_info+"分"}</span> </p> diff --git a/public/react/src/modules/tpm/TPMShixunDiscuss.css b/public/react/src/modules/tpm/TPMShixunDiscuss.css index 6006b3f30..3af4ec269 100644 --- a/public/react/src/modules/tpm/TPMShixunDiscuss.css +++ b/public/react/src/modules/tpm/TPMShixunDiscuss.css @@ -1,47 +1,47 @@ -.tpmComment .-fit { - position: inherit; -} -.tpmComment .rc-pagination { - margin-left: auto; - margin-right: auto; - margin-top: 12px; - margin-bottom: 20px; -} -.tpmComment .paginationSection { - background: #FAFAFA; -} -.tpmComment .comment_item_cont.df.clearfix:nth-last-child(1) { - border-bottom: none; -} - -/*.tpmComment .fl.edu-back-white {*/ -/*min-height: 600px;*/ -/*}*/ - - -.user_watch_btn { - cursor: pointer; -} - - -/*md编辑器*/ -.tpmComment .commentItemMDEditor a.task-btn { - background: #4cacff!important; - margin-right: 16px; - margin-top: 16px; -} -/* md编辑器 resizeBar*/ - .tpmComment .commentItemMDEditor .editor__resize { - transform: translateX(-176%) -} - -#ratePanel > div > div > div.fr div.rateYo.fl.mt3 { - height: 20px; - line-height: 20px; - cursor: default; - width: 90px; -} - -.tpmComment .icon-jiangli { - /* margin-top: 2px; */ +.tpmComment .-fit { + position: inherit; +} +.tpmComment .rc-pagination { + margin-left: auto; + margin-right: auto; + margin-top: 12px; + margin-bottom: 20px; +} +.tpmComment .paginationSection { + background: #FAFAFA; +} +.tpmComment .comment_item_cont.df.clearfix:nth-last-child(1) { + border-bottom: none; +} + +/*.tpmComment .fl.edu-back-white {*/ +/*min-height: 600px;*/ +/*}*/ + + +.user_watch_btn { + cursor: pointer; +} + + +/*md编辑器*/ +.tpmComment .commentItemMDEditor a.task-btn { + background: #4cacff!important; + margin-right: 16px; + margin-top: 16px; +} +/* md编辑器 resizeBar*/ + .tpmComment .commentItemMDEditor .editor__resize { + transform: translateX(-176%) +} + +#ratePanel > div > div > div.fr div.rateYo.fl.mt3 { + height: 20px; + line-height: 20px; + cursor: default; + width: 110px; +} + +.tpmComment .icon-jiangli { + /* margin-top: 2px; */ } \ No newline at end of file diff --git a/public/react/src/modules/tpm/shixuns/ShixunCard.js b/public/react/src/modules/tpm/shixuns/ShixunCard.js index 3a0935e66..021185cc8 100644 --- a/public/react/src/modules/tpm/shixuns/ShixunCard.js +++ b/public/react/src/modules/tpm/shixuns/ShixunCard.js @@ -7,24 +7,15 @@ import PropTypes from 'prop-types'; import classNames from 'classnames'; -import {getImageUrl,setImagesUrl, toPath} from 'educoder'; +import { Rating ,Pagination} from "@icedesign/base"; -import { Spin,Icon } from 'antd'; +import {getImageUrl,setImagesUrl, toPath} from 'educoder'; -import 'antd/lib/pagination/style/index.css'; +import { Spin,Icon,Tooltip ,Rate} from 'antd'; import './shixunCss/shixunCard.css'; -import Rating from '@icedesign/base/lib/rating'; - -import Pagination from '@icedesign/base/lib/pagination'; - // 引入业务组件样式 -import '@icedesign/base/lib/pagination/style.js'; - -import '@icedesign/base/lib/rating/style.js'; - -import { Tooltip } from 'antd'; import axios from 'axios'; @@ -55,6 +46,15 @@ class ShixunCard extends Component { render() { let {middleshixundata, pagination, typepvisible, pages, totalcount} = this.props; + const MyRate = ({ defaultValue, ...rest }) => { + let myValue = defaultValue; + console.log(myValue-Math.floor(myValue)) + // if (myValue < Math.ceil(myValue)) { + // myValue = Math.floor(myValue) + 0.5; + // } + + return <Rating {...rest} value={myValue} />; + }; return ( <div className="educontent mb80"> @@ -78,10 +78,11 @@ class ShixunCard extends Component { </div> <div className="mt10 mb20 clearfix" - style={{display: middleshixundata === undefined || middleshixundata.length === 0 ? "none" : "block"}}> + // style={{display: middleshixundata === undefined || middleshixundata.length === 0 ? "none" : "block"}} + > <div className="shixun_list_content"> <div className="square-list clearfix"> - { middleshixundata===undefined?" ":middleshixundata.map((item,key)=>{ + {middleshixundata === undefined || middleshixundata.length === 0?" ":middleshixundata.map((item,key)=>{ return( <div className="square-Item" key={key} id={item.id}> <style> @@ -122,12 +123,27 @@ class ShixunCard extends Component { </p> {/*target="_blank"*/} - + {/*<style>*/} + {/*{*/} + {/*`*/} + {/*.anticon-star{*/} + {/*font-size:16px;*/} + {/*}*/} + {/*.pathInfo{*/} + {/*margin-right:-5px;*/} + {/*}*/} + {/*.ant-rate{*/} + {/*color: #FFA800;*/} + {/*}*/} + {/*`*/} + {/*}*/} + {/*</style>*/} <p className="clearfix mt8 ml-3"> <span className="rateYoStar fl" style={{padding: '0px',height: '20px',lineHeight: '19px',cursor: 'default'}} title=""> - <Rating key={key} value={item.score_info===null?5:item.score_info} disabled allowHalf /> + {/*<Rate allowHalf value={item.score_info===null?5:item.score_info} disabled key={key} />*/} + <MyRate key={key} allowHalf defaultValue={item.score_info===null?5:item.score_info} disabled/> </span> - <span className="fl ml25 font-12 color-grey-9 lineh-12 mt4">{item.score_info===null?"5分":item.score_info+"分"}</span> + <span className="fl ml25 font-12 color-grey-9 lineh-12 mt5">{item.score_info===null?"5分":item.score_info+"分"}</span> </p> <p className="clearfix mt8 font-12 color-grey-B4"> diff --git a/public/react/src/modules/tpm/shixuns/css/TPMBanner.css b/public/react/src/modules/tpm/shixuns/css/TPMBanner.css index a6a7acc9a..fe059fccd 100644 --- a/public/react/src/modules/tpm/shixuns/css/TPMBanner.css +++ b/public/react/src/modules/tpm/shixuns/css/TPMBanner.css @@ -8,7 +8,7 @@ .rateYo{ text-align: center; cursor: default; - width: 90px; + width: 111px; } a:link, a:visited { diff --git a/public/stylesheets/educoder/edu-all.css b/public/stylesheets/educoder/edu-all.css index 91ea604d4..c20b648db 100644 --- a/public/stylesheets/educoder/edu-all.css +++ b/public/stylesheets/educoder/edu-all.css @@ -3051,7 +3051,7 @@ a.singlepublishtwo{ /*工程认证*/ /*首页*/ .authMainImg{width: 100%;height: 240px;background:url("/images/educoder/auth/banner1.jpg") no-repeat top center;background-size: 100% 100%;justify-content: center;align-items: center;display: -webkit-flex;} -.ListTableLine>p,.ListTableLine>.ListTableTitle{padding: 0px 30px;background-color: #F5F5F5;line-height: 40px;height: 56px;padding-top: 8px;box-sizing: border-box;} +.ListTableLine>p,.ListTableLine>.ListTableTitle{margin-bottom: 0px;padding: 0px 30px;background-color: #F5F5F5;line-height: 40px;height: 56px;padding-top: 8px;box-sizing: border-box;} .ListTableLine>p span,.ListTableTitle span{float: left;color: #666;box-sizing: border-box} .ListTableLine li{min-height: 48px;padding: 10px 0px;box-sizing: border-box;margin:0px 30px;border-bottom: 1px solid #eaeaea;} .ListTableLine li>span{float: left;box-sizing: border-box;}