Merge branch 'develop' into gitlab_guange

gitlab_guange
huang 10 years ago
commit 0fe68563dd

@ -30,11 +30,21 @@ gem 'rails_kindeditor',path:'lib/rails_kindeditor'
#gem "rmagick", ">= 2.0.0"
gem 'binding_of_caller'
gem 'chinese_pinyin'
# gem 'sunspot_rails', '~> 1.3.3'
# gem 'sunspot_solr'
# gem 'sunspot'
# gem 'progress_bar'
gem 'ansi'
gem 'kaminari'
gem 'elasticsearch-model'
gem 'elasticsearch-rails'
group :development do
gem 'grape-swagger'
gem 'better_errors', '~> 1.1.0'
gem 'rack-mini-profiler', '~> 0.9.3'
gem 'win32console'
end
group :development, :test do

@ -1367,7 +1367,7 @@ class UsersController < ApplicationController
end
end
if(params[:type].blank? || params[:type] == "1") #全部
if(params[:type].nil? || params[:type].blank? || params[:type] == "1" || params[:type] == 'all') #全部
if User.current.id.to_i == params[:id].to_i
user_course_ids = User.current.courses.map { |c| c.id} #我的资源库的话,那么应该是我上传的所有资源 加上 我加入的课程的所有资源
@attachments = Attachment.where("(author_id = #{params[:id]} and container_type in('Project','Principal','Course','Issue','Document','Message','News','StudentWorkScore','HomewCommon')) "+
@ -1856,7 +1856,7 @@ class UsersController < ApplicationController
# 根据资源关键字进行搜索
def resource_search
search = params[:search].to_s.strip.downcase
if(params[:type].nil? || params[:type] == "1") #全部
if(params[:type].nil? || params[:type].blank? || params[:type] == "1" || params[:type] == 'all') #全部
if User.current.id.to_i == params[:id].to_i
user_course_ids = User.current.courses.map { |c| c.id} #我的资源库的话,那么应该是我上传的所有资源 加上 我加入的课程的所有资源 取交集并查询
@attachments = Attachment.where("((author_id = #{params[:id]} and container_type in('Project','Principal','Course','Issue','Document','Message','News','StudentWorkScore','HomewCommon')) "+

@ -151,36 +151,104 @@ class WelcomeController < ApplicationController
end
def search
search_condition = params[:q]
search_type = params[:search_type].to_sym unless search_condition.blank?
search_by = params[:search_by]
@name = params[:q]
@search_type = params[:search_type]
case params[:search_type]
when 'all'
@alls = Elasticsearch::Model.search({
query: {
multi_match: {
query: @name,
type:"most_fields",
operator: "or",
fields: ['login', 'firstname','lastname','name','description^0.5','filename']
}
},
highlight: {
pre_tags: ['<span class="c_red">'],
post_tags: ['</span>'],
fields: {
login: {},
firstname: {},
lastname: {},
name:{},
description:{},
filename:{}
}
}
},[User,Course,Attachment,Project] ).page(params[:page] || 1).per(20).results
when 'user'
@users = User.search(@name).page(params[:page] || 1).per(20)
when 'project'
@projects = Project.search(@name).page(params[:page] || 1).per(20).results
when 'course'
@courses = Course.search(@name).page(params[:page] || 1).per(20).results
when 'attachment'
@attachments = Attachment.search(@name).page(params[:page] || 1).per(20).results
else
@alls = Elasticsearch::Model.search({
query: {
multi_match: {
query: @name,
type:"most_fields",
operator: "or",
fields: ['login', 'firstname','lastname','name','description^0.5','filename']
}
},
highlight: {
pre_tags: ['<span class="c_red">'],
post_tags: ['</span>'],
fields: {
login: {},
firstname: {},
lastname: {},
name:{},
description:{},
filename:{}
}
}
},[User,Course,Attachment,Project] ).page(params[:page] || 1).per(20).results
if search_type.nil? && params[:contests_search] && params[:name] != ""
search_type = :contests
search_condition = params[:name]
end
@users_count = User.search(@name).results.total
@course_count = Course.search(@name).results.total
@attach_count = Attachment.search(@name).results.total
@project_count = Project.search(@name).results.total
@total_count = Elasticsearch::Model.search({
query: {
multi_match: {
query: @name,
type:"most_fields",
operator: "or",
fields: ['login', 'firstname','lastname','name','description^0.5','filename']
}
},
highlight: {
pre_tags: ['<span class="c_red">'],
post_tags: ['</span>'],
fields: {
login: {},
firstname: {},
lastname: {},
name:{},
description:{},
filename:{}
}
}
},[User,Course,Attachment,Project] ).results.total
# search_type = params[:search_type].to_sym unless search_condition.blank?
# search_by = params[:search_by]
#
# if search_type.nil? && params[:contests_search] && params[:name] != ""
# search_type = :contests
# search_condition = params[:name]
# end
respond_to do |format|
format.html{
case search_type
when :projects
redirect_to projects_search_url(:name => search_condition,
:project_type => Project::ProjectType_project)
when :courses
redirect_to courses_search_url(:name => search_condition)
when :contests
redirect_to contests_url(:name => search_condition)
when :users
redirect_to users_search_url(:name => search_condition,:search_by => search_by)
when :users_teacher
redirect_to users_search_url(:name => search_condition, :search_by => search_by, :role => :teacher)
when :users_student
redirect_to users_search_url(:name => search_condition, :search_by => search_by, :role => :student)
else
#redirect_to home_path, :alert => l(:label_sumbit_empty)
(redirect_to signin_path, :notice => l(:label_sumbit_empty);return) #if params[:name].blank?
end
}
format.js
format.html{ render :layout=>'users_base'}
end
end

@ -1869,6 +1869,23 @@ module ApplicationHelper
s
end
def get_user_identity identity
s = ""
case identity
when 0
s = '教师'
when 1
s = '学生'
when 2
s = '组织'
when 3
s= '开发者'
else
s = '学生'
end
s
end
def get_memo
@new_memo = Memo.new
@public_forum = Forum.find(1) rescue ActiveRecord::RecordNotFound

@ -17,7 +17,7 @@
require "digest/md5"
require "fileutils"
require 'elasticsearch/model'
class Attachment < ActiveRecord::Base
belongs_to :container, :polymorphic => true
belongs_to :project, foreign_key: 'container_id', conditions: "attachments.container_type = 'Project'"
@ -38,6 +38,18 @@ class Attachment < ActiveRecord::Base
validates :description, length: {maximum: 254}
validate :validate_max_file_size
#elasticsearch
include Elasticsearch::Model
#elasticsearch kaminari init
Kaminari::Hooks.init
Elasticsearch::Model::Response::Response.__send__ :include, Elasticsearch::Model::Response::Pagination::Kaminari
settings index: { number_of_shards: 1 } do
mappings dynamic: 'false' do
indexes :filename, analyzer: 'smartcn',index_options: 'offsets'
indexes :downloads, analyzer: 'smartcn',index_options: 'offsets'
end
end
acts_as_taggable
acts_as_event :title => :filename,
@ -74,9 +86,9 @@ class Attachment < ActiveRecord::Base
@@thumbnails_storage_path = File.join(Rails.root, "tmp", "thumbnails")
before_save :files_to_final_location,:act_as_course_activity
after_create :office_conver, :be_user_score,:act_as_forge_activity
after_update :office_conver, :be_user_score
after_destroy :delete_from_disk,:down_user_score
after_create :office_conver, :be_user_score,:act_as_forge_activity,:create_attachment_ealasticsearch_index
after_update :office_conver, :be_user_score,:update_attachment_ealasticsearch_index
after_destroy :delete_from_disk,:down_user_score,:delete_attachment_ealasticsearch_index
# add by nwb
# 获取所有可公开的资源文件列表
@ -92,7 +104,35 @@ class Attachment < ActiveRecord::Base
" LEFT JOIN #{News.table_name} ON #{Attachment.table_name}.container_type='News' AND (#{News.table_name}.project_id in "+self.public_project_id + " OR #{News.table_name}.course_id in " + self.public_course_id + ")" +
" LEFT JOIN #{HomeworkAttach.table_name} ON #{Attachment.table_name}.container_type='HomeworkAttach' AND #{HomeworkAttach.table_name}.bid_id in "+self.public_bid_id)
}
scope :indexable,lambda { where('is_public = 1 and ((container_type in ("Principal")) ' +
'or (container_type = "Course" and container_id in( SELECT `courses`.id FROM `courses` WHERE (courses.status <> 9 AND courses.is_public = 1)) )'+
'or (container_type = "Project" and container_id in(SELECT `projects`.id FROM `projects` WHERE (projects.status <> 9 AND projects.is_public = 1) ))' +')')} #用于elastic建索引的scope
def self.search(query)
__elasticsearch__.search(
{
query: {
multi_match: {
query: query,
type:"most_fields",
operator: "or",
fields: ['filename']
}
},
sort:{
_score:{order:"desc"},
downloads: {order:"desc"}
},
highlight: {
pre_tags: ['<span class="c_red">'],
post_tags: ['</span>'],
fields: {
filename: {}
}
}
}
)
end
# add by nwb
# 公开的项目id列表
def self.public_project_id
@ -561,4 +601,46 @@ class Attachment < ActiveRecord::Base
end
end
def create_attachment_ealasticsearch_index
if self.is_public == 1 && ( (self.container_type == 'Project' && Project.find(self.container_id).is_public == 1) ||
( self.container_type == 'Course' && Course.find(self.container_id).is_public == 1) ||
self.container_type == 'Principal')
self.__elasticsearch__.index_document
end
end
def update_attachment_ealasticsearch_index
if self.is_public == 1 && ( (self.container_type == 'Project' && Project.find(self.container_id).is_public == 1) ||
( self.container_type == 'Course' && Course.find(self.container_id).is_public == 1) ||
self.container_type == 'Principal')
begin
self.__elasticsearch__.update_document
rescue => e
end
else
begin
self.__elasticsearch__.delete_document
rescue => e
end
end
end
def delete_attachment_ealasticsearch_index
begin
self.__elasticsearch__.delete_document
rescue => e
end
end
end
# Delete the previous articles index in Elasticsearch
# Attachment.__elasticsearch__.client.indices.delete index: Attachment.index_name rescue nil
#
# # Create the new index with the new mapping
# Attachment.__elasticsearch__.client.indices.create \
# index: Attachment.index_name,
# body: { settings: Attachment.settings.to_hash, mappings: Attachment.mappings.to_hash }
# Index all article records from the DB to Elasticsearch
#暂时只做公开课程/项目里的公开资源 和其他的公开资源
#Attachment.where('is_public = 1 and ((container_type in ("Principal")) ' +
# 'or (container_type = "Course" and container_id in( SELECT `courses`.id FROM `courses` WHERE (courses.status <> 9 AND courses.is_public = 1)) )'+
# 'or (container_type = "Project" and container_id in(SELECT `projects`.id FROM `projects` WHERE (projects.status <> 9 AND projects.is_public = 1) ))' +')').import :force=>true

