From fa27d3bf32d0f46d8a3a783a8a028a0f2dfed942 Mon Sep 17 00:00:00 2001 From: nieguanghui Date: Wed, 28 Aug 2013 09:34:54 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=A1=B9=E7=9B=AE=E5=92=8C?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E7=9A=84=E6=8E=92=E5=BA=8F=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/account_controller.rb | 3 + app/controllers/projects_controller.rb | 193 +++++++++++------- app/controllers/users_controller.rb | 55 ++++- app/models/changeset.rb | 5 + app/models/project.rb | 1 - app/models/watcher.rb | 4 + app/views/projects/index.html.erb | 15 ++ app/views/users/index.html.erb | 15 ++ .../20130823133435_create_project_statuses.rb | 9 + .../20130823143552_create_user_statuses.rb | 11 + .../20130828004955_stored_status_procedure.rb | 76 +++++++ db/schema.rb | 33 ++- 12 files changed, 338 insertions(+), 82 deletions(-) create mode 100644 db/migrate/20130823133435_create_project_statuses.rb create mode 100644 db/migrate/20130823143552_create_user_statuses.rb create mode 100644 db/migrate/20130828004955_stored_status_procedure.rb diff --git a/app/controllers/account_controller.rb b/app/controllers/account_controller.rb index 879c61c0a..f588bf48d 100644 --- a/app/controllers/account_controller.rb +++ b/app/controllers/account_controller.rb @@ -282,6 +282,7 @@ class AccountController < ApplicationController def register_by_email_activation(user, &block) token = Token.new(:user => user, :action => "register") if user.save and token.save + UserStatus.create(:user_id => user.id) Mailer.register(token).deliver flash[:notice] = l(:notice_account_register_done) redirect_to signin_path @@ -298,6 +299,7 @@ class AccountController < ApplicationController user.activate user.last_login_on = Time.now if user.save + UserStatus.create(:user_id => user.id) self.logged_user = user flash[:notice] = l(:notice_account_activated) redirect_to my_account_path @@ -311,6 +313,7 @@ class AccountController < ApplicationController # Pass a block for behavior when a user fails to save def register_manually_by_administrator(user, &block) if user.save + UserStatus.create(:user_id => user.id) # Sends an email to the administrators Mailer.account_activation_request(user).deliver account_pending diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index a31fd18aa..cc4fda9fe 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -14,7 +14,6 @@ # 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 ProjectsController < ApplicationController layout 'base_projects'# by young menu_item :overview @@ -51,71 +50,117 @@ class ProjectsController < ApplicationController helper :activities helper :documents helper :watchers -# helper :watcherlist - + # helper :watcherlist + ### added by william include ActsAsTaggableOn::TagsHelper # Lists visible projects -# def index -# respond_to do |format| -# format.html { -# scope = Project -# unless params[:closed] -# scope = scope.active -# end -# @projects = scope.visible.order('lft').all -# } -# format.api { -# @offset, @limit = api_offset_and_limit -# @project_count = Project.visible.count -# @projects = Project.visible.offset(@offset).limit(@limit).order('lft').all -# } -# format.atom { -# projects = Project.visible.order('created_on DESC').limit(Setting.feeds_limit.to_i).all -# render_feed(projects, :title => "#{Setting.app_title}: #{l(:label_project_latest)}") -# } -# end -# end + # def index + # respond_to do |format| + # format.html { + # scope = Project + # unless params[:closed] + # scope = scope.active + # end + # @projects = scope.visible.order('lft').all + # } + # format.api { + # @offset, @limit = api_offset_and_limit + # @project_count = Project.visible.count + # @projects = Project.visible.offset(@offset).limit(@limit).order('lft').all + # } + # format.atom { + # projects = Project.visible.order('created_on DESC').limit(Setting.feeds_limit.to_i).all + # render_feed(projects, :title => "#{Setting.app_title}: #{l(:label_project_latest)}") + # } + # end + # end def index #Modified by nie # @offset, @limit = api_offset_and_limit({:limit => 10}) # @project_count = Project.visible.count # @project_pages = Paginator.new @project_count, @limit, params['page'] - # @offset ||= @project_pages.offset + # @offset ||= @project_pages.offset # @projects = Project.visible.offset(@offset).limit(@limit).order('lft').all - + @offset, @limit = api_offset_and_limit({:limit => 10}) @projects = Project.visible # @projects.each do |project| - # @admin = project.users_by_role[Role.find(3)] - # unless @admin.nil? - # @admin.each do |user| - # ProjectInfo.create(:user_id => user.id, :project_id => project.id) - # end -# - # end + # @admin = project.users_by_role[Role.find(3)] + # unless @admin.nil? + # @admin.each do |user| + # ProjectInfo.create(:user_id => user.id, :project_id => project.id) + # end + # + # end + # end + # @projects.each do |project| + # ProjectStatus.create(:changesets_count => project.changesets.count, :project_id => project.id, :watchers_count => project.watcher_users.count) # end @projects = Project.visible.like(params[:name]) if params[:name].present? - @project_count = @projects.count + @project_count = @projects.count @project_pages = Paginator.new @project_count, @limit, params['page'] - @offset ||= @project_pages.offset - @projects = @projects.offset(@offset).limit(@limit).order('created_on DESC').all + + @offset ||= @project_pages.reverse_offset + #@projects = @projects.offset(@offset).limit(@limit).order('created_on DESC').all + if params[:project_sort_type].present? + case params[:project_sort_type] + when '0' + @offset ||= @project_pages.reverse_offset + unless @offset == 0 + @projects = @projects.offset(@offset).limit(@limit).all.reverse + else + limit = @project_count % @limit + @projects = @projects.offset(@offset).limit(limit).all.reverse + end + # @projects = @projects.sort {|x,y| y.created_on <=> x.created_on } + # @projects = @projects[@offset, @limit] + when '1' + @offset ||= @project_pages.reverse_offset + unless @offset == 0 + @projects = @projects.includes(:project_status).reorder('project_statuses.changesets_count').offset(@offset).limit(@limit).all.reverse + else + limit = @project_count % @limit + @projects = @projects.includes(:project_status).reorder('project_statuses.changesets_count').offset(@offset).limit(limit).all.reverse + end + + #@projects = @projects[@offset, @limit] + when '2' + @offset ||= @project_pages.reverse_offset + unless @offset == 0 + @projects = @projects.includes(:project_status).reorder('project_statuses.watchers_count').offset(@offset).limit(@limit).all.reverse + else + limit = @project_count % @limit + @projects = @projects.includes(:project_status).reorder('project_statuses.watchers_count').offset(@offset).limit(limit).all.reverse + end + end + else + @offset ||= @project_pages.reverse_offset + unless @offset == 0 + @projects = @projects.offset(@offset).limit(@limit).all.reverse + else + limit = @project_count % @limit + @projects = @projects.offset(@offset).limit(limit).all.reverse + end + # @projects = @projects.sort {|x,y| y.created_on <=> x.created_on } + # @projects = @projects[@offset, @limit] + + end #end - respond_to do |format| + respond_to do |format| format.html { - render :layout => 'base' + render :layout => 'base' scope = Project unless params[:closed] - scope = scope.active + scope = scope.active end - @projects = scope.visible.offset(@offset).limit(@limit).order('created_on DESC').all } format.api { -# @offset, @limit = api_offset_and_limit -# @project_count = Project.visible.count -# @projects = Project.visible.offset(@offset).limit(@limit).order('lft').all + # @offset, @limit = api_offset_and_limit + # @project_count = Project.visible.count + # @projects = Project.visible.offset(@offset).limit(@limit).order('lft').all } format.atom { projects = Project.visible.order('created_on DESC').limit(Setting.feeds_limit.to_i).all @@ -123,7 +168,7 @@ class ProjectsController < ApplicationController } end end - + def feedback @jours = @project.journals_for_messages.reverse @limit = 10 @@ -139,7 +184,7 @@ class ProjectsController < ApplicationController @trackers = Tracker.sorted.all @project = Project.new @project.safe_attributes = params[:project] - render :layout => 'base' + render :layout => 'base' end def create @@ -155,8 +200,9 @@ class ProjectsController < ApplicationController r = Role.givable.find_by_id(Setting.new_project_user_role_id.to_i) || Role.givable.first m = Member.new(:user => User.current, :roles => [r]) project = ProjectInfo.new(:user_id => User.current.id, :project_id => @project.id) - @project.members << m - @project.project_infos << project + project_status = ProjectStatus.create(:project_id => @project.id) + @project.members << m + @project.project_infos << project end respond_to do |format| format.html { @@ -203,15 +249,15 @@ class ProjectsController < ApplicationController end end rescue ActiveRecord::RecordNotFound - # source_project not found + # source_project not found render_404 - end + end # Show @project def show # try to redirect to the requested menu item if params[:jump] && redirect_to_project_menu_item(@project, params[:jump]) - return + return end @users_by_role = @project.users_by_role @@ -229,13 +275,13 @@ class ProjectsController < ApplicationController end @key = User.current.rss_key - #新增内容 + #新增内容 @days = Setting.activity_days_default.to_i if params[:from] begin; @date_to = params[:from].to_date + 1; rescue; end end - + has = { "show_issues" => true, "show_files" => true, @@ -246,24 +292,24 @@ class ProjectsController < ApplicationController @date_from = @date_to - @days @with_subprojects = params[:with_subprojects].nil? ? Setting.display_subprojects_issues? : (params[:with_subprojects] == '1') @author = (params[:user_id].blank? ? nil : User.active.find(params[:user_id])) -# 决定显示所用用户或单个用户活动 + # 决定显示所用用户或单个用户活动 @activity = Redmine::Activity::Fetcher.new(User.current, :project => @project, :with_subprojects => @with_subprojects, :author => @author) @activity.scope_select {|t| !has["show_#{t}"].nil?} - # @activity.scope = (@author.nil? ? :default : :all) if @activity.scope.empty? + # @activity.scope = (@author.nil? ? :default : :all) if @activity.scope.empty? #Added by young events = @activity.events(@date_from, @date_to) - + @offset, @limit = api_offset_and_limit({:limit => 10}) @events_count = events.count @events_pages = Paginator.new @events_count, @limit, params['page'] - @offset ||= @events_pages.offset + @offset ||= @events_pages.offset events = events.slice(@offset,@limit) #Ended by young @events_by_day = events.group_by {|event| User.current.time_to_date(event.event_datetime)} - # documents - @sort_by = %w(category date title author).include?(params[:sort_by]) ? params[:sort_by] : 'category' + # documents + @sort_by = %w(category date title author).include?(params[:sort_by]) ? params[:sort_by] : 'category' documents = @project.documents.includes(:attachments, :category).all case @sort_by when 'date' @@ -273,16 +319,15 @@ class ProjectsController < ApplicationController when 'author' @grouped = documents.select{|d| d.attachments.any?}.group_by {|d| d.attachments.last.author} else - @grouped = documents.group_by(&:category) + @grouped = documents.group_by(&:category) end @document = @project.documents.build -# + # respond_to do |format| format.html format.api end end - def settings @issue_custom_fields = IssueCustomField.sorted.all @@ -294,17 +339,16 @@ class ProjectsController < ApplicationController def edit end - + #by young def member end - - + def file end - + def statistics - + end #end @@ -369,9 +413,9 @@ class ProjectsController < ApplicationController format.html { redirect_to admin_projects_path } format.api { render_api_ok } end - else - render :layout => "base" - end + else + render :layout => "base" + end # hide project in layout @project = nil end @@ -387,18 +431,17 @@ class ProjectsController < ApplicationController parent = parent_id.blank? ? nil : Project.find_by_id(parent_id.to_i) unless @project.allowed_parents.include?(parent) @project.errors.add :parent_id, :invalid - return false + return false end end true end -end -# added by huang -def watcherlist + # added by huang + + def watcherlist if @watched - @users -= watched.watcher_users + @users -= watched.watcher_users end - + end end -# end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index ce62f3423..af726d413 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -138,7 +138,7 @@ class UsersController < ApplicationController end #end - def index + def index sort_init 'login', 'asc' sort_update %w(login firstname lastname mail admin created_on last_login_on) @@ -154,16 +154,61 @@ class UsersController < ApplicationController "show_changesets" => true } # @count = Redmine::Activity::Fetcher.new(User.current, :author => @user).scope_select {|t| !has["show_#{t}"].nil?}.events(nil, nil).count - + scope = User.logged.status(@status) scope = scope.like(params[:name]) if params[:name].present? scope = scope.in_group(params[:group_id]) if params[:group_id].present? - + # scope.each do |user| + # UserStatus.create(:changesets_count => user.changesets.count, :watchers_count => user.watcher_users.count, :user_id => user.id) + # end @user_count = scope.count @user_pages = Paginator.new @user_count, @limit, params['page'] - @offset ||= @user_pages.offset - @users = scope.order(sort_clause).limit(@limit).offset(@offset).all + #@offset ||= @user_pages.offset + #@users = scope.order(sort_clause).limit(@limit).offset(@offset).all @user_base_tag = params[:id]?'base_users':'base' + if params[:user_sort_type].present? + case params[:user_sort_type] + when '0' + @offset ||= @user_pages.reverse_offset + unless @offset == 0 + @users = scope.offset(@offset).limit(@limit).all.reverse + else + limit = @user_count % @limit + @users = scope.offset(@offset).limit(limit).all.reverse + end + # @projects = @projects.sort {|x,y| y.created_on <=> x.created_on } + # @projects = @projects[@offset, @limit] + when '1' + @offset ||= @user_pages.reverse_offset + unless @offset == 0 + @users = scope.includes(:user_status).reorder('user_statuses.changesets_count').offset(@offset).limit(@limit).all.reverse + else + limit = @user_count % @limit + @users = scope.includes(:user_status).reorder('user_statuses.changesets_count').offset(@offset).limit(limit).all.reverse + end + #sort {|x,y| y.user_status.changesets_count <=> x.user_status.changesets_count} + #@users = @users[@offset, @limit] + when '2' + @offset ||= @user_pages.reverse_offset + unless @offset == 0 + @users = scope.includes(:user_status).reorder('user_statuses.watchers_count').offset(@offset).limit(@limit).all.reverse + else + limit = @user_count % @limit + @users = scope.includes(:user_status).reorder('user_statuses.watchers_count').offset(@offset).limit(limit).all.reverse + end + #@users = @users[@offset, @limit] + end + else + @offset ||= @user_pages.reverse_offset + unless @offset == 0 + @users = scope.offset(@offset).limit(@limit).all.reverse + else + limit = @user_count % @limit + @users = scope.offset(@offset).limit(limit).all.reverse + end + # @projects = @projects.sort {|x,y| y.created_on <=> x.created_on } + # @projects = @projects[@offset, @limit] + end respond_to do |format| format.html { @groups = Group.all.sort diff --git a/app/models/changeset.rb b/app/models/changeset.rb index b46f7a312..e3e7ac705 100644 --- a/app/models/changeset.rb +++ b/app/models/changeset.rb @@ -23,6 +23,11 @@ class Changeset < ActiveRecord::Base has_many :acts, :class_name => 'Activity', :as => :act, :dependent => :destroy # end + #Added by nie + has_one :project_status, :dependent => :destroy + has_one :users_status + #end + has_and_belongs_to_many :issues has_and_belongs_to_many :parents, :class_name => "Changeset", diff --git a/app/models/project.rb b/app/models/project.rb index 31cf1c934..bd856f7d0 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -57,7 +57,6 @@ class Project < ActiveRecord::Base #ADDED BY NIE has_many :project_infos, :dependent => :destroy has_one :project_status, :class_name => "ProjectStatus", :dependent => :destroy - #end has_one :wiki, :dependent => :destroy # Custom field for the project issues diff --git a/app/models/watcher.rb b/app/models/watcher.rb index 1cea711b7..853e0cf6b 100644 --- a/app/models/watcher.rb +++ b/app/models/watcher.rb @@ -18,6 +18,10 @@ class Watcher < ActiveRecord::Base belongs_to :watchable, :polymorphic => true belongs_to :user + #Added by nie + has_one :project_status + has_one :users_status + #end validates_presence_of :user validates_uniqueness_of :user_id, :scope => [:watchable_type, :watchable_id] diff --git a/app/views/projects/index.html.erb b/app/views/projects/index.html.erb index 8f4852ef5..98ca363ad 100644 --- a/app/views/projects/index.html.erb +++ b/app/views/projects/index.html.erb @@ -19,6 +19,21 @@ <%end%> + + +
<%= render_project_hierarchy(@projects)%>
diff --git a/app/views/users/index.html.erb b/app/views/users/index.html.erb index 18b926de9..b13639877 100644 --- a/app/views/users/index.html.erb +++ b/app/views/users/index.html.erb @@ -86,6 +86,21 @@   + + +
<% for user in @users -%> <% unless user.id == 1%> diff --git a/db/migrate/20130823133435_create_project_statuses.rb b/db/migrate/20130823133435_create_project_statuses.rb new file mode 100644 index 000000000..dc808ea45 --- /dev/null +++ b/db/migrate/20130823133435_create_project_statuses.rb @@ -0,0 +1,9 @@ +class CreateProjectStatuses < ActiveRecord::Migration + def change + create_table :project_statuses do |t| + t.integer :changesets_count + t.integer :watchers_count + t.integer :project_id + end + end +end diff --git a/db/migrate/20130823143552_create_user_statuses.rb b/db/migrate/20130823143552_create_user_statuses.rb new file mode 100644 index 000000000..eacd1acdd --- /dev/null +++ b/db/migrate/20130823143552_create_user_statuses.rb @@ -0,0 +1,11 @@ +class CreateUserStatuses < ActiveRecord::Migration + def change + create_table :user_statuses do |t| + t.integer :changesets_count + t.integer :watchers_count + t.integer :user_id + + t.timestamps + end + end +end diff --git a/db/migrate/20130828004955_stored_status_procedure.rb b/db/migrate/20130828004955_stored_status_procedure.rb new file mode 100644 index 000000000..91b37ecd2 --- /dev/null +++ b/db/migrate/20130828004955_stored_status_procedure.rb @@ -0,0 +1,76 @@ +class StoredStatusProcedure < ActiveRecord::Migration + def up + #sql = <<- END_OF_SQL_CODE + execute " +create procedure `sp_user_status_cursor`() +begin + declare v_uid bigint(22); + declare v int(10); + declare _done TINYINT(1) default 0; + declare cur_user cursor for select user_id, count(*) from changesets where user_id != '' group by user_id; + declare continue handler for not found set _done = 1; + open cur_user; + loop_xxx:loop + fetch cur_user into v_uid,v; + if _done=1 then + leave loop_xxx; + end if; + begin + update user_statuses set changesets_count = v where user_id = v_uid; + commit; + end; + end loop; +end; +" + execute " + create event if not exists e_test +on schedule every 1 day starts'2013_08_27 01:50:00' +on completion preserve +do call `sp_user_status_cursor`(); +" + execute " + create procedure `sp_project_status_cursor`() +begin + declare v_uid bigint(22); + declare v int(10); + declare _done TINYINT(1) default 0; + declare cur_user cursor for select project_id,count(*) from (select project_id,repositories.id from repositories inner join changesets where repositories.id = changesets.repository_id)t group by project_id; + declare continue handler for not found set _done = 1; + open cur_user; + loop_xxx:loop + fetch cur_user into v_uid,v; + if _done=1 then + leave loop_xxx; + end if; + begin + update project_statuses set changesets_count = v where project_id = v_uid; + commit; + end; + end loop; +end; +" + execute " + create event if not exists e_project_status_test +on schedule every 1 day starts'2013_08_27 01:50:00' +on completion preserve +do call `sp_project_status_cursor`(); +" + execute " + set global event_scheduler = on; +" + end + + def down + execute " drop procedure if exists `sp_user_status_cursor`; + " + execute " + drop event if exists e_test; + " + execute " + drop procedure if exists `sp_project_status_cursor`; + " + execute " + drop event if exists e_project_status_test; + " + end +end diff --git a/db/schema.rb b/db/schema.rb index d8bbd14f8..bc3ecca3c 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20130819020004) do +ActiveRecord::Schema.define(:version => 20130828004955) do create_table "a_user_watchers", :force => true do |t| t.string "name" @@ -445,6 +445,23 @@ ActiveRecord::Schema.define(:version => 20130819020004) do t.string "salt", :null => false end + create_table "permissions", :force => true do |t| + t.string "controller", :limit => 30, :default => "", :null => false + t.string "action", :limit => 30, :default => "", :null => false + t.string "description", :limit => 60, :default => "", :null => false + t.boolean "is_public", :default => false, :null => false + t.integer "sort", :default => 0, :null => false + t.boolean "mail_option", :default => false, :null => false + t.boolean "mail_enabled", :default => false, :null => false + end + + create_table "permissions_roles", :id => false, :force => true do |t| + t.integer "permission_id", :default => 0, :null => false + t.integer "role_id", :default => 0, :null => false + end + + add_index "permissions_roles", ["role_id"], :name => "permissions_roles_role_id" + create_table "praise_tread_caches", :force => true do |t| t.integer "object_id", :null => false t.string "object_type" @@ -470,6 +487,12 @@ ActiveRecord::Schema.define(:version => 20130819020004) do t.datetime "updated_at", :null => false end + create_table "project_statuses", :force => true do |t| + t.integer "changesets_count" + t.integer "watchers_count" + t.integer "project_id" + end + create_table "project_tags", :force => true do |t| t.integer "project_id" t.integer "tag_id" @@ -648,6 +671,14 @@ ActiveRecord::Schema.define(:version => 20130819020004) do add_index "user_preferences", ["user_id"], :name => "index_user_preferences_on_user_id" + create_table "user_statuses", :force => true do |t| + t.integer "changesets_count" + t.integer "watchers_count" + t.integer "user_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + create_table "user_tags", :force => true do |t| t.integer "user_id" t.integer "tag_id"