diff --git a/app/controllers/praise_tread_controller.rb b/app/controllers/praise_tread_controller.rb index 53df54e9f..53c74519b 100644 --- a/app/controllers/praise_tread_controller.rb +++ b/app/controllers/praise_tread_controller.rb @@ -71,6 +71,10 @@ class PraiseTreadController < ApplicationController @obj = Bid.find_by_id(id) when 'Contest' @obj = Contest.find_by_id(id) + when 'Memo' + @obj = Memo.find_by_id(id) + when 'Message' + @obj = Message.find_by_id(id) end return @obj end diff --git a/app/controllers/watchers_controller.rb b/app/controllers/watchers_controller.rb index 60c0175f3..50bb2ccd8 100644 --- a/app/controllers/watchers_controller.rb +++ b/app/controllers/watchers_controller.rb @@ -124,7 +124,7 @@ class WatchersController < ApplicationController def find_watchables #根据参数获取关注对象的类型(user、project) klass = Object.const_get(params[:object_type].camelcase) rescue nil - #判断获取的对象能否响应‘watched_by’方法 + #判断获取的对象类型能否响应‘watched_by’方法 if klass && klass.respond_to?('watched_by') @watchables = klass.find_all_by_id(Array.wrap(params[:object_id])) raise Unauthorized if @watchables.any? {|w| w.respond_to?(:visible?) && !w.visible?} diff --git a/app/models/journal.rb b/app/models/journal.rb index e77ebc74d..c82db5a1f 100644 --- a/app/models/journal.rb +++ b/app/models/journal.rb @@ -46,9 +46,11 @@ class Journal < ActiveRecord::Base # fq after_create :act_as_activity - before_save :be_user_score # end + before_save :be_user_score + #before_destroy :down_user_score + scope :visible, lambda {|*args| user = args.shift || User.current @@ -155,10 +157,18 @@ class Journal < ActiveRecord::Base # 更新用户分数 -by zjc def be_user_score - #新建了留言且留言不为空,不为空白 + #新建了缺陷留言且留言不为空,不为空白 if self.new_record? && !self.notes.nil? && self.notes.gsub(' ','') != '' #协同得分加分 UserScore.joint(:post_issue, User.current,self.issue.author, { message_id: self.id }) end end + # 减少用户分数 -by zjc + def down_user_score + #删除有效缺陷留言 + if !self.notes.nil? && self.notes.gsub(' ','') != '' + #协同得分减分 + UserScore.joint(:delete_issue, User.current,self.issue.author, { message_id: self.id }) + end + end end diff --git a/app/models/journals_for_message.rb b/app/models/journals_for_message.rb index d719a23ac..cba605afc 100644 --- a/app/models/journals_for_message.rb +++ b/app/models/journals_for_message.rb @@ -43,6 +43,7 @@ class JournalsForMessage < ActiveRecord::Base after_create :reset_counters! after_destroy :reset_counters! before_save :be_user_score + #before_destroy :down_user_score # default_scope { where('m_parent_id IS NULL') } @@ -103,10 +104,18 @@ class JournalsForMessage < ActiveRecord::Base # 更新用户分数 -by zjc def be_user_score - #新建了留言且留言不为空,不为空白 - if self.new_record? + #新建了留言回复 + if self.new_record? && self.reply_id != 0 #协同得分加分 UserScore.joint(:reply_message, User.current,User.find(self.reply_id), { journals_for_messages_id: self.id }) end end + # 更新用户分数 -by zjc + def down_user_score + #删除了留言回复 + if self.reply_id != 0 + #协同得分减分 + UserScore.joint(:reply_message_delete, User.current,User.find(self.reply_id), { journals_for_messages_id: self.id }) + end + end end diff --git a/app/models/memo.rb b/app/models/memo.rb index a0581d945..d706f814b 100644 --- a/app/models/memo.rb +++ b/app/models/memo.rb @@ -46,7 +46,7 @@ class Memo < ActiveRecord::Base # after_create :send_notification # after_save :plusParentAndForum # after_destroy :minusParentAndForum - + before_save :be_user_score # scope :visible, lambda { |*args| # includes(:forum => ).where() # } @@ -140,5 +140,17 @@ class Memo < ActiveRecord::Base @forum.topic_count = 0 if @forum.topic_count.to_int < 0 end @forum.save - end + end + + #更新用户分数 -by zjc + def be_user_score + #新建memo且无parent的为发帖 + if self.new_record? && self.parent_id.nil? + UserScore.joint(:post_message, User.current,nil, { memo_id: self.id }) + #新建memo且有parent的为回帖 + elsif self.new_record? && !self.parent_id.nil? + UserScore.joint(:reply_posting, User.current,self.parent.author, { memo_id: self.id }) + end + end + end diff --git a/app/models/message.rb b/app/models/message.rb index 337c493d5..e778977fe 100644 --- a/app/models/message.rb +++ b/app/models/message.rb @@ -55,6 +55,7 @@ class Message < ActiveRecord::Base # fq after_create :act_as_activity before_save :be_user_score + #before_destroy :down_user_score # end scope :visible, lambda {|*args| @@ -133,4 +134,14 @@ class Message < ActiveRecord::Base UserScore.joint(:reply_posting, User.current,self.parent.author, { message_id: self.id }) end end + #减少用户分数 + def down_user_score + #删除发帖 + if self.parent_id.nil? + UserScore.joint(:delete_message, User.current,nil, { message_id: self.id }) + #删除留言 + else + UserScore.joint(:reply_deleting, User.current,self.parent.author, { message_id: self.id }) + end + end end diff --git a/app/models/praise_tread.rb b/app/models/praise_tread.rb index c27e1fc9f..8fc604671 100644 --- a/app/models/praise_tread.rb +++ b/app/models/praise_tread.rb @@ -2,5 +2,41 @@ class PraiseTread < ActiveRecord::Base attr_accessible :user_id,:praise_tread_object_id,:praise_tread_object_type,:praise_or_tread belongs_to :user belongs_to :praise_tread_object, polymorphic: true - + before_save :be_user_score + + def find_object_by_type_and_id(type,id) + @obj = nil + case type + when 'User' + @obj = User.find_by_id(id) + when 'Issue' + @obj = Issue.find_by_id(id) + when 'Project' + @obj = Project.find_by_id(id) + when 'Bid' + @obj = Bid.find_by_id(id) + when 'Contest' + @obj = Contest.find_by_id(id) + when 'Memo' + @obj = Memo.find_by_id(id) + when 'Message' + @obj = Message.find_by_id(id) + end + return @obj + end + + #更新用户分数 - by zjc + def be_user_score + #踩贴吧或讨论区帖子 + if self.new_record? && self.praise_or_tread == 0 && (self.praise_tread_object_type == 'Memo' || self.praise_tread_object_type == 'Message') + obj = find_object_by_type_and_id(self.praise_tread_object_type,praise_tread_object_id) + target_user = obj.author + UserScore.skill(:treaded_by_user, User.current,target_user, { praise_tread_id: self.id }) + #顶贴吧或讨论区帖子 + elsif self.new_record? && self.praise_or_tread == 1 && (self.praise_tread_object_id == 'Memo' || self.praise_tread_object_type == 'Message') + obj = find_object_by_type_and_id(self.praise_tread_object_type,praise_tread_object_id) + target_user = obj.author + UserScore.skill(:praised_by_user, User.current,target_user,{ praise_tread_id: self.id }) + end + end end diff --git a/app/models/user.rb b/app/models/user.rb index e85876618..b4aaea49f 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -122,6 +122,10 @@ 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' + ##### scope :logged, lambda { where("#{User.table_name}.status <> #{STATUS_ANONYMOUS}") } scope :status, lambda {|arg| where(arg.blank? ? nil : {:status => arg.to_i}) } scope :visible, lambda {|*args| @@ -876,6 +880,63 @@ class User < Principal end end + #获取user的等级 -by zjc + def get_level + if self.level.nil? + update_user_level + end + self.level.level + end + + #更新用户等级 - by zjc + def update_user_level + user_level = UserLevels.new + user_level.user = self + + #判断user的等级 + pis = self.project_infos #ProjectInfo.find_all_by_user_id(self.id) + isManager = false; + pis.each do |pi| + #判断是否为项目管理员 + if self.allowed_to?({:controller => "projects", :action => "edit"}, pi.project) + isManager = true; + end + end + has_effective_praise_count = false; + self.messages.each do |message| + if message.parent_id.nil? + ptcs = PraiseTreadCache.find_all_by_object_id(message.id) + ptcs.each do |ptc| + if ptc.object_type == 'Message' && ptc.praise_num.to_i > 5 + has_effective_praise_count = true + end + end + end + end + if !has_effective_praise_count + self.memos do |memo| + if memo.parent_id.nil? + ptcs = PraiseTreadCache.find_all_by_object_id(memo.id) + ptcs.each do |ptc| + if ptc.object_type == 'Memo' && ptc.praise_num > 5 + has_effective_praise_count = true + end + end + end + end + end + + if isManager || self.changesets.count > 100 + user_level.level = 3 + elsif (self.changesets.count > 1 && self.changesets.count <= 100) || has_effective_praise_count + user_level.level = 2 + else + user_level.level = 1 + end + user_level.save + self.reload + end + protected def validate_password_length @@ -884,7 +945,6 @@ class User < Principal errors.add(:password, :too_short, :count => Setting.password_min_length.to_i) end end - private def act_as_activity @@ -926,6 +986,8 @@ class User < Principal Redmine::Utils.random_hex(16) end + + end class AnonymousUser < User diff --git a/app/models/user_levels.rb b/app/models/user_levels.rb new file mode 100644 index 000000000..eb8dd37ed --- /dev/null +++ b/app/models/user_levels.rb @@ -0,0 +1,5 @@ +#用户等级类 - by zjc +class UserLevels < ActiveRecord::Base + attr_accessible :user_id, :level + belongs_to :user +end \ No newline at end of file diff --git a/app/models/user_score.rb b/app/models/user_score.rb index c33f3e3f2..288370845 100644 --- a/app/models/user_score.rb +++ b/app/models/user_score.rb @@ -56,10 +56,18 @@ class UserScore < ActiveRecord::Base user_score.collaboration = user_score.collaboration.to_i + 2 user_score.save Rails.logger.info "[UserScore#joint] ===> User: #{current_user} posting a message. options => (#{options.to_s})" + when :delete_message # current_user 发帖了 Delete Message + user_score.collaboration = user_score.collaboration.to_i - 2 + user_score.save + Rails.logger.info "[UserScore#joint] ===> User: #{current_user} deleting a message. options => (#{options.to_s})" when :post_issue # current_user 对 target_user 的缺陷留言了 Add Journal user_score.collaboration = user_score.collaboration.to_i + 1 user_score.save Rails.logger.info "[UserScore#joint] ===> User: #{current_user} posting a issue. options => (#{options.to_s})" + when :delete_issue # current_user 删除了 对 target_user 的缺陷留言了 Delete Journal + user_score.collaboration = user_score.collaboration.to_i - 1 + user_score.save + Rails.logger.info "[UserScore#joint] ===> User: #{current_user} deleting a issue. options => (#{options.to_s})" when :change_issue_status # current_user 更改了缺陷的状态 Changed Issue user_score.collaboration = user_score.collaboration.to_i + 1 user_score.save @@ -68,10 +76,18 @@ class UserScore < ActiveRecord::Base user_score.collaboration = user_score.collaboration.to_i + 1 user_score.save Rails.logger.info "[UserScore#joint] ===> User: #{current_user} reply message. options => (#{options.to_s})" + when :reply_message_delete # current_user 删除了对 target_user 留言的回复 delete Journals_for_messages + user_score.collaboration = user_score.collaboration.to_i - 1 + user_score.save + Rails.logger.info "[UserScore#joint] ===> User: #{current_user} delete reply message. options => (#{options.to_s})" when :reply_posting # current_user 对 target_user 帖子的回复 Add Message user_score.collaboration = user_score.collaboration.to_i + 1 user_score.save Rails.logger.info "[UserScore#joint] ===> User: #{current_user} reply posting. options => (#{options.to_s})" + when :reply_deleting # current_user 删除了 对 target_user 帖子的回复 Delete Message + user_score.collaboration = user_score.collaboration.to_i - 1 + user_score.save + Rails.logger.info "[UserScore#joint] ===> User: #{current_user} reply deleting. options => (#{options.to_s})" else Rails.logger.error "[UserScore#joint] ===> #{operate} is not define." return false @@ -95,19 +111,19 @@ class UserScore < ActiveRecord::Base user_score = target_user.user_score_attr case operate when :followed_by # current_user 关注了target_user - user_score.active = user_score.influence.to_i + 2 + user_score.influence = user_score.influence.to_i + 2 user_score.save Rails.logger.info "[UserScore#influence] ===> User: #{current_user} be followed. options => (#{options.to_s})" when :cancel_followed # current_uer 取消了对 target_user的关注 - user_score.active = user_score.influence.to_i - 2 + user_score.influence = user_score.influence.to_i - 2 user_score.save Rails.logger.info "[UserScore#influence] ===> User: #{current_user} canceled followed. options => (#{options.to_s})" else Rails.logger.error "[UserScore#influence] ===> #{operate} is not define." return false end - rescue => e - Rails.logger.error "[UserScore#influence] ===> Exception: #{e}." + #rescue => e + #Rails.logger.error "[UserScore#influence] ===> Exception: #{e}." end # 前略·技术得分 @@ -122,13 +138,44 @@ class UserScore < ActiveRecord::Base # Returns boolean. 返回积分保存结果 def self.skill(operate, current_user, target_user, options={}) current_user, target_user = get_users(current_user, target_user) - user_score = current_user.user_score_attr + current_user_score = current_user.user_score_attr + target_user_score = target_user.user_score_attr case operate # when :treading # current_user 踩了 target_user 的帖子 # Rails.logger.info "[UserScore#skill] ===> User: #{current_user} treading #{target_user}'s posting. options => (#{options.to_s})" - when :treaded_by_user # current_user 踩了 target_user 的帖子 + when :treaded_by_user # current_user 踩了 target_user 的帖子 + current_user_score.skill = current_user_score.skill.to_i - 2 #踩别人的帖子减2分 + current_user_score.save + if current_user.id == target_user.id + target_user.reload + target_user_score = target_user.user_score_attr + end + level = current_user.get_level + if level == 1 + target_user_score.skill = target_user_score.skill.to_i - 2 #帖子被一级会员踩-2分 + target_user_score.save + elsif level == 2 + target_user_score.skill = target_user_score.skill.to_i - 4 #帖子被二级会员踩-4分 + target_user_score.save + elsif level == 3 + target_user_score.skill = target_user_score.skill.to_i - 6 #帖子被三级会员踩-6分 + target_user_score.save + end + Rails.logger.info "[UserScore#skill] ===> User: #{current_user} treaded_by #{target_user}. options => (#{options.to_s})" - when :praised_by_user # current_user 顶了 target_user 的帖子 + when :praised_by_user # current_user 顶了 target_user 的帖子 + level = current_user.get_level + if level == 1 + target_user_score.skill = target_user_score.skill.to_i + 4 #帖子被一级会员顶+4分 + target_user_score.save + elsif level == 2 + target_user_score.skill = target_user_score.skill.to_i + 6 #帖子被二级会员顶+6分 + target_user_score.save + elsif level == 3 + target_user_score.skill = target_user_score.skill.to_i + 8 #帖子被三级会员顶+8分 + target_user_score.save + end + Rails.logger.info "[UserScore#skill] ===> User: #{current_user} praised_by #{target_user}. options => (#{options.to_s})" else Rails.logger.error "[UserScore#skill] ===> #{operate} is not define." @@ -194,17 +241,17 @@ class UserScore < ActiveRecord::Base #分数小于0时修正为0 #分数大于等于0时不修正 -by zjc def correct_score - if self.collaboration < 0 + if !self.collaboration.nil? && self.collaboration < 0 self.collaboration = 0 end - if self.active < 0 - self.active = 0 - end - if self.influence < 0 + if !self.influence.nil? && self.influence < 0 self.influence = 0 end - if self.skill < 0 + if !self.skill.nil? && self.skill < 0 self.skill = 0 end + if !self.active.nil? && self.active < 0 + self.active = 0 + end end end diff --git a/app/models/watcher.rb b/app/models/watcher.rb index f700e62ac..88f23900c 100644 --- a/app/models/watcher.rb +++ b/app/models/watcher.rb @@ -22,6 +22,8 @@ class Watcher < ActiveRecord::Base has_one :project_status has_one :users_status #end + before_save :be_user_score + before_destroy :down_user_score validates_presence_of :user validates_uniqueness_of :user_id, :scope => [:watchable_type, :watchable_id] @@ -70,4 +72,22 @@ class Watcher < ActiveRecord::Base end pruned end + + # 更新用户分数 -by zjc + def be_user_score + #添加了关注 + if self.new_record? && self.watchable_type == 'Principal' + #影响力得分 + UserScore.influence(:followed_by, self.user,self.watchable, { watcher_id: self.id }) + end + + end + #减分操作 -by zjc + def down_user_score + #取消关注 + if self.watchable_type == 'Principal' + UserScore.influence(:cancel_followed, self.user,self.watchable, { watcher_id: self.id }) + end + + end end diff --git a/app/views/messages/show.html.erb b/app/views/messages/show.html.erb index 4f22fd140..92b62cb60 100644 --- a/app/views/messages/show.html.erb +++ b/app/views/messages/show.html.erb @@ -60,6 +60,8 @@
+ + <%= render :partial => "/praise_tread/praise_tread",:locals => {:obj => @topic,:show_flag => true,:user_id =>User.current.id}%>
<%= watcher_link(@topic, User.current) %> <%= link_to( @@ -82,6 +84,7 @@ :class => 'icon icon-del' ) if @message.destroyable_by?(User.current) %>
+
<%= link_to image_tag(url_to_avatar(@topic.author), :class => "avatar"), user_path(@topic.author) %> diff --git a/app/views/welcome/index.html.erb b/app/views/welcome/index.html.erb index ca99f33dc..483dbfc02 100644 --- a/app/views/welcome/index.html.erb +++ b/app/views/welcome/index.html.erb @@ -52,7 +52,9 @@ <%= link_to "更多>>", { :controller => 'projects', :action => 'index', :project_type => 0, :host => Setting.project_domain}, :target => "_blank" %>
    - <% find_miracle_project(10, 3).map do |project| %> + <% projects = find_miracle_project(10, 3) %> + <% cache projects do %> + <% projects.map do |project| %>
  • <%= image_tag(get_project_avatar(project), :class => "avatar-4") %> @@ -71,11 +73,11 @@ :title => "项目得分,综合考虑了项目的各项活动,反映了该项目的活跃程度", :class => "tooltip", :id => "tooltip-#{project.id}" %> -

  • <% end; reset_cycle %>
