You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
pgfqe6ch8/app/models/memo.rb

327 lines
10 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# root_idnil => 主贴; 有值 => 主帖的ID值为帖子的ID
# parent_id 回复对这个id的回复
# sticky 顶置 1
# replies_count 表示帖子的主回复(一级回复数)
# all_replies_count 表示帖子的所有回复(一级回复数 + 二级回复数)
require 'elasticsearch/model'
class Memo < ActiveRecord::Base
include Redmine::SafeAttributes
include UserScoreHelper
include ApplicationHelper
include Elasticsearch::Model
belongs_to :forum
has_many_kindeditor_assets :assets, :dependent => :destroy
has_many :tidings, :as => :container , :dependent => :destroy
belongs_to :author, :class_name => "User", :foreign_key => 'author_id'
has_many :tag_repertoires, :through => :memo_tag_repertoires
has_many :memo_tag_repertoires, :dependent => :destroy
validates_presence_of :author_id, :forum_id, :subject,:content
# 若是主题帖,则内容可以是空
#validates :content, presence: true, if: Proc.new{|o| !o.parent_id.nil? }
validates_length_of :subject, maximum: 100
validate :cannot_reply_to_locked_topic, :on => :create
#elasticsearch kaminari init
Kaminari::Hooks.init
Elasticsearch::Model::Response::Response.__send__ :include, Elasticsearch::Model::Response::Pagination::Kaminari
settings index: {
number_of_shards: 5 ,
analysis: {
char_filter: {
and_filter: {
type: "mapping",
mappings: [ "&=> and "]
}
},
analyzer: {
my_analyzer: {
type: 'custom',
tokenizer: 'standard',
filter: ['classic'],
char_filter: ['html_strip']
}
}
}
} do
mappings dynamic: 'false' do
indexes :subject, analyzer: 'smartcn',index_options: 'offsets'#, char_filter: 'html_strip'
indexes :content, analyzer:'my_analyzer',index_options: 'offsets',search_analyzer: 'smartcn'
indexes :updated_at,index:"not_analyzed" ,type:'date'
end
end
acts_as_tree :counter_cache => :replies_count, :order => "#{Memo.table_name}.created_at ASC"
acts_as_attachable
has_many :user_score_details, :class_name => 'UserScoreDetails',:as => :score_changeable_obj
has_many :praise_tread, as: :praise_tread_object, dependent: :destroy
has_one :praise_tread_cache, as: :object, dependent: :destroy
# 消息
has_many :memo_messages, :class_name =>'MemoMessage', :dependent => :destroy
# end
belongs_to :last_reply, :class_name => 'Memo', :foreign_key => 'last_reply_id'
# acts_as_searchable :column => ['subject', 'content'],
# #:include => { :forum => :p}
# #:project_key => "#{Forum.table_name}.project_id"
# :date_column => "#{table_name}.created_at"
acts_as_event :title => Proc.new {|o| "#{o.forum.name}: #{o.subject}"},
:datetime => :updated_at,
# :datetime => :created_at,
:description => :content,
:author => :author,
:type => Proc.new {|o| o.parent_id.nil? ? 'Memo' : 'Reply'},
:url => Proc.new {|o| {:controller => 'memos', :action => 'show', :forum_id => o.forum_id}.merge(o.parent_id.nil? ? {:id => o.id} : {:id => o.parent_id, :r => o.id, :anchor => "reply-#{o.id}"})}
acts_as_activity_provider :author_key => :author_id,
:func => 'memos',
:timestamp => 'created_at'
# :find_options => {:type => 'memos'}
# acts_as_watchable
safe_attributes "author_id",
"subject",
"content",
"forum_id",
"last_memo_id",
"lock",
"sticky",
"parent_id",
"replies_count",
"all_replies_count",
"root_id",
"language"
after_create :add_author_as_watcher, :reset_counters!, :send_tiding
after_update
after_destroy :reset_counters!,:delete_kindeditor_assets #,:down_user_score -- 公共区发帖暂不计入得分,
# after_create :send_notification
# after_save :plusParentAndForum
# after_destroy :minusParentAndForum
#before_save :be_user_score
# scope :visible, lambda { |*args|
# includes(:forum => ).where()
# }
scope :indexable,lambda {
where('parent_id is null')
}
scope :visible, lambda{where(hidden: 0)}
scope :field_for_list, lambda{
select([:id, :subject, :author_id, :sticky, :updated_at, :language, :reward, :all_replies_count, :viewed_count, :forum_id])
}
scope :field_for_recommend, lambda{select([:id, :subject, :language, :forum_id, :all_replies_count])}
scope :user_posts, ->(user_id){where(root_id: nil, author_id: user_id, forum_id: [3,5])} # 只取技术分享和操作指南
scope :memo_replies, ->(id){where(:root_id => id)}
scope :hot, lambda{order("all_replies_count desc, updated_at desc")}
scope :posts, lambda{ where(root_id: nil, forum_id: [3,5]) }# 只取技术分享和操作指南
def self.search(query)
__elasticsearch__.search(
{
query: {
multi_match: {
query: query,
type:"most_fields",
operator: "or",
fields: ['subject','content^0.5']
}
},
sort: {
_score:{order: "desc" },
updated_at:{order: "desc" }
},
highlight: {
pre_tags: ['<span class="c_red">'],
post_tags: ['</span>'],
fields: {
subject: {},
content: {}
}
}
}
)
end
def reply_for_memo
Memo.where(:parent_id => self.id)
end
def all_replies
self.all_replies_count
end
def send_mail
# Mailer.run.forum_message_added(self) if Setting.notified_events.include?('forum_message_added')
end
def creator_user
self.author
end
def created_time
self.created_on
end
def content_detail
self.content
end
# 公共贴吧消息记录
# 原则:新帖子给超级管理员发消息
def send_tiding
if self.parent_id.present?
self.tidings << Tiding.new(:user_id => self.parent.author_id, :trigger_user_id => self.author_id, :parent_container_id => self.root_id, :parent_container_type => "Memo",
:belong_container_id => self.forum_id, :belong_container_type => "Forum", :viewed => 0, :tiding_type => "Comment")
else
self.tidings << Tiding.new(:user_id => 1, :trigger_user_id => self.author_id, :parent_container_id => self.id, :parent_container_type => "Memo",
:belong_container_id => self.forum_id, :belong_container_type => "Forum", :viewed => 0, :tiding_type => "Comment")
end
end
def cannot_reply_to_locked_topic
errors.add :base, l(:label_memo_locked) if root.locked? && self != root
end
# def update_memos_forum
# if forum_id_changed?
# Message.update_all({:board_id => board_id}, ["id = ? OR parent_id = ?", root.id, root.id ])
# Forum.reset_counters!(forum_id_was)
# Forum.reset_counters!(forum_id)
# end
# end
def reset_counters!
if parent && parent.id
parent.update_attribute(:last_reply_id, parent.children.maximum(:id))
end
if root
root.update_attribute(:last_reply_id, Memo.where(:root_id => root.id).maximum(:id)) unless root.destroyed?
end
forum.reset_counters!
end
def sticky?
sticky == 1
end
def replies
Memo.where("parent_id = ?", id)
end
def locked?
self.lock
end
def editable_by? user
# user && user.logged? || (self.author == usr && usr.allowed_to?(:edit_own_messages, project))
user.admin? || self.author == user
end
def destroyable_by? user
(user && self.author == user) || user.admin? || self.forum.creator == user || Memo.find(self.root_id).author == user
#self.author == user || user.admin?
end
def deleted_attach_able_by? user
(user && user.logged? && (self.author == user) ) || user.admin?
end
private
def add_author_as_watcher
Watcher.create(:watchable => self.root, :user => author)
end
def send_notification
# if Setting.notified_events.include?('message_posted')
# Mailer.run.message_posted(self)
# end
end
# def update_reply_count
# if self.root_id
# self.root.increment!(:replies_count)
# end
# end
def plusParentAndForum
@forum = Forum.find(self.forum_id)
@forum.memo_count = @forum.memo_count.to_int + 1
@forum.last_memo_id = self.id
if self.parent_id
@parent_memo = Memo.find_by_id(self.parent_id)
@parent_memo.last_reply_id = self
@parent_memo.replies_count = @parent_memo.replies_count.to_int + 1
@parent_memo.save
else
@forum.topic_count = @forum.topic_count.to_int + 1
end
@forum.save
end
def minusParentAndForum
@forum = Forum.find(self.forum_id)
@forum.memo_count = @forum.memo_count.to_int - 1
@forum.memo_count = 0 if @forum.memo_count.to_int < 0
# @forum.last_memo_id = Memo.reorder('created_at ASC').find_all_by_forum_id(self.forum_id).last.id
if self.parent_id
@parent_memo = Memo.find_by_id(self.parent_id)
# @parent_memo.last_reply_id = Memo.reorder('created_at ASC').find_all_by_parent_id(self.parent_id).last.id
@parent_memo.replies_count = @parent_memo.replies_count.to_int - 1
@parent_memo.replies_count = 0 if @parent_memo.replies_count.to_int < 0
@parent_memo.save
else
@forum.topic_count = @forum.topic_count.to_int - 1
@forum.topic_count = 0 if @forum.topic_count.to_int < 0
end
@forum.save
end
#更新用户分数 -by zjc
def be_user_score
#新建memo且无parent的为发帖
if self.parent_id.nil?
UserScore.joint(:post_message, User.current,nil,self ,{ memo_id: self.id })
update_memo_number(User.current,1)
#新建memo且有parent的为回帖
elsif !self.parent_id.nil?
UserScore.joint(:reply_posting, User.current,self.parent.author,self, { memo_id: self.id })
update_replay_for_memo(User.current,1)
end
end
#被删除时更新用户分数
def down_user_score
update_memo_number(User.current,1)
update_replay_for_memo(User.current,1)
end
# Time 2015-03-26 15:20:24
# Author lizanle
# Description 从硬盘上删除资源
def delete_kindeditor_assets
delete_kindeditor_assets_from_disk self.id,OwnerTypeHelper::MEMO
end
def create_memo_ealasticsearch_index
if self.parent_id.nil?
self.__elasticsearch__.index_document
end
end
def update_memo_ealasticsearch_index
if self.parent_id.nil?
self.__elasticsearch__.update_document
end
end
def delete_memo_ealasticsearch_index
if self.parent_id.nil?
self.__elasticsearch__.delete_document
end
end
end