@ -17,8 +17,8 @@
class Board < ActiveRecord::Base
include Redmine::SafeAttributes
belongs_to :project
belongs_to :course
belongs_to :project,:touch => true
belongs_to :course,:touch=>true
has_many :topics, :class_name => 'Message', :conditions => "#{Message.table_name}.parent_id IS NULL", :order => "#{Message.table_name}.created_on DESC"
has_many :messages, :dependent => :destroy, :order => "#{Message.table_name}.created_on DESC"
belongs_to :last_message, :class_name => 'Message', :foreign_key => :last_message_id

@ -31,7 +31,7 @@ class Comment < ActiveRecord::Base
:title=>Proc.new {|o| "RE: #{o.commented.title}" },
:url => Proc.new {|o| {:controller => 'news', :action => 'show', :id => o.commented.id} }
belongs_to :commented, :polymorphic => true, :counter_cache => true
belongs_to :commented, :polymorphic => true, :counter_cache => true,:touch => true
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
validates_presence_of :commented, :author, :comments
safe_attributes 'comments'
@ -81,8 +81,10 @@ class Comment < ActiveRecord::Base
# 课程成员得分(英雄榜)
def act_as_student_score
unless self.author.allowed_to?(:as_teacher, self.commented.course)
course_member_score(self.commented.course.id, self.author_id, "NewReply")
if self.commented.course
unless self.author.allowed_to?(:as_teacher, self.commented.course)
course_member_score(self.commented.course.id, self.author_id, "NewReply")
end
end
end

