# Redmine - project management software # Copyright (C) 2006-2013 Jean-Philippe Lang # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # 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. class UserScore < ActiveRecord::Base belongs_to :user before_save :correct_score def self.find_max_file self.maximum(:file) end def self.find_min_file self.minimum(:file) end def self.find_max_issue self.maximum(:issue) end def self.find_min_issue self.minimum(:file) end # 以上类方法目测没用,反正也报错 # =============================================================================== # 前略·协同得分 # operate - 更新操作 类型 symbol # user - 计分用户 # # Examples # # UserScore.joint(:post_message, User.current, nil) # # => true #当前用户发帖计分操作成功 # # Returns boolean. 返回积分保存结果 def self.joint(operate, current_user, target_user,obj, options={}) current_user, target_user = get_users(current_user, target_user) user_score = current_user.user_score_attr user_grade = nil #项目个人得分 project = obj.project unless project.nil? user_grade = UserGrade.find_by_user_id_and_project_id(current_user.id, project.id) if user_grade.nil? user_grade = UserGrade.create(:user_id => current_user.id,:project_id => project.id) end end case operate when :post_message # current_user 发帖了 Add Message user_score.collaboration = user_score.collaboration.to_i + 2 user_score.save unless user_grade.nil? user_grade.grade = user_grade.grade.to_i + 2 user_grade.save end create_score_changed_details({:current_user_id => current_user.id ,:score_type => "collaboration",:score_action => "post_message",:user_id => current_user.id,:old_score => user_score.collaboration - 2,:new_score => user_score.collaboration,:current_user_level => UserLevels.get_level(current_user),:score_changeable_obj_id=> obj.id,:score_changeable_obj_type => obj.class.to_s}) 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_message # current_user 对 target_user 的缺陷留言了 Add Journal user_score.collaboration = user_score.collaboration.to_i + 1 user_score.save unless user_grade.nil? user_grade.grade = user_grade.grade.to_i + 1 user_grade.save end create_score_changed_details({:current_user_id => current_user.id ,:target_user_id =>target_user.id, :score_type => "collaboration",:score_action => "post_issue_message",:user_id => current_user.id,:old_score => user_score.collaboration - 1,:new_score => user_score.collaboration,:current_user_level => UserLevels.get_level(current_user),:target_user_level => UserLevels.get_level(target_user),:score_changeable_obj_id=> obj.id,:score_changeable_obj_type => obj.class.to_s}) Rails.logger.info "[UserScore#joint] ===> User: #{current_user} posting a issue. options => (#{options.to_s})" #when :delete_issue_message # 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 unless user_grade.nil? user_grade.grade = user_grade.grade.to_i + 1 user_grade.save end create_score_changed_details({:current_user_id => current_user.id , :score_type => "collaboration",:score_action => "change_issue_status",:user_id => current_user.id,:old_score => user_score.collaboration - 1,:new_score => user_score.collaboration,:current_user_level => UserLevels.get_level(current_user),:score_changeable_obj_id=> obj.id,:score_changeable_obj_type => obj.class.to_s}) Rails.logger.info "[UserScore#joint] ===> User: #{current_user} change issue status. options => (#{options.to_s})" when :reply_message # current_user 对 target_user 留言的回复 Add Journals_for_messages user_score.collaboration = user_score.collaboration.to_i + 1 user_score.save unless user_grade.nil? user_grade.grade = user_grade.grade.to_i + 1 user_grade.save end create_score_changed_details({:current_user_id => current_user.id ,:target_user_id =>target_user.id, :score_type => "collaboration",:score_action => "reply_message",:user_id => current_user.id,:old_score => user_score.collaboration - 1,:new_score => user_score.collaboration,:current_user_level => UserLevels.get_level(current_user),:target_user_level => UserLevels.get_level(target_user),:score_changeable_obj_id=> obj.id,:score_changeable_obj_type => obj.class.to_s}) 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 unless user_grade.nil? user_grade.grade = user_grade.grade.to_i + 1 user_grade.save end create_score_changed_details({:current_user_id => current_user.id ,:target_user_id =>target_user.id, :score_type => "collaboration",:score_action => "reply_posting",:user_id => current_user.id,:old_score => user_score.collaboration - 1,:new_score => user_score.collaboration,:current_user_level => UserLevels.get_level(current_user),:target_user_level => UserLevels.get_level(target_user),:score_changeable_obj_id=> obj.id,:score_changeable_obj_type => obj.class.to_s}) 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 end rescue => e Rails.logger.error "[UserScore#joint] ===> Exception: #{e}." end # 前略·影响力得分 # operate - 更新操作 类型 symbol # user - 计分用户 # # Examples # # UserScore.influence(:followed_by, user) # # => true #当前被关注用户记分成功 # # Returns boolean. 返回积分保存结果 def self.influence(operate, current_user, target_user,obj, options={}) current_user, target_user = get_users(current_user, target_user) user_score = target_user.user_score_attr case operate when :followed_by # current_user 关注了target_user Add watcher user_score.influence = user_score.influence.to_i + 2 user_score.save create_score_changed_details({:current_user_id => current_user.id ,:target_user_id =>target_user.id, :score_type => "influence",:score_action => "followed_by",:user_id => target_user.id,:old_score => user_score.influence - 2,:new_score => user_score.influence,:current_user_level => UserLevels.get_level(current_user),:target_user_level => UserLevels.get_level(target_user),:score_changeable_obj_id=> obj.id,:score_changeable_obj_type => obj.class.to_s}) Rails.logger.info "[UserScore#influence] ===> User: #{current_user} be followed. options => (#{options.to_s})" when :cancel_followed # current_uer 取消了对 target_user的关注 delete watcher user_score.influence = user_score.influence.to_i - 2 user_score.save create_score_changed_details({:current_user_id => current_user.id ,:target_user_id =>target_user.id, :score_type => "influence",:score_action => "cancel_followed",:user_id => target_user.id,:old_score => user_score.influence + 2,:new_score => user_score.influence,:current_user_level => UserLevels.get_level(current_user),:target_user_level => UserLevels.get_level(target_user),:score_changeable_obj_id=> obj.id,:score_changeable_obj_type => obj.class.to_s}) 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}." end # 前略·技术得分 # operate - 更新操作 类型 symbol # user - 计分用户 # # Examples # # UserScore.skill(:followed_by, current_user, target_user) # # => true #当前current_user对target_user用户帖子的记分成功 # # Returns boolean. 返回积分保存结果 def self.skill(operate, current_user, target_user,obj, options={}) current_user, target_user = get_users(current_user, target_user) current_user_score = current_user.user_score_attr target_user_score = target_user.user_score_attr current_user_grade = nil #项目个人得分 target_user_grade = nil project = obj.project unless project.nil? current_user_grade = UserGrade.find_by_user_id_and_project_id(current_user.id, project.id) target_user_grade = UserGrade.find_by_user_id_and_project_id(target_user.id, project.id) if current_user_grade.nil? current_user_grade = UserGrade.create(:user_id => current_user.id,:project_id => project.id) end if target_user_grade.nil? target_user_grade = UserGrade.create(:user_id => target_user.id,:project_id => project.id) end end 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 的帖子 current_user_score.skill = current_user_score.skill.to_i - 2 #踩别人的帖子减2分 add praise_tread current_user_score.save unless current_user_grade.nil? current_user_grade.grade = current_user_grade.grade - 2 current_user_grade.save end create_score_changed_details({:current_user_id => current_user.id ,:target_user_id =>target_user.id, :score_type => "skill",:score_action => "treaded_by_user",:user_id => current_user.id,:old_score => current_user_score.skill + 2,:new_score => current_user_score.skill,:current_user_level => UserLevels.get_level(current_user),:target_user_level => UserLevels.get_level(target_user),:score_changeable_obj_id=> obj.id,:score_changeable_obj_type => obj.class.to_s}) if current_user.id == target_user.id target_user.reload target_user_score = target_user.user_score_attr unless target_user_grade.nil? target_user_grade.reload end end level = UserLevels.get_level(current_user) if level == 1 target_user_score.skill = target_user_score.skill.to_i - 2 #帖子被一级会员踩-2分 add praise_tread target_user_score.save unless target_user_grade.nil? target_user_grade.grade = target_user_grade.grade - 2 target_user_grade.save end create_score_changed_details({:current_user_id => current_user.id ,:target_user_id =>target_user.id, :score_type => "skill",:score_action => "treaded_by_user",:user_id => target_user.id,:old_score => target_user_score.skill + 2,:new_score => target_user_score.skill,:current_user_level => UserLevels.get_level(current_user),:target_user_level => UserLevels.get_level(target_user),:score_changeable_obj_id=> obj.id,:score_changeable_obj_type => obj.class.to_s}) elsif level == 2 target_user_score.skill = target_user_score.skill.to_i - 4 #帖子被二级会员踩-4分 add praise_tread target_user_score.save unless target_user_grade.nil? target_user_grade.grade = target_user_grade.grade - 4 target_user_grade.save end create_score_changed_details({:current_user_id => current_user.id ,:target_user_id =>target_user.id, :score_type => "skill",:score_action => "treaded_by_user",:user_id => target_user.id,:old_score => target_user_score.skill + 4,:new_score => target_user_score.skill,:current_user_level => UserLevels.get_level(current_user),:target_user_level => UserLevels.get_level(target_user),:score_changeable_obj_id=> obj.id,:score_changeable_obj_type => obj.class.to_s}) elsif level == 3 target_user_score.skill = target_user_score.skill.to_i - 6 #帖子被三级会员踩-6分 add praise_tread target_user_score.save unless target_user_grade.nil? target_user_grade.grade = target_user_grade.grade - 6 target_user_grade.save end create_score_changed_details({:current_user_id => current_user.id ,:target_user_id =>target_user.id, :score_type => "skill",:score_action => "treaded_by_user",:user_id => target_user.id,:old_score => target_user_score.skill + 6,:new_score => target_user_score.skill,:current_user_level => UserLevels.get_level(current_user),:target_user_level => UserLevels.get_level(target_user),:score_changeable_obj_id=> obj.id,:score_changeable_obj_type => obj.class.to_s}) 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 的帖子 level = UserLevels.get_level(current_user) if level == 1 target_user_score.skill = target_user_score.skill.to_i + 4 #帖子被一级会员顶+4分 add praise_tread target_user_score.save unless target_user_grade.nil? target_user_grade.grade = target_user_grade.grade + 4 target_user_grade.save end create_score_changed_details({:current_user_id => current_user.id ,:target_user_id =>target_user.id, :score_type => "skill",:score_action => "praised_by_user",:user_id => target_user.id,:old_score => target_user_score.skill - 4,:new_score => target_user_score.skill,:current_user_level => UserLevels.get_level(current_user),:target_user_level => UserLevels.get_level(target_user),:score_changeable_obj_id=> obj.id,:score_changeable_obj_type => obj.class.to_s}) elsif level == 2 target_user_score.skill = target_user_score.skill.to_i + 6 #帖子被二级会员顶+6分 add praise_tread target_user_score.save unless target_user_grade.nil? target_user_grade.grade = target_user_grade.grade + 6 target_user_grade.save end create_score_changed_details({:current_user_id => current_user.id ,:target_user_id =>target_user.id, :score_type => "skill",:score_action => "praised_by_user",:user_id => target_user.id,:old_score => target_user_score.skill - 6,:new_score => target_user_score.skill,:current_user_level => UserLevels.get_level(current_user),:target_user_level => UserLevels.get_level(target_user),:score_changeable_obj_id=> obj.id,:score_changeable_obj_type => obj.class.to_s}) elsif level == 3 target_user_score.skill = target_user_score.skill.to_i + 8 #帖子被三级会员顶+8分 add praise_tread target_user_score.save unless target_user_grade.nil? target_user_grade.grade = target_user_grade.grade + 8 target_user_grade.save end create_score_changed_details({:current_user_id => current_user.id ,:target_user_id =>target_user.id, :score_type => "skill",:score_action => "praised_by_user",:user_id => target_user.id,:old_score => target_user_score.skill - 8,:new_score => target_user_score.skill,:current_user_level => UserLevels.get_level(current_user),:target_user_level => UserLevels.get_level(target_user),:score_changeable_obj_id=> obj.id,:score_changeable_obj_type => obj.class.to_s}) 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." return false end rescue => e Rails.logger.error "[UserScore#skill] ===> Exception: #{e}." end # 前略·项目得分 # operate - 更新操作 类型 symbol # user - 计分用户 # # Examples # # UserScore.project(:pull_code, current_user) # # => true #当前current_user对项目贡献积分成功 # # Returns boolean. 返回积分保存结果 def self.project(operate, current_user,obj, options={}) current_user, target_user = get_users(current_user, nil) user_score = current_user.try(:user_score_attr) user_grade = nil #项目个人得分 project = obj.project unless project.nil? user_grade = UserGrade.find_by_user_id_and_project_id(current_user.id, project.id) if user_grade.nil? user_grade = UserGrade.create(:user_id => current_user.id,:project_id => project.id) end end return false if current_user.nil? case operate when :push_code # current_user 提交了代码 changeset user_score = user_score.active.to_i + 4 user_score.save unless user_grade.nil? user_grade.grade = user_grade.grade + 4 user_grade.save end create_score_changed_details({:current_user_id => current_user.id , :score_type => "active",:score_action => "push_code",:user_id => current_user.id,:old_score => user_score.active - 4,:new_score => user_score.active,:current_user_level => UserLevels.get_level(current_user),:score_changeable_obj_id=> obj.id,:score_changeable_obj_type => obj.class.to_s}) Rails.logger.debug "[UserScore#project] ===> User: [#{current_user.id},#{current_user.name}] pushed code one time. options => (#{options.to_s})" when :push_document # current_user 提交了文档 document user_score.active = user_score.active.to_i + 4 user_score.save unless user_grade.nil? user_grade.grade = user_grade.grade + 4 user_grade.save end create_score_changed_details({:current_user_id => current_user.id , :score_type => "active",:score_action => "push_document",:user_id => current_user.id,:old_score => user_score.active - 4,:new_score => user_score.active,:current_user_level => UserLevels.get_level(current_user),:score_changeable_obj_id=> obj.id,:score_changeable_obj_type => obj.class.to_s}) Rails.logger.debug "[UserScore#project] ===> User: [#{current_user.id},#{current_user.name}] pushed a document. options => (#{options.to_s})" when :push_file # current_user 提交了附件 attachment user_score.active = user_score.active.to_i + 4 user_score.save unless user_grade.nil? user_grade.grade = user_grade.grade + 4 user_grade.save end create_score_changed_details({:current_user_id => current_user.id , :score_type => "active",:score_action => "push_file",:user_id => current_user.id,:old_score => user_score.active - 4,:new_score => user_score.active,:current_user_level => UserLevels.get_level(current_user),:score_changeable_obj_id=> obj.id,:score_changeable_obj_type => obj.class.to_s}) Rails.logger.debug "[UserScore#project] ===> User: [#{current_user.id},#{current_user.name}] pushed a file. options => (#{options.to_s})" when :update_issue_ratio # current_user 更新了缺陷完成度 issue user_score.active = user_score.active.to_i + 2 user_score.save unless user_grade.nil? user_grade.grade = user_grade.grade + 2 user_grade.save end create_score_changed_details({:current_user_id => current_user.id , :score_type => "active",:score_action => "update_issue_ratio",:user_id => current_user.id,:old_score => user_score.active - 2,:new_score => user_score.active,:current_user_level => UserLevels.get_level(current_user),:score_changeable_obj_id=> obj.id,:score_changeable_obj_type => obj.class.to_s}) Rails.logger.debug "[UserScore#project] ===> User: [#{current_user.id},#{current_user.name}] updated issue ratio. options => (#{options.to_s})" when :post_issue # current_user 发布了缺陷 issue user_score.active = user_score.active.to_i + 4 user_score.save unless user_grade.nil? user_grade.grade = user_grade.grade + 4 user_grade.save end create_score_changed_details({:current_user_id => current_user.id , :score_type => "active",:score_action => "post_issue",:user_id => current_user.id,:old_score => user_score.active - 4,:new_score => user_score.active,:current_user_level => UserLevels.get_level(current_user),:score_changeable_obj_id=> obj.id,:score_changeable_obj_type => obj.class.to_s}) Rails.logger.debug "[UserScore#project] ===> User: [#{current_user.id},#{current_user.name}] posting issue. options => (#{options.to_s})" else Rails.logger.error "[UserScore#project] ===> #{operate} is not define." return false end rescue => e Rails.logger.error "[UserScore#project] ===> Exception: #{e}." end #获取用户的user_score def self.score(user) if user.user_score.nil? us = UserScore.new us.user_id = user.id us.save us else user.user_score end end #计算总得分 def total_score score = self.influence.to_i + self.skill.to_i + self.collaboration.to_i + self.active.to_i score end #创建分数改变记录 -by zjc def self.create_score_changed_details(attributes) if attributes.is_a? Hash usd = UserScoreDetails.new usd.current_user_id =attributes[:current_user_id] usd.target_user_id = attributes[:target_user_id] usd.score_type = attributes[:score_type] usd.score_action = attributes[:score_action] usd.user_id = attributes[:user_id] usd.old_score = attributes[:old_score] usd.new_score = attributes[:new_score] usd.current_user_level = attributes[:current_user_level] usd.target_user_level = attributes[:target_user_level] #usd.score_changeable_obj = attributes[:score_changeable_obj] usd.score_changeable_obj_id = attributes[:score_changeable_obj_id] usd.score_changeable_obj_type = attributes[:score_changeable_obj_type] usd.save end end private def self.get_users(current_user, target_user) cUser = (current_user.kind_of?User) ? current_user : User.find_by_id(current_user) tUser = (target_user.kind_of?User) ? target_user : User.find_by_id(target_user) [cUser, tUser] end #修正分数 #分数小于0时修正为0 #分数大于等于0时不修正 -by zjc def correct_score if !self.collaboration.nil? && self.collaboration < 0 self.collaboration = 0 end if !self.influence.nil? && self.influence < 0 self.influence = 0 end if !self.skill.nil? && self.skill < 0 self.skill = 0 end if !self.active.nil? && self.active < 0 self.active = 0 end end end