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/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/graduation_tasks_controller.rb b/app/controllers/graduation_tasks_controller.rb index 841b516bb..de48f9fdb 100644 --- a/app/controllers/graduation_tasks_controller.rb +++ b/app/controllers/graduation_tasks_controller.rb @@ -168,7 +168,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/controllers/subjects_controller.rb b/app/controllers/subjects_controller.rb index 36f14a5d5..ba9b13f85 100644 --- a/app/controllers/subjects_controller.rb +++ b/app/controllers/subjects_controller.rb @@ -368,7 +368,7 @@ class SubjectsController < ApplicationController @schools.map do |s| school_courses = Course.where(id: course_ids, school_id: s.id) course_count = school_courses.count - student_count = StudentsForCourse.where(course_id: school_courses.pluck(:id)).count + student_count = CourseMember.where(course_id: school_courses.pluck(:id), role: 4).count homework_count = HomeworkCommon.find_by_sql("select count(*) cnt from homework_commons hc join courses c on hc.course_id = c.id where c.school_id = #{s.id} and hc.id in(#{homework_common_id})").first.try(:cnt) s.attributes.dup.merge({name: s.name, course_count: course_count, student_count: student_count,homework_count: homework_count}) diff --git a/app/models/graduation_work.rb b/app/models/graduation_work.rb index 235bfcac6..c7420ffef 100644 --- a/app/models/graduation_work.rb +++ b/app/models/graduation_work.rb @@ -48,7 +48,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 9c9efa17c..b4ad834de 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/user.rb b/app/models/user.rb index ebf68cce6..1dc511513 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/services/users/apply_professional_auth_service.rb b/app/services/users/apply_professional_auth_service.rb index 3ba9fbafd..74ee08c85 100644 --- a/app/services/users/apply_professional_auth_service.rb +++ b/app/services/users/apply_professional_auth_service.rb @@ -40,8 +40,8 @@ class Users::ApplyProfessionalAuthService < ApplicationService # sms_cache = Rails.cache.read("apply_pro_certification") # if sms_cache.nil? - # sms_notify_admin - Rails.cache.write("apply_pro_certification", 1) + sms_notify_admin + # Rails.cache.write("apply_pro_certification", 1) # end end end 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 @@
'+(n?e:a(e,!0))+"
\n":""+(n?e:a(e,!0))+"
"},i.prototype.blockquote=function(e){return"\n"+e+"\n"},i.prototype.html=function(e){return e},i.prototype.heading=function(e,t,n){return this.options.headerIds?"
"+e+"
\n"},i.prototype.table=function(e,t){return t&&(t=""+t+""),""+e+"
"},i.prototype.br=function(){return this.options.xhtml?""+a(e.message+"",!0)+"";throw e}}d.exec=d,m.options=m.setOptions=function(e){return f(m.defaults,e),m},m.getDefaults=function(){return{baseUrl:null,breaks:!1,gfm:!0,headerIds:!0,headerPrefix:"",highlight:null,langPrefix:"language-",mangle:!0,pedantic:!1,renderer:new i,sanitize:!1,sanitizer:null,silent:!1,smartLists:!1,smartypants:!1,tables:!0,xhtml:!1}},m.defaults=m.getDefaults(),m.Parser=o,m.parser=o.parse,m.Renderer=i,m.TextRenderer=l,m.Lexer=n,m.lexer=n.lex,m.InlineLexer=s,m.inlineLexer=s.output,m.parse=m,"undefined"!=typeof module&&"object"==typeof exports?module.exports=m:"function"==typeof define&&define.amd?define(function(){return m}):e.marked=m}(this||("undefined"!=typeof window?window:global)); +// b(i[1].replace(/^ *| *\| *$/g,"")) --> i[1].replace(/^ *| *\| *$/g, "").split(/ *\| */) table没识别的问题 +// header.length===a.align.length --> header.length table没识别的问题 a.header.length -> a.cells[p].split('|').length - 2 +!function(e){"use strict";var t={newline:/^\n+/,code:/^( {4}[^\n]+\n*)+/,fences:d,hr:/^ {0,3}((?:- *){3,}|(?:_ *){3,}|(?:\* *){3,})(?:\n+|$)/,heading:/^ *(#{1,6})*([^\n]+?) *(?:#+ *)?(?:\n+|$)/,nptable:d,blockquote:/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,list:/^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,html:"^ {0,3}(?:<(script|pre|style)[\\s>][\\s\\S]*?(?:\\1>[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?\\?>\\n*|\\n*|\\n*|?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:\\n{2,}|$)|<(?!script|pre|style)([a-z][\\w-]*)(?:attribute)*? */?>(?=\\h*\\n)[\\s\\S]*?(?:\\n{2,}|$)|(?!script|pre|style)[a-z][\\w-]*\\s*>(?=\\h*\\n)[\\s\\S]*?(?:\\n{2,}|$))",def:/^ {0,3}\[(label)\]: *\n? *([^\s>]+)>?(?:(?: +\n? *| *\n *)(title))? *(?:\n+|$)/,table:d,lheading:/^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,paragraph:/^([^\n]+(?:\n(?!hr|heading|lheading| {0,3}>|<\/?(?:tag)(?: +|\n|\/?>)|<(?:script|pre|style|!--))[^\n]+)*)/,text:/^[^\n]+/};function n(e){this.tokens=[],this.tokens.links={},this.options=e||m.defaults,this.rules=t.normal,this.options.pedantic?this.rules=t.pedantic:this.options.gfm&&(this.options.tables?this.rules=t.tables:this.rules=t.gfm)}t._label=/(?!\s*\])(?:\\[\[\]]|[^\[\]])+/,t._title=/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/,t.def=p(t.def).replace("label",t._label).replace("title",t._title).getRegex(),t.bullet=/(?:[*+-]|\d+\.)/,t.item=/^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/,t.item=p(t.item,"gm").replace(/bull/g,t.bullet).getRegex(),t.list=p(t.list).replace(/bull/g,t.bullet).replace("hr","\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))").replace("def","\\n+(?="+t.def.source+")").getRegex(),t._tag="address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",t._comment=//,t.html=p(t.html,"i").replace("comment",t._comment).replace("tag",t._tag).replace("attribute",/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),t.paragraph=p(t.paragraph).replace("hr",t.hr).replace("heading",t.heading).replace("lheading",t.lheading).replace("tag",t._tag).getRegex(),t.blockquote=p(t.blockquote).replace("paragraph",t.paragraph).getRegex(),t.normal=f({},t),t.gfm=f({},t.normal,{fences:/^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]*?)\n? *\1 *(?:\n+|$)/,paragraph:/^/,heading:/^ *(#{1,6})+([^\n]+?) *#* *(?:\n+|$)/}),t.gfm.paragraph=p(t.paragraph).replace("(?!","(?!"+t.gfm.fences.source.replace("\\1","\\2")+"|"+t.list.source.replace("\\1","\\3")+"|").getRegex(),t.tables=f({},t.gfm,{nptable:/^ *([^|\n ].*\|.*)\n *([-:]+ *\|[-| :]*)(?:\n((?:.*[^>\n ].*(?:\n|$))*)\n*|$)/,table:/^ *\|(.+)\n *\|?( *[-:]+[-| :]*)(?:\n((?: *[^>\n ].*(?:\n|$))*)\n*|$)/}),t.pedantic=f({},t.normal,{html:p("^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?\\1> *(?:\\n{2,}|\\s*$)|
'+(n?e:a(e,!0))+"
\n":""+(n?e:a(e,!0))+"
"},i.prototype.blockquote=function(e){return"\n"+e+"\n"},i.prototype.html=function(e){return e},i.prototype.heading=function(e,t,n){return this.options.headerIds?"
"+e+"
\n"},i.prototype.table=function(e,t){return t&&(t=""+t+""),""+e+"
"},i.prototype.br=function(){return this.options.xhtml?""+a(e.message+"",!0)+"";throw e}}d.exec=d,m.options=m.setOptions=function(e){return f(m.defaults,e),m},m.getDefaults=function(){return{baseUrl:null,breaks:!1,gfm:!0,headerIds:!0,headerPrefix:"",highlight:null,langPrefix:"language-",mangle:!0,pedantic:!1,renderer:new i,sanitize:!1,sanitizer:null,silent:!1,smartLists:!1,smartypants:!1,tables:!0,xhtml:!1}},m.defaults=m.getDefaults(),m.Parser=o,m.parser=o.parse,m.Renderer=i,m.TextRenderer=l,m.Lexer=n,m.lexer=n.lex,m.InlineLexer=s,m.inlineLexer=s.output,m.parse=m,"undefined"!=typeof module&&"object"==typeof exports?module.exports=m:"function"==typeof define&&define.amd?define(function(){return m}):e.marked=m}(this||("undefined"!=typeof window?window:global)); diff --git a/public/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/package.json b/public/react/package.json index e91e61f03..4d899935f 100644 --- a/public/react/package.json +++ b/public/react/package.json @@ -3,7 +3,7 @@ "version": "0.1.0", "private": true, "dependencies": { - "@icedesign/base": "^0.2.5", + "@icedesign/base": "^0.2.8", "@novnc/novnc": "^1.1.0", "antd": "^3.23.2", "array-flatten": "^2.1.2", diff --git a/public/react/public/index.html b/public/react/public/index.html index 4fd2c4356..a2d09dedc 100755 --- a/public/react/public/index.html +++ b/public/react/public/index.html @@ -5,10 +5,9 @@ - + + +