@ -1,10 +1,24 @@
require 'elasticsearch/model'
class Course < ActiveRecord::Base
include Redmine::SafeAttributes
STATUS_ACTIVE = 1
STATUS_CLOSED = 5
STATUS_ARCHIVED = 9
#elasticsearch
include Elasticsearch::Model
#elasticsearch kaminari init
Kaminari::Hooks.init
Elasticsearch::Model::Response::Response.__send__ :include, Elasticsearch::Model::Response::Pagination::Kaminari
settings index: { number_of_shards: 1 } do
mappings dynamic: 'false' do
indexes :name, analyzer: 'smartcn',index_options: 'offsets'
indexes :description, analyzer: 'smartcn',index_options: 'offsets'
indexes :updated_at, analyzer: 'smartcn',index_options: 'offsets',type:"date"
end
end
attr_accessible :code, :extra, :name, :state, :tea_id, :time , :location, :state, :term, :password,:is_public,:description,:class_period, :open_student, :enterprise_name
#belongs_to :project, :class_name => 'Course', :foreign_key => :extra, primary_key: :identifier
@ -56,9 +70,9 @@ class Course < ActiveRecord::Base
validates_length_of :description, :maximum => 10000
before_save :self_validate
# 公开课程变成私有课程,所有资源都变成私有
after_update :update_files_public
after_create :create_board_sync, :act_as_course_activity, :act_as_course_message
before_destroy :delete_all_members
after_update :update_files_public,:update_course_ealasticsearch_index
after_create :create_board_sync, :act_as_course_activity, :act_as_course_message,:create_course_ealasticsearch_index
before_destroy :delete_all_members,:delete_course_ealasticsearch_index
safe_attributes 'extra',
'time',
@ -100,6 +114,34 @@ class Course < ActiveRecord::Base
where(" LOWER(name) LIKE :p ", :p => pattern)
end
}
scope :indexable,lambda { where('is_public = 1') }
def self.search(query)
__elasticsearch__.search(
{
query: {
multi_match: {
query: query,
type:"most_fields",
operator: "or",
fields: ['name', 'description^0.5']
}
},
sort: {
_score:{order: "desc" },
updated_at:{order:"desc"}
},
highlight: {
pre_tags: ['<span class="c_red">'],
post_tags: ['</span>'],
fields: {
name: {},
description: {}
}
}
}
)
end
def visible?(user=User.current)
user.allowed_to?(:view_course, self)
@ -344,6 +386,57 @@ class Course < ActiveRecord::Base
#def name
# read_attribute('name') || Project.find_by_identifier(self.extra).try(:name)
#end
# after_commit on: [:create] do
# __elasticsearch__.index_document
# end
#
# after_commit on: [:update] do
# __elasticsearch__.update_document
# end
#
# after_commit on: [:destroy] do
# __elasticsearch__.delete_document
# end
def create_course_ealasticsearch_index
if self.is_public == 1
self.__elasticsearch__.index_document
end
end
def update_course_ealasticsearch_index
if self.is_public == 1 #如果是初次更新成为公开的情况,会报错,那么这条记录尚未被索引过。没有报错就是更新的其他属性
begin
self.__elasticsearch__.update_document
rescue => e
self.__elasticsearch__.index_document
end
else #如果是更新成为私有的,那么索引就要被删除
begin
self.__elasticsearch__.delete_document
rescue => e
end
end
end
def delete_course_ealasticsearch_index
begin
self.__elasticsearch__.delete_document
rescue => e
end
end
end
# Delete the previous articles index in Elasticsearch
# Course.__elasticsearch__.client.indices.delete index: Course.index_name rescue nil
#
# # Create the new index with the new mapping
# Course.__elasticsearch__.client.indices.create \
# index: Course.index_name,
# body: { settings: Course.settings.to_hash, mappings: Course.mappings.to_hash }
# Index all article records from the DB to Elasticsearch
#Course.where('is_public = 1').import :force=>true