+ <% end %>
@@ -84,7 +86,9 @@

用户动态

<%= link_to "更多>>", { :controller => 'users', :action => 'index'}, :target => "_blank" %>
- <% find_all_activities.each do |event| %> + <%activities = find_all_activities%> + <% cache activities do %> + <% activities.each do |event| %>
  • <%= image_tag url_to_avatar(event.event_author), :class => "avatar-3" %> @@ -96,12 +100,14 @@
  • <% end %> + <% end %>
    diff --git a/lib/plugins/acts_as_watchable/lib/acts_as_watchable.rb b/lib/plugins/acts_as_watchable/lib/acts_as_watchable.rb index 36a230462..06d661478 100644 --- a/lib/plugins/acts_as_watchable/lib/acts_as_watchable.rb +++ b/lib/plugins/acts_as_watchable/lib/acts_as_watchable.rb @@ -47,8 +47,13 @@ module Redmine ################### modified by liuping def remove_watcher(user) return nil unless user && user.is_a?(User) - if self.instance_of?(User) - Watcher.delete_all "watchable_type = 'Principal' AND watchable_id = #{self.id} AND user_id = #{user.id}" + if self.instance_of?(User) + #通过model层删除以触发before_destroy事件 -by zjc + watchers = Watcher.find_by_sql "select * from `watchers` where watchable_type = 'Principal' AND watchable_id = #{self.id} AND user_id = #{user.id}" + watchers.each do |watcher| + watcher.destroy + end + #Watcher.delete_all "watchable_type = 'Principal' AND watchable_id = #{self.id} AND user_id = #{user.id}" else Watcher.delete_all "watchable_type = '#{self.class}' AND watchable_id = #{self.id} AND user_id = #{user.id}" end