diff --git a/app/controllers/apply_project_masters_controller.rb b/app/controllers/apply_project_masters_controller.rb index 7dadaf2ed..9e5c52348 100644 --- a/app/controllers/apply_project_masters_controller.rb +++ b/app/controllers/apply_project_masters_controller.rb @@ -1,4 +1,7 @@ class ApplyProjectMastersController < ApplicationController + + before_filter :require_login, :find_apply, :only => [:create, :delete] + # GET /apply_project_masters # GET /apply_project_masters.json def index @@ -40,17 +43,20 @@ class ApplyProjectMastersController < ApplicationController # POST /apply_project_masters # POST /apply_project_masters.json def create - @apply_project_master = ApplyProjectMaster.new(params[:apply_project_master]) - - respond_to do |format| - if @apply_project_master.save - format.html { redirect_to @apply_project_master, notice: 'Apply project master was successfully created.' } - format.json { render json: @apply_project_master, status: :created, location: @apply_project_master } - else - format.html { render action: "new" } - format.json { render json: @apply_project_master.errors, status: :unprocessable_entity } - end - end + # @apply_project_master = ApplyProjectMaster.new(params[:apply_project_master]) +# + # respond_to do |format| + # if @apply_project_master.save + # format.html { redirect_to @apply_project_master, notice: 'Apply project master was successfully created.' } + # format.json { render json: @apply_project_master, status: :created, location: @apply_project_master } + # else + # format.html { render action: "new" } + # format.json { render json: @apply_project_master.errors, status: :unprocessable_entity } + # end + # end + + set_apply(@apply, User.current, true) + end # PUT /apply_project_masters/1 @@ -80,4 +86,29 @@ class ApplyProjectMastersController < ApplicationController format.json { head :no_content } end end + + def delete + set_apply(@apply, User.current, false) + end + + private + + def find_apply + klass = Object.const_get(params[:object_type].camelcase) rescue nil + if klass && klass.respond_to?('applied_by') + @apply = klass.find_all_by_id(Array.wrap(params[:object_id])) + end + render_404 unless @apply.present? + end + + #flag标注功能,为1时设置‘申请版主’,为0时设置取消 + def set_apply(objects, user, flag) + objects.each do |object| + object.set_apply(user, flag) + end + respond_to do |format| + format.html { redirect_to_referer_or {render :text => (watching ? 'Watcher added.' : 'Watcher removed.'), :layout => true}} + format.js { render :partial => 'set_apply', :locals => {:user => user, :objects => objects} } + end + end end diff --git a/app/controllers/no_uses_controller.rb b/app/controllers/no_uses_controller.rb index c18c6c3b6..f66997107 100644 --- a/app/controllers/no_uses_controller.rb +++ b/app/controllers/no_uses_controller.rb @@ -1,9 +1,12 @@ class NoUsesController < ApplicationController + + before_filter :require_login, :find_no_use, :only => [:create, :delete] + # GET /no_uses # GET /no_uses.json def index @no_uses = NoUse.all - + respond_to do |format| format.html # index.html.erb format.json { render json: @no_uses } @@ -40,17 +43,20 @@ class NoUsesController < ApplicationController # POST /no_uses # POST /no_uses.json def create - @no_use = NoUse.new(params[:no_use]) + set_no_use(@no_use, User.current, true) - respond_to do |format| - if @no_use.save - format.html { redirect_to @no_use, notice: 'No use was successfully created.' } - format.json { render json: @no_use, status: :created, location: @no_use } - else - format.html { render action: "new" } - format.json { render json: @no_use.errors, status: :unprocessable_entity } - end - end + # respond_to do |format| + # if @no_use.save + # format.html { redirect_to @no_use, notice: 'No use was successfully created.' } + # format.json { render json: @no_use, status: :created, location: @no_use } + # else + # format.html { render action: "new" } + # format.json { render json: @no_use.errors, status: :unprocessable_entity } + # end + # end + end + def delete + set_no_use(@no_use, User.current, false) end # PUT /no_uses/1 @@ -72,52 +78,34 @@ class NoUsesController < ApplicationController # DELETE /no_uses/1 # DELETE /no_uses/1.json def destroy - @no_use = NoUse.find(params[:id]) - @no_use.destroy + # @no_use = NoUse.find(params[:id]) + # @no_use.destroy + + set_no_use(@no_use, User.current, false) - respond_to do |format| - format.html { redirect_to no_uses_url } - format.json { head :no_content } - end + # respond_to do |format| + # format.html { redirect_to no_uses_url } + # format.json { head :no_content } + # end end private def find_no_use klass = Object.const_get(params[:object_type].camelcase) rescue nil - if klass && klass.respond_to?('watched_by') + if klass && klass.respond_to?('no_use_for') @no_use = klass.find_all_by_id(Array.wrap(params[:object_id])) end render_404 unless @no_use.present? end - def set_watcher(watchables, user, watching) - watchables.each do |watchable| - watchable.set_watcher(user, watching) - # @user = watchable # added by william - if watching - # 修改 user和project的状态 - if watchable.instance_of?(User) - #写user_statuses表 - UserStatus.find_by_user_id(watchable.id).update_watchers_count(1) - elsif watchable.instance_of?(Project) - #写project_statuese表 - ProjectStatus.find_by_project_id(watchable.id).update_watchers_count(1) - end - else - # 修改 user和project的状态 - if watchable.instance_of?(User) - #写user_statuses表 - UserStatus.find_by_user_id(watchable.id).update_watchers_count(-1) - elsif watchable.instance_of?(Project) - #写project_statuese表 :project_status - ProjectStatus.find_by_project_id(watchable.id).update_watchers_count(-1) - end - end - + #flag标注功能,为1时设置‘没有帮助’,为0时设置取消 + def set_no_use(objects, user, flag) + objects.each do |object| + object.set_no_use(user, flag) end respond_to do |format| format.html { redirect_to_referer_or {render :text => (watching ? 'Watcher added.' : 'Watcher removed.'), :layout => true}} - format.js { render :partial => 'set_watcher', :locals => {:user => user, :watched => watchables} } + format.js { render :partial => 'set_no_use', :locals => {:user => user, :objects => objects} } end end end diff --git a/app/controllers/relative_memos_controller.rb b/app/controllers/relative_memos_controller.rb index 98ca8cd52..70d2f00c2 100644 --- a/app/controllers/relative_memos_controller.rb +++ b/app/controllers/relative_memos_controller.rb @@ -2,6 +2,15 @@ class RelativeMemosController < ApplicationController helper :sort include SortHelper + helper :apply_project_masters + include ApplyProjectMastersHelper + helper :no_uses + include NoUsesHelper + + before_filter :find_memo, :except => [:new, :create] + + layout 'base_opensource_p' + # GET /open_source_projects # GET /open_source_projects.json def index @@ -22,42 +31,41 @@ class RelativeMemosController < ApplicationController # GET /open_source_projects/1 # GET /open_source_projects/1.json + REPLIES_PER_PAGE = 20 unless const_defined?(:REPLIES_PER_PAGE) def show - # @open_source_project = OpenSourceProject.find(params[:id]) -# - # sort_init 'updated_at', 'desc' - # sort_update 'created_at' => "#{RelativeMemo.table_name}.created_at", - # 'replies' => "#{RelativeMemo.table_name}.replies_count", - # 'updated_at' => "COALESCE (last_replies_relative_memos.created_at, #{RelativeMemo.table_name}.created_at)" -# - # @memo = RelativeMemo.new(:open_source_project => @open_source_project) - # @topic_count = @open_source_project.topics.count - # @topic_pages = Paginator.new @topic_count, per_page_option, params['page'] - # @memos = @open_source_project.topics. - # reorder("#{RelativeMemo.table_name}.sticky DESC"). - # includes(:last_reply). - # limit(@topic_pages.per_page). - # offset(@topic_pages.offset). - # order(sort_clause). - # all + pre_count = REPLIES_PER_PAGE + + @memo = @memo.root # 取出楼主,防止输入帖子id让回复作为主贴显示 + @memo.update_column(:viewed_count_local, (@memo.viewed_count_local.to_i + 1)) + + page = params[:page] + if params[:r] && page.nil? + offset = @memo.children.where("#{Memo.table_name}.id < ?", params[:r].to_i).count + page = 1 + offset / pre_count + else + + end + @reply_count = @memo.children.count + @reply_pages = Paginator.new @reply_count, pre_count, page + @replies = @memo.children. + includes(:author, :attachments). + reorder("#{RelativeMemo.table_name}.created_at ASC"). + limit(@reply_pages.per_page). + offset(@reply_pages.offset). + all + + @mome_new = Memo.new - - # @offset, @limit = api_offset_and_limit({:limit => 10}) - # @forum = Forum.find(params[:id]) - # @memos_all = @forum.topics - # @topic_count = @memos_all.count - # @topic_pages = Paginator.new @topic_count, @limit, params['page'] + # @memo = Memo.find_by_id(params[:id]) + # @forum = Forum.find(params[:forum_id]) + # @replies = @memo.replies + # @mome_new = Memo.new - # @offset ||= @topic_pages.offset - # @memos = @memos_all.offset(@offset).limit(@limit).all - - # respond_to do |format| - # format.html { - # render :layout => "base_opensource_p" - # } - # format.json { render json: @open_source_project } - # end + respond_to do |format| + format.html # show.html.erb + format.json { render json: @memo } + end end @@ -120,4 +128,21 @@ class RelativeMemosController < ApplicationController format.json { head :no_content } end end + + private + + def find_memo + return unless find_osp + @memo = @open_source_project.relative_memos.find(params[:id]) + rescue ActiveRecord::RecordNotFound + render_404 + nil + end + + def find_osp + @open_source_project = OpenSourceProject.find(params[:open_source_project_id]) + rescue ActiveRecord::RecordNotFound + render_404 + nil + end end diff --git a/app/helpers/apply_project_masters_helper.rb b/app/helpers/apply_project_masters_helper.rb index 11724cde0..a2dccba35 100644 --- a/app/helpers/apply_project_masters_helper.rb +++ b/app/helpers/apply_project_masters_helper.rb @@ -9,15 +9,23 @@ module ApplyProjectMastersHelper # css = @watch_flag ? ([watcher_css(objects), watched ? 'icon ' : 'icon '].join(' ') << options[0].to_s) : # ([watcher_css(objects), watched ? 'icon icon-fav ' : 'icon icon-fav-off '].join(' ') << options[0].to_s) + css = apply_css(objects) << options[0].to_s + text = applied ? (allowed ? ("123") : ("123")) : ("231") - url = apply_project_master_path( + url = apply_project_masters_path( :object_type => objects.first.class.to_s.underscore, :object_id => (objects.size == 1 ? objects.first.id : objects.map(&:id).sort) ) method = applied ? 'delete' : 'post' - link_to text, url, :remote => true, :method => method - #, :class => css + link_to text, url, :remote => true, :method => method, :class => css end + + def apply_css(objects) + objects = Array.wrap(objects) + id = (objects.size == 1 ? objects.first.id : 'bulk') + "#{objects.first.class.to_s.underscore}-#{id}-watcher" + end + end diff --git a/app/helpers/no_uses_helper.rb b/app/helpers/no_uses_helper.rb index 2c7c268fc..a7a5ac24b 100644 --- a/app/helpers/no_uses_helper.rb +++ b/app/helpers/no_uses_helper.rb @@ -5,18 +5,24 @@ module NoUsesHelper clicked = objects.any? {|object| object.no_use_for?(user)} # @watch_flag = (objects.first.instance_of?(User) or objects.first.instance_of?(Project) or (objects.first.instance_of?(Bid))) - # css = @watch_flag ? ([watcher_css(objects), watched ? 'icon ' : 'icon '].join(' ') << options[0].to_s) : + css = no_use_css(objects) << options[0].to_s # ([watcher_css(objects), watched ? 'icon icon-fav ' : 'icon icon-fav-off '].join(' ') << options[0].to_s) - text = clicked ? ("123") : ("231") + text = clicked ? l(:no_use) : l(:cancel_no_use) - url = apply_project_master_path( + url = no_uses_path( :object_type => objects.first.class.to_s.underscore, :object_id => (objects.size == 1 ? objects.first.id : objects.map(&:id).sort) ) method = clicked ? 'delete' : 'post' - link_to text, url, :remote => true, :method => method + link_to text, url, :remote => true, :method => method, :class => css #, :class => css end + + def no_use_css(objects) + objects = Array.wrap(objects) + id = (objects.size == 1 ? objects.first.id : 'bulk') + "#{objects.first.class.to_s.underscore}-#{id}-watcher" + end end diff --git a/app/models/apply_project_master.rb b/app/models/apply_project_master.rb index 336c102df..f4d21b2bb 100644 --- a/app/models/apply_project_master.rb +++ b/app/models/apply_project_master.rb @@ -1,3 +1,15 @@ class ApplyProjectMaster < ActiveRecord::Base # attr_accessible :title, :body + belongs_to :apply, :polymorphic => true + belongs_to :user + + validates_presence_of :user + validates_uniqueness_of :user_id, :scope => [:apply_type, :apply_id] + validate :validate_user + + protected + + def validate_user + errors.add :user_id, :invalid unless user.nil? || user.active? + end end diff --git a/app/models/no_use.rb b/app/models/no_use.rb index 333174a8d..a46e519e8 100644 --- a/app/models/no_use.rb +++ b/app/models/no_use.rb @@ -1,3 +1,15 @@ class NoUse < ActiveRecord::Base # attr_accessible :title, :body + belongs_to :no_use, :polymorphic => true + belongs_to :user + + validates_presence_of :user + validates_uniqueness_of :user_id, :scope => [:no_use_type, :no_use_id] + validate :validate_user + + protected + + def validate_user + errors.add :user_id, :invalid unless user.nil? || user.active? + end end diff --git a/app/models/open_source_project.rb b/app/models/open_source_project.rb index 57bcfeabc..320b79f7e 100644 --- a/app/models/open_source_project.rb +++ b/app/models/open_source_project.rb @@ -2,11 +2,21 @@ class OpenSourceProject < ActiveRecord::Base attr_accessible :String include Redmine::SafeAttributes + has_many :applies, :class_name => "ApplyProjectMaster", :as => :apply, :dependent => :delete_all has_many :topics, :class_name => 'RelativeMemo', :foreign_key => 'osp_id', :conditions => "#{RelativeMemo.table_name}.parent_id IS NULL", :order => "#{RelativeMemo.table_name}.created_at DESC", :dependent => :destroy - has_many :relative_memos, :dependent => :destroy + has_many :relative_memos, :class_name => 'RelativeMemo', :foreign_key => 'osp_id', :dependent => :destroy has_many :tags, :through => :project_tags, :class_name => 'Tag' has_many :project_tags, :class_name => 'ProjectTags' + + acts_as_taggable + + scope :applied_by, lambda { |user_id| + { :include => :apply_project_master, + :conditions => ["#{ApplyProjectMaster.table_name}.user_id = ?", user_id] } + } + + def short_description(length = 255) description.gsub(/^(.{#{length}}[^\n\r]*).*$/m, '\1...').strip if description end @@ -19,6 +29,19 @@ class OpenSourceProject < ActiveRecord::Base false end + def set_apply(user, flag=true) + flag ? set_filter(user) : remove_filter(user) + end + + def set_filter(user) + self.applies << ApplyProjectMaster.new(:user => user, :status => 1) + end + + def remove_filter(user) + return nil unless user && user.is_a?(User) + ApplyProjectMaster.delete_all "apply_type = '#{self.class}' AND apply_id = #{self.id} AND user_id = #{user.id}" + end + def reset_counters! self.class.reset_counters!(id) end diff --git a/app/models/relative_memo.rb b/app/models/relative_memo.rb index cd2d0e8a6..a1532dcb2 100644 --- a/app/models/relative_memo.rb +++ b/app/models/relative_memo.rb @@ -6,6 +6,9 @@ class RelativeMemo < ActiveRecord::Base has_many :tags, :through => :project_tags, :class_name => 'Tag' has_many :project_tags, :class_name => 'ProjectTags' + + has_many :no_uses, :as => :no_use, :dependent => :delete_all + acts_as_taggable validates_presence_of :osp_id, :subject @@ -77,8 +80,26 @@ class RelativeMemo < ActiveRecord::Base } def no_use_for?(user) + self.no_uses.each do |no_use| + if no_use.user_id == user.id + return true + end + end false end + + def set_no_use(user, flag=true) + flag ? set_filter(user) : remove_filter(user) + end + + def set_filter(user) + self.no_uses << NoUse.new(:user => user) + end + + def remove_filter(user) + return nil unless user && user.is_a?(User) + NoUse.delete_all "no_use_type = '#{self.class}' AND no_use_id = #{self.id} AND user_id = #{user.id}" + end def reset_counters! if parent && parent.id diff --git a/app/views/apply_project_masters/_set_apply.js.erb b/app/views/apply_project_masters/_set_apply.js.erb new file mode 100644 index 000000000..2c2075743 --- /dev/null +++ b/app/views/apply_project_masters/_set_apply.js.erb @@ -0,0 +1,2 @@ +<% selector = ".#{apply_css(objects)}" %> +$("<%= selector %>").each(function(){$(this).replaceWith("<%= escape_javascript apply_super_user(objects, user) %>")}); diff --git a/app/views/no_uses/_set_no_use.js.erb b/app/views/no_uses/_set_no_use.js.erb new file mode 100644 index 000000000..fa0c5a8e8 --- /dev/null +++ b/app/views/no_uses/_set_no_use.js.erb @@ -0,0 +1,2 @@ +<% selector = ".#{no_use_css(objects)}" %> +$("<%= selector %>").each(function(){$(this).replaceWith("<%= escape_javascript no_use_link(objects, user) %>")}); diff --git a/app/views/open_source_projects/index.html.erb b/app/views/open_source_projects/index.html.erb index 50d2fbb5e..032e0a82b 100644 --- a/app/views/open_source_projects/index.html.erb +++ b/app/views/open_source_projects/index.html.erb @@ -149,7 +149,7 @@ li { -
  • 1.61万 件宝贝
  • +
  • 1.61万 个开源项目
  • @@ -171,6 +171,19 @@ li { + diff --git a/app/views/relative_memos/show.html.erb b/app/views/relative_memos/show.html.erb index e69de29bb..69ea0de41 100644 --- a/app/views/relative_memos/show.html.erb +++ b/app/views/relative_memos/show.html.erb @@ -0,0 +1,142 @@ +
    +
    +
    <%= link_to image_tag(url_to_avatar(@memo.author), :class => "avatar"), user_path(@memo.author) if @memo.author %>
    +

    <%=link_to @memo.author.name, user_path(@memo.author) if @memo.author%>

    +
    +
    +
    + + <%#= link_to( + l(:button_quote), + {:action => 'quote', :id => @memo}, + :remote => true, + :method => 'get', + :title => l(:button_quote) + )if !@memo.locked? && User.current.logged? %> + + <%#= link_to( + image_tag('edit.png'), + {:action => 'edit', :id => @memo}, + :method => 'get', + :title => l(:button_edit) + ) if @memo.editable_by?(User.current) %> + + <%#= link_to( + l(:button_delete), + {:action => 'destroy', :id => @memo}, + :method => :delete, + :data => {:confirm => l(:text_are_you_sure)}, + :title => l(:button_delete) + ) if @memo.destroyable_by?(User.current) %> + + +
    + +
    <%= label_tag l(:field_subject) %>: <%=h @memo.subject %>
    +
    + + <%= raw @memo.content %> +

    + <% if @memo.attachments.any?%> + <% options = {:author => true, :deletable => @memo.deleted_attach_able_by?(User.current) } %> + <%= render :partial => 'attachments/links', :locals => {:attachments => @memo.attachments, :options => options} %> + <% end %> +

    +
    +
    <%= authoring @memo.created_at, @memo.author.name if @memo.author %>
    + +
    +
    +
    +
    +

    <%= l(:label_reply_plural) %> (<%= @replies.nil? ? 0 : @replies.size %>)

    + <% pages_count = @reply_pages.offset %> + <% @replies.each do |reply| %> +
    "> +

    <%= pages_count += 1 %>楼 :

    +
    + + <%#= link_to( + l(:button_quote), + {:action => 'quote', :id => reply}, + :remote => true, + :method => 'get', + :title => l(:button_quote) + )if !@memo.locked? && User.current.logged? %> + + <%#= link_to( + image_tag('edit.png'), + {:action => 'edit', :id => reply}, + :title => l(:button_edit) + ) if reply.editable_by?(User.current) %> + + <%#= link_to( + l(:button_delete), + {:action => 'destroy', :id => reply}, + :method => :delete, + :data => {:confirm => l(:text_are_you_sure)}, + :title => l(:button_delete) + ) if reply.destroyable_by?(User.current) %> + +
    + + + + + + + + + +
    + <%= link_to image_tag(url_to_avatar(reply.author), :class => "avatar"), user_path(reply.author) if reply.author %> + +
    <%=h reply.content.html_safe %>
    + +

    + <% if reply.attachments.any?%> + <% options = {:author => true, :deletable => reply.deleted_attach_able_by?(User.current) } %> + <%= render :partial => 'attachments/links', :locals => {:attachments => reply.attachments, :options => options} %> + <% end %> +

    +
    <%= authoring reply.created_at, reply.author.name if reply.author %>
    +
    + <% end %> + +
    + +<% if User.current.login? %> +
    + <%#= render :partial => 'memos/reply_box' %> +
    +<% else %> +
    + <%= l(:label_user_login_tips) %> + <%= link_to l(:label_user_login_new), signin_path %> +
    +
    +<% end %> diff --git a/config/locales/zh.yml b/config/locales/zh.yml index 4aac82bf2..1877e1d33 100644 --- a/config/locales/zh.yml +++ b/config/locales/zh.yml @@ -1806,3 +1806,5 @@ zh: label_contest_reason: 参赛宣言: label_notification: 通知 label_sumbit_empty: 搜索内容不能为空 + no_use: 没有帮助 + cancel_no_use: 撤销没有帮助 diff --git a/config/routes.rb b/config/routes.rb index 0b17651c5..d357eff01 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -17,9 +17,12 @@ RedmineApp::Application.routes.draw do resources :no_uses + delete 'no_uses', :to => 'no_uses#delete' + resources :apply_project_masters + delete 'apply_project_masters', :to => 'apply_project_masters#delete' resources :open_source_projects do diff --git a/db/migrate/20140404031622_add_view_count_to_relative_memos.rb b/db/migrate/20140404031622_add_view_count_to_relative_memos.rb new file mode 100644 index 000000000..17eb95b70 --- /dev/null +++ b/db/migrate/20140404031622_add_view_count_to_relative_memos.rb @@ -0,0 +1,6 @@ +class AddViewCountToRelativeMemos < ActiveRecord::Migration + def change + add_column :relative_memos, :viewed_count_crawl, :int, default: 0 + add_column :relative_memos, :viewed_count_local, :int, default: 0 + end +end diff --git a/db/schema.rb b/db/schema.rb index 40523093c..f0969c398 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 => 20140403113341) do +ActiveRecord::Schema.define(:version => 20140404031622) do create_table "activities", :force => true do |t| t.integer "act_id", :null => false @@ -201,6 +201,7 @@ ActiveRecord::Schema.define(:version => 20140403113341) do t.string "setup_time" t.string "endup_time" t.string "class_period" + t.integer "school_id" end create_table "custom_fields", :force => true do |t| @@ -769,18 +770,20 @@ ActiveRecord::Schema.define(:version => 20140403113341) do add_index "queries", ["user_id"], :name => "index_queries_on_user_id" create_table "relative_memos", :force => true do |t| - t.integer "osp_id", :null => false + t.integer "osp_id", :null => false t.integer "parent_id" - t.string "subject", :null => false - t.text "content", :null => false + t.string "subject", :null => false + t.text "content", :null => false t.integer "author_id" - t.integer "replies_count", :default => 0 + t.integer "replies_count", :default => 0 t.integer "last_reply_id" - t.boolean "lock", :default => false - t.boolean "sticky", :default => false - t.boolean "is_quote", :default => false - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.boolean "lock", :default => false + t.boolean "sticky", :default => false + t.boolean "is_quote", :default => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "viewed_count_crawl", :default => 0 + t.integer "viewed_count_local", :default => 0 end create_table "repositories", :force => true do |t|