@ -17,7 +17,7 @@
class Document < ActiveRecord::Base
include Redmine::SafeAttributes
belongs_to :project
belongs_to :project,:touch=>true
belongs_to :user
belongs_to :category, :class_name => "DocumentCategory", :foreign_key => "category_id"
include UserScoreHelper

@ -2,6 +2,7 @@ class Exercise < ActiveRecord::Base
#exercise_status: 1,新建2发布3关闭
include Redmine::SafeAttributes
belongs_to :user
belongs_to :course ,:touch => true
has_many :exercise_questions, :dependent => :destroy,:order => "#{ExerciseQuestion.table_name}.question_number"
has_many :exercise_users, :dependent => :destroy
has_many :users, :through => :exercise_users #该测试被哪些用户提交答案过

@ -19,7 +19,7 @@ class Issue < ActiveRecord::Base
include Redmine::SafeAttributes
include Redmine::Utils::DateCalculation
include UserScoreHelper
belongs_to :project
belongs_to :project,:touch=> true
belongs_to :tracker
belongs_to :status, :class_name => 'IssueStatus', :foreign_key => 'status_id'
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'

@ -21,9 +21,10 @@ class JournalsForMessage < ActiveRecord::Base
after_destroy :delete_kindeditor_assets
belongs_to :project,
:foreign_key => 'jour_id',
:conditions => "#{self.table_name}.jour_type = 'Project' "
:conditions => "#{self.table_name}.jour_type = 'Project' ",:touch => true
belongs_to :course,
:foreign_key => 'jour_id'
:foreign_key => 'jour_id',:touch=>true
belongs_to :jour, :polymorphic => true

@ -20,7 +20,7 @@ class Message < ActiveRecord::Base
include UserScoreHelper
include ApplicationHelper
has_many_kindeditor_assets :assets, :dependent => :destroy
belongs_to :board
belongs_to :board,:touch => true
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
has_many :praise_tread, as: :praise_tread_object, dependent: :destroy
@ -287,13 +287,15 @@ class Message < ActiveRecord::Base
# 课程成员得分(英雄榜)
def act_as_student_score
unless self.author.allowed_to?(:as_teacher, self.course)
if self.parent_id.nil?
# 发帖
course_member_score(self.course.id, self.author_id, "Message")
else
# 回帖
course_member_score(self.course.id, self.author_id, "MessageReply")
if self.course
unless self.author.allowed_to?(:as_teacher, self.course)
if self.parent_id.nil?
# 发帖
course_member_score(self.course.id, self.author_id, "Message")
else
# 回帖
course_member_score(self.course.id, self.author_id, "MessageReply")
end
end
end
end

@ -17,11 +17,11 @@
class News < ActiveRecord::Base
include Redmine::SafeAttributes
belongs_to :project
belongs_to :project,:touch => true
include ApplicationHelper
has_many_kindeditor_assets :assets, :dependent => :destroy
#added by nwb
belongs_to :course
belongs_to :course,:touch => true
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
has_many :comments, :as => :commented, :dependent => :destroy, :order => "created_on"
# fq

@ -14,7 +14,7 @@
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
require 'elasticsearch/model'
class Project < ActiveRecord::Base
include Redmine::SafeAttributes
ProjectType_project = 0
@ -30,6 +30,19 @@ class Project < ActiveRecord::Base
# Specific overidden Activities
#elasticsearch
include Elasticsearch::Model
#elasticsearch kaminari init
Kaminari::Hooks.init
Elasticsearch::Model::Response::Response.__send__ :include, Elasticsearch::Model::Response::Pagination::Kaminari
settings index: { number_of_shards: 1 } do
mappings dynamic: 'false' do
indexes :name, analyzer: 'smartcn',index_options: 'offsets'
indexes :description, analyzer: 'smartcn',index_options: 'offsets'
indexes :updated_on, analyzer: 'smartcn',index_options: 'offsets', type:'date'
end
end
has_many :student_works
has_many :time_entry_activities
has_many :members, :include => [:principal, :roles], :conditions => "#{Principal.table_name}.type='User' AND #{Principal.table_name}.status=#{Principal::STATUS_ACTIVE}"
@ -138,8 +151,9 @@ class Project < ActiveRecord::Base
#ActiveModel::Dirty 这里有一个changed方法。对任何对象都可以用
after_save :update_inherited_members, :if => Proc.new {|project| project.inherit_members_changed?}
# 创建project之后默认创建一个board之后的board去掉了board的概念
after_create :create_board_sync,:acts_as_forge_activities
before_destroy :delete_all_members
after_create :create_board_sync,:acts_as_forge_activities,:create_project_ealasticsearch_index
before_destroy :delete_all_members,:delete_project_ealasticsearch_index
after_update :update_project_ealasticsearch_index
def remove_references_before_destroy
return if self.id.nil?
Watcher.delete_all ['watchable_id = ?', id]
@ -172,7 +186,33 @@ class Project < ActiveRecord::Base
}
scope :project_entities, -> { where(project_type: ProjectType_project) }
scope :course_entities, -> { where(project_type: ProjectType_course) }
scope :indexable,lambda { where('is_public = 1')} #用于elastic建索引的scope
def self.search(query)
__elasticsearch__.search(
{
query: {
multi_match: {
query: query,
type:"most_fields",
operator: "or",
fields: ['name','description^0.5']
}
},
sort: {
_score:{order: "desc" },
updated_on:{order: "desc" }
},
highlight: {
pre_tags: ['<span class="c_red">'],
post_tags: ['</span>'],
fields: {
name: {},
description: {}
}
}
}
)
end
def new_course
self.where('project_type = ?', 1)
end
@ -1176,5 +1216,36 @@ class Project < ActiveRecord::Base
end
def create_project_ealasticsearch_index
if self.is_public
self.__elasticsearch__.index_document
end
end
def update_project_ealasticsearch_index
if self.is_public #如果是初次更新成为公开的情况,会报错,那么这条记录尚未被索引过。没有报错就是更新的其他属性
begin
self.__elasticsearch__.update_document
rescue => e
self.__elasticsearch__.index_document
end
else #如果是更新成为私有的,那么索引就要被删除
begin
self.__elasticsearch__.delete_document
rescue => e
end
end
end
def delete_project_ealasticsearch_index
begin
self.__elasticsearch__.delete_document
rescue => e
end
end
end
#Project.where('is_public = 1').import :force=>true

@ -2,7 +2,7 @@
class ProjectTags < ActiveRecord::Base
attr_accessible :description, :project_id, :tag_id, :user_id
####################################################################################################添加代码
belongs_to :project
belongs_to :project,:touch => true
belongs_to :tag
belongs_to :user

@ -16,7 +16,7 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
require "digest/sha1"
require 'elasticsearch/model'
class User < Principal
TEACHER = 0
STUDENT = 1
@ -25,6 +25,20 @@ class User < Principal
include Redmine::SafeAttributes
seems_rateable_rater
#elasticsearch
include Elasticsearch::Model
#elasticsearch kaminari init
Kaminari::Hooks.init
Elasticsearch::Model::Response::Response.__send__ :include, Elasticsearch::Model::Response::Pagination::Kaminari
settings index: { number_of_shards: 1 } do
mappings dynamic: 'false' do
indexes :login, analyzer: 'smartcn',index_options: 'offsets'
indexes :firstname, analyzer: 'smartcn',index_options: 'offsets'
indexes :lastname, analyzer: 'smartcn',index_options: 'offsets'
indexes :last_login_on, analyzer: 'smartcn',index_options: 'offsets',type: 'date'
end
end
# Different ways of displaying/sorting users
USER_FORMATS = {
:firstname_lastname => {
@ -64,6 +78,7 @@ class User < Principal
},
}
#每日一报、一事一报、不报
MAIL_NOTIFICATION_OPTIONS = [
#['week', :label_user_mail_option_week],
@ -162,6 +177,7 @@ class User < Principal
#####
has_many :shares ,:dependent => :destroy
# add by zjc
has_one :level, :class_name => 'UserLevels', :dependent => :destroy
has_many :memos , :foreign_key => 'author_id'
@ -222,12 +238,12 @@ class User < Principal
# validates_email_realness_of :mail
before_create :set_mail_notification
before_save :update_hashed_password
before_destroy :remove_references_before_destroy
before_destroy :remove_references_before_destroy,:delete_user_ealasticsearch_index
# added by fq
after_create :act_as_activity, :add_onclick_time, :act_as_principal_activity
after_create :act_as_activity, :add_onclick_time, :act_as_principal_activity,:create_user_ealasticsearch_index
# end
# 更新邮箱用户或用户名的同事,同步更新邀请信息
after_update :update_invite_list
after_update :update_invite_list,:update_user_ealasticsearch_index
include Trustie::Gitlab::ManageUser
@ -240,7 +256,7 @@ class User < Principal
where("#{User.table_name}.id NOT IN (SELECT gu.user_id FROM #{table_name_prefix}groups_users#{table_name_suffix} gu WHERE gu.group_id = ?)", group_id)
}
scope :sorted, lambda { order(*User.fields_for_order_statement)}
scope :indexable,lambda { where('id not in (2,4)')} #用于elastic建索引的scope,id为2是匿名用户4是管理员不能被索引
scope :like, lambda {|arg, type|
if arg.blank?
where(nil)
@ -258,7 +274,33 @@ class User < Principal
end
end
}
def self.search(query)
__elasticsearch__.search(
{
query: {
multi_match: {
query: query,
type:"most_fields",
operator: "or",
fields: ['login', 'firstname','lastname']
}
},
sort:{
_score:{order:"desc"},
last_login_on: {order:"desc"}
},
highlight: {
pre_tags: ['<span class="c_red">'],
post_tags: ['</span>'],
fields: {
login: {},
firstname: {},
lastname: {}
}
}
}
)
end
# ======================================================================
@ -1119,6 +1161,23 @@ class User < Principal
end
end
def create_user_ealasticsearch_index
if self.id != 2 && self.id != 4
self.__elasticsearch__.index_document
end
end
def update_user_ealasticsearch_index
if self.id != 2 && self.id != 4
self.__elasticsearch__.update_document
end
end
def delete_user_ealasticsearch_index
if self.id != 2 && self.id != 4
self.__elasticsearch__.delete_document
end
end
end
class AnonymousUser < User
@ -1153,4 +1212,17 @@ class AnonymousUser < User
def destroy
false
end
end
# Delete the previous articles index in Elasticsearch
# User.__elasticsearch__.client.indices.delete index: User.index_name rescue nil
#
# # Create the new index with the new mapping
# User.__elasticsearch__.client.indices.create \
# index: User.index_name,
# body: { settings: User.settings.to_hash, mappings: User.mappings.to_hash }
# Index all article records from the DB to Elasticsearch
# 匿名用户 角色 和 管理员角色不能被索引
#User.where('id not in (2,4)').import :force=>true

@ -20,7 +20,7 @@
<a class="btn_submit c_white" data-button="ok" onclick="pollsSubmit($(this));">
保存
</a>
<a class="btn_cancel" data-button="cancel" onclick="resetHead();pollsCancel();">
<a class="btn_cancel" data-button="cancel" onclick="pollsCancel();">
<%= l(:button_cancel)%>
</a>
</div>
@ -35,6 +35,6 @@
$("#exercise_time").val("<%=exercise.time if exercise.time!= -1 %>");
$("#exercise_publish_time").val("<%= Time.parse(format_time(exercise.publish_time)).strftime("%Y-%m-%d") if !exercise.publish_time.nil?%>");
/*$("#exercise_description").text("<%#=exercise.exercise_description.html_safe %>");*/
document.getElementById("exercise_description").innerText = <%=exercise.exercise_description.html_safe %>;
document.getElementById("exercise_description").innerHTML = <%=exercise.exercise_description.html_safe %>;
}
</script>

@ -7,5 +7,5 @@
remote: data-remote
-%>
<%= link_to_unless current_page.last?, t('views.pagination.last').html_safe, url, :remote => remote %>
<%= link_to_unless false, t('views.pagination.last').html_safe, url, :remote => remote %>

@ -8,8 +8,7 @@
-%>
<%= paginator.render do -%>
<ul id="paginator" class="wlist">
<%#= first_page_tag unless current_page.first? %>
<%= prev_page_tag unless current_page.first? %>
<%= prev_page_tag %>
<% each_page do |page| -%>
<% if page.left_outer? || page.right_outer? || page.inside_window? -%>
<%= page_tag page %>
@ -17,7 +16,7 @@
<%= gap_tag %>
<% end -%>
<% end -%>
<%= next_page_tag unless current_page.last? %>
<%= next_page_tag %>
<!--<%#= last_page_tag unless current_page.last? %>-->
</ul>
<% end -%>

@ -7,6 +7,6 @@
remote: data-remote
-%>
<li >
<%= link_to_unless current_page.first?, t('views.pagination.previous').html_safe, url, :rel => 'prev', :remote => remote ,:class=>"previous c_blue"%>
<%= link_to_unless false, t('views.pagination.previous').html_safe, url, :rel => 'prev', :remote => remote ,:class=>"previous c_blue"%>
</li>

@ -18,24 +18,24 @@
</ul>
</div>
<script>
<% type = type%>
$(function (){
if('<%= type %>' != null && '<%= type %>' == 'courses' ){
$('input:radio[value="courses"]').attr('checked','checked');
}
if('<%= type %>' != null && '<%= type %>' == 'projects' ){
$('input:radio[value="projects"]').attr('checked','checked');
}
if('<%= type %>' != null && '<%= type %>' == 'users' ){
$('input:radio[value="users"]').attr('checked','checked');
}
});
<%# type = type%>
// $(function (){
// if('<%#= type %>' != null && '<%#= type %>' == 'courses' ){
// $('input:radio[value="courses"]').attr('checked','checked');
// }
// if('<%#= type %>' != null && '<%#= type %>' == 'projects' ){
// $('input:radio[value="projects"]').attr('checked','checked');
// }
// if('<%#= type %>' != null && '<%#= type %>' == 'users' ){
// $('input:radio[value="users"]').attr('checked','checked');
// }
// });
$(function(){
$("#navHomepageSearchInput").keypress(function(e){
var name = $.trim($('#navHomepageSearchInput').val());
if (e.keyCode == '13' && name != "" && name.length != 0) {
$('#type').val($('input[type=radio]:checked').val());
//$('#type').val($('input[type=radio]:checked').val());
$(this).parent().submit();
}
})
@ -44,7 +44,7 @@
function search_in_header(obj){
var name = $.trim($('#navHomepageSearchInput').val());
if (name != "" && name.length != 0) {
$('#type').val($('input[type=radio]:checked').val());
//$('#type').val($('input[type=radio]:checked').val());
obj.parent().submit();
}
}
@ -54,28 +54,28 @@
<% name = name%>
<%= form_tag({controller: :welcome, action: :search },:class=>'navHomepageSearchBox', method: :get) do %>
<input type="text" name="q" value="<%= name.nil? ? "" : name%>" id="navHomepageSearchInput" class="navHomepageSearchInput" placeholder="请输入关键词进行搜索"/>
<input type="hidden" name="search_type" id="type" value=""/>
<input type="text" name="q" value="<%= name.nil? ? "" : name%>" id="navHomepageSearchInput" class="navHomepageSearchInput" placeholder="请输入关键词搜索公开的课程、项目、用户以及资源"/>
<input type="hidden" name="search_type" id="type" value="all"/>
<input type="text" style="display: none;"/>
<a href="javascript:void(0);" class="homepageSearchIcon" onclick="search_in_header($(this));"></a>
<% end %>
<div class="navSearchTypeBox" id="navHomepageSearchType">
<div class="fl mr15 mt8">
<input type="radio" value="courses" name="search_type" checked/>
课程
</div>
<div class="fl mr15 mt8">
<input type="radio" value="projects" name="search_type" />
项目
</div>
<div class="fl mr15 mt8">
<input type="radio" value="users" name="search_type" />
用户
</div>
<div id="navSearchAlert" class="fr mr10">
<span class="c_red">请选择搜索类型</span>
</div>
</div>
<!--<div class="navSearchTypeBox" id="navHomepageSearchType">-->
<!--<div class="fl mr15 mt8">-->
<!--<input type="radio" value="courses" name="search_type" checked/>-->
<!--课程-->
<!--</div>-->
<!--<div class="fl mr15 mt8">-->
<!--<input type="radio" value="projects" name="search_type" />-->
<!--项目-->
<!--</div>-->
<!--<div class="fl mr15 mt8">-->
<!--<input type="radio" value="users" name="search_type" />-->
<!--用户-->
<!--</div>-->
<!--<div id="navSearchAlert" class="fr mr10">-->
<!--<span class="c_red">请选择搜索类型</span>-->
<!--</div>-->
<!--</div>-->
</div>
<div class="navHomepageProfile" id="navHomepageProfile">

@ -18,23 +18,23 @@
// alert(3)
$(doc).parent().submit();
}
<% type = type%>
$(function (){
if('<%= type %>' != null && '<%= type %>' == 'courses' ){
$('input:radio[value="courses"]').attr('checked','checked');
}
if('<%= type %>' != null && '<%= type %>' == 'projects' ){
$('input:radio[value="projects"]').attr('checked','checked');
}
if('<%= type %>' != null && '<%= type %>' == 'users' ){
$('input:radio[value="users"]').attr('checked','checked');
}
});
<!--<%# type = type%>-->
// $(function (){
// if('<%#= type %>' != null && '<%#= type %>' == 'courses' ){
// $('input:radio[value="courses"]').attr('checked','checked');
// }
// if('<%#= type %>' != null && '<%#= type %>' == 'projects' ){
// $('input:radio[value="projects"]').attr('checked','checked');
// }
// if('<%#= type %>' != null && '<%#= type %>' == 'users' ){
// $('input:radio[value="users"]').attr('checked','checked');
// }
// });
function search_in_header(obj){
var name = $.trim($('#navHomepageSearchInput').val());
if (name != "" && name.length != 0) {
$('#type').val($('input[type=radio]:checked').val());
//$('#type').val($('input[type=radio]:checked').val());
obj.parent().submit();
}
}
@ -42,7 +42,7 @@
function search_in_header_I(e,obj){
var name = $.trim($('#navHomepageSearchInput').val());
if (e.keyCode == '13' && name != "" && name.length != 0) {
$('#type').val($('input[type=radio]:checked').val());
//$('#type').val($('input[type=radio]:checked').val());
obj.parent().submit();
}
}
@ -52,28 +52,28 @@
<% name = name%>
<%= form_tag({controller: :welcome, action: :search },:class=>'navHomepageSearchBox', method: :get) do %>
<input type="text" name="q" value="<%= name.nil? ? "" : name%>" id="navHomepageSearchInput" class="navHomepageSearchInput" placeholder="请输入关键词进行搜索" onkeypress="search_in_header_I(event,$(this));"/>
<input type="hidden" name="search_type" id="type" value=""/>
<input type="text" name="q" value="<%= name.nil? ? "" : name%>" id="navHomepageSearchInput" class="navHomepageSearchInput" placeholder="请输入关键词搜索公开的课程、项目、用户以及资源" onkeypress="search_in_header_I(event,$(this));"/>
<input type="hidden" name="search_type" id="type" value="all"/>
<input type="text" style="display: none;"/>
<a href="javascript:void(0);" class="homepageSearchIcon" onclick="search_in_header($(this));"></a>
<% end %>
<div class="navSearchTypeBox" id="navHomepageSearchType">
<div class="fl mr15 mt8">
<input type="radio" value="courses" name="search_type" checked/>
课程
</div>
<div class="fl mr15 mt8">
<input type="radio" value="projects" name="search_type" />
项目
</div>
<div class="fl mr15 mt8">
<input type="radio" value="users" name="search_type" />
用户
</div>
<div id="navSearchAlert" class="fr mr10">
<span class="c_red">请选择搜索类型</span>
</div>
</div>
<!--<div class="navSearchTypeBox" id="navHomepageSearchType">-->
<!--<div class="fl mr15 mt8">-->
<!--<input type="radio" value="courses" name="search_type" checked/>-->
<!--课程-->
<!--</div>-->
<!--<div class="fl mr15 mt8">-->
<!--<input type="radio" value="projects" name="search_type" />-->
<!--项目-->
<!--</div>-->
<!--<div class="fl mr15 mt8">-->
<!--<input type="radio" value="users" name="search_type" />-->
<!--用户-->
<!--</div>-->
<!--<div id="navSearchAlert" class="fr mr10">-->
<!--<span class="c_red">请选择搜索类型</span>-->
<!--</div>-->
<!--</div>-->
</div>
<div id="loginInButton" class="fr ml20">

@ -212,7 +212,7 @@
<% contributor_course_scor(@course.id).each do |contributor_score| %>
<% unless contributor_score.total_score ==0 %>
<li> <a href="javascript:void:(0);"><%=link_to image_tag(url_to_avatar(contributor_score.user), :width => "35", :height => "35", :class=> "rankPortrait"),user_path(contributor_score.user) %></a>
<p><a href="javascript:void:(0);"><%=link_to contributor_score.user, user_path(contributor_score.user), :title => contributor_score.user %></a></p>
<p><a href="javascript:void:(0);"><%=link_to contributor_score.user.show_name, user_path(contributor_score.user), :title => contributor_score.user.show_name %></a></p>
<p><span class="c_green" style="cursor:pointer">
<a onmouseover ="message_titile_show($(this),event)" onmouseout ="message_titile_hide($(this))" class="c_green"><%= contributor_score.total_score.to_i %></a></span></p>
<div style="display: none" class="numIntro">
@ -246,7 +246,7 @@
<% hero_homework_scores.each do |student_score| %>
<% if student_score.score.to_i != 0 %>
<li> <a href="javascript:void:(0);"><%=link_to image_tag(url_to_avatar(student_score.user), :width => "35", :height => "35", :class=> "rankPortrait"),user_path(student_score.user) %></a>
<p><a href="javascript:void:(0);"><%=link_to student_score.user, user_path(student_score.user), :title => student_score.user %></a></p>
<p><a href="javascript:void:(0);"><%=link_to student_score.user.show_name, user_path(student_score.user), :title => student_score.user.show_name %></a></p>
<p><span class="c_red" style="cursor:pointer" title="作业总分:<%= student_score.score %>"><%= student_score.score.to_i %></span></p>
</li>
<% end %>

@ -1,7 +1,7 @@
<%= form_tag( url_for(:controller => 'users',:action => 'resource_search',:id=>user.id),
:remote=>true ,:method => 'get',:class=>'resourcesSearchloadBox',:id=>'resource_search_form') do %>
<input type="text" name="search" placeholder="输入资源关键词进行搜索" class="searchResource" />
<%= hidden_field_tag(:type,type) %>
<%= hidden_field_tag(:type,type.nil? ? 1 : type) %>
<%= submit_tag '',:class=>'homepageSearchIcon',:onfocus=>'this.blur();',:style=>'border-style:none' %>
<!--<a href="javascript:void(0);" onclick='this.parent.submit();return false;' class="searchIcon"></a>-->
<% end %>

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save