From e333c748b7f71d9ee79ccd25f8eb375985468546 Mon Sep 17 00:00:00 2001 From: kg Date: Sat, 19 Apr 2014 09:53:09 +0800 Subject: [PATCH 01/54] boards footer --- app/views/boards/show.html.erb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/views/boards/show.html.erb b/app/views/boards/show.html.erb index f518120ef..c80467291 100644 --- a/app/views/boards/show.html.erb +++ b/app/views/boards/show.html.erb @@ -91,13 +91,14 @@ --> <% end %> +<% else %> +

<%= l(:label_no_data) %>

+<% end %> -<% else %> -

<%= l(:label_no_data) %>

-<% end %> + <% other_formats_links do |f| %> <%= f.link_to 'Atom', :url => {:key => User.current.rss_key} %> From 7758e9bbf11fde265df0f1b0198e7cc2a5eddb02 Mon Sep 17 00:00:00 2001 From: wanglinchun Date: Mon, 21 Apr 2014 21:03:18 +0800 Subject: [PATCH 02/54] df --- app/views/softapplications/show.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/softapplications/show.html.erb b/app/views/softapplications/show.html.erb index 76483c7c0..c0234831a 100644 --- a/app/views/softapplications/show.html.erb +++ b/app/views/softapplications/show.html.erb @@ -68,7 +68,7 @@
软件评论:
-
评分: <%= rating_for @softapplication, dimension: :quality, class: 'rateable div_inline' %>
+
评分: <%= rating_for @softapplication, dimension: :quality, class: 'rateable div_inline' %>
From 3ba524668f0f9424867dde5158c8c54490ba2d48 Mon Sep 17 00:00:00 2001 From: Wen Date: Mon, 21 Apr 2014 22:34:51 +0800 Subject: [PATCH 03/54] =?UTF-8?q?=E7=94=A8=E6=88=B7=E8=AF=84=E5=88=86?= =?UTF-8?q?=E6=9C=AA=E5=AE=8C=E6=88=90=E7=89=88=E6=9C=AC=3D=20=3D=20?= =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E4=B8=80=E4=B8=8B=E4=BB=A5=E9=98=B2=E4=B8=A2?= =?UTF-8?q?=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/helpers/user_score_helper.rb | 116 ++++++++++++++++++++++++++++++- app/views/test/index.html.erb | 11 ++- db/schema.rb | 26 ++++++- 3 files changed, 148 insertions(+), 5 deletions(-) diff --git a/app/helpers/user_score_helper.rb b/app/helpers/user_score_helper.rb index ff4a5adbd..4dc4d4c6e 100644 --- a/app/helpers/user_score_helper.rb +++ b/app/helpers/user_score_helper.rb @@ -34,11 +34,123 @@ module UserScoreHelper end def calculate_skill_count(user) - 0 + + praise_count = 0 + tread_count = 0 + issues = Issue.where('author_id = ?', user.id) + issues.each do |i| + ptcs = PraiseTreadCache.where('object_id = ?', i.id) + ptcs.each do |p| + praise_count = praise_count + p.praise_num + tread_count = tread_count + p.tread_num + end + end + + bids = Bid.where('author_id = ?', user.id) + bids.each do |b| + ptcs = PraiseTreadCache.where('object_id = ?', b.id) + ptcs.each do |p| + praise_count = praise_count + p.praise_num + tread_count = tread_count + p.tread_num + end + end + + contests = Contest.where('author_id = ?', user.id) + contests.each do |c| + ptcs = PraiseTreadCache.where('object_id = ?', c.id) + ptcs.each do |p| + praise_count = praise_count + p.praise_num + tread_count = tread_count + p.tread_num + end + end + + + level = calculate_level(user) + + skill_score = 0 + + if level == 0 + skill_score = praise_count - 0.5 * tread_count + elseif level == 1 + skill_score = 2 * praise_count - 1.5 * tread_count + elseif level == 2 + skill_socre = 3 * praise_count - 2.5 * tread_count + elseif level == 3 + skill_socre = 4 * praise_count - 3.5 * tread_count + elseif level == 4 + skill_socre = 5 * praise_count - 4.5 * tread_count + end + +# case level +# when 0 skill_score = praise_count - 0.5 * tread_count +# when 1 skill_score = 2 * praise_count - 1.5 * tread_count +# when 2 skill_socre = 3 * praise_count - 2.5 * tread_count +# when 3 skill_socre = 4 * praise_count - 3.5 * tread_count +# when 4 skill_socre = 5 * praise_count - 4.5 * tread_count +# end + + + + tread_user_count = PraiseTread.where('praise_or_tread = ?, user_id = ?', 0, user.id).count + + skill_score = skill_score - 0.5 * tread_user_count + + return skill_score + + + end def calculate_level(user) - 1 + commit_count = user.changesets.count + max_praise_num = 0 + + + issues = Issue.where('author_id = ?', user.id) + issues.each do |i| + ptcs = PraiseTreadCache.where('object_id = ?', i.id) + ptcs.each do |p| + if p.praise_num > max_praise_num + max_praise_num = p.praise_num + end + end + end + + bids = Bid.where('author_id = ?', user.id) + bids.each do |b| + ptcs = PraiseTreadCache.where('object_id = ?', b.id) + ptcs.each do |p| + if p.praise_num > max_praise_num + max_praise_num = p.praise_num + end + end + end + + contests = Contest.where('author_id = ?', user.id) + contests.each do |c| + ptcs = PraiseTreadCache.where('object_id = ?', c.id) + ptcs.each do |p| + if p.praise_num > max_praise_num + max_praise_num = p.praise_num + end + end + end + + + best_answer_num = 0 + + level = 0 + + if max_praise_num > 4 + level = 1 + elseif commit_count > 0 and commit_count < 101 + level = 1 + elseif commit_count > 100 + level = 2 + end + + return level + end def calculate_activity_count(user) diff --git a/app/views/test/index.html.erb b/app/views/test/index.html.erb index 31cfdb9eb..93225f513 100644 --- a/app/views/test/index.html.erb +++ b/app/views/test/index.html.erb @@ -1,6 +1,13 @@

test

-<%= debug request %> +<% PraiseTreadCache.where('object_id = 47').each do |p| %> + + <%if p.praise_num < 0 or p.praise_num == 2%> + <%= p.praise_num %> + <%end%> + + +<% end %>
-<%= request.host().class %> +
\ No newline at end of file diff --git a/db/schema.rb b/db/schema.rb index 3918413f3..c82407286 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 => 20140421044830) do +ActiveRecord::Schema.define(:version => 20140421091020) do create_table "activities", :force => true do |t| t.integer "act_id", :null => false @@ -754,6 +754,11 @@ ActiveRecord::Schema.define(:version => 20140421044830) do add_index "time_entries", ["project_id"], :name => "time_entries_project_id" add_index "time_entries", ["user_id"], :name => "index_time_entries_on_user_id" + create_table "tmp", :force => true do |t| + t.string "name" + t.string "part_number" + end + create_table "tokens", :force => true do |t| t.integer "user_id", :default => 0, :null => false t.string "action", :limit => 30, :default => "", :null => false @@ -813,6 +818,19 @@ ActiveRecord::Schema.define(:version => 20140421044830) do add_index "user_preferences", ["user_id"], :name => "index_user_preferences_on_user_id" + create_table "user_scores", :force => true do |t| + t.integer "user_id", :null => false + t.integer "collaboration" + t.integer "influence" + t.integer "skill" + t.integer "active" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "level" + t.integer "file" + t.integer "issue" + end + create_table "user_statuses", :force => true do |t| t.integer "changesets_count" t.integer "watchers_count" @@ -947,4 +965,10 @@ ActiveRecord::Schema.define(:version => 20140421044830) do add_index "workflows", ["role_id", "tracker_id", "old_status_id"], :name => "wkfs_role_tracker_old_status" add_index "workflows", ["role_id"], :name => "index_workflows_on_role_id" + create_table "yans", :force => true do |t| + t.string "name" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + end From cc5b55ec9c2eba00d8535c627aa8bd5983726baf Mon Sep 17 00:00:00 2001 From: wanglinchun Date: Tue, 22 Apr 2014 08:49:08 +0800 Subject: [PATCH 04/54] =?UTF-8?q?=E8=B0=83=E6=95=B4=E5=BA=94=E7=94=A8?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E4=B8=AD=E7=AE=80=E4=BB=8B=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E4=B8=8A=E4=B8=8B=E8=BE=B9=E8=B7=9D=E4=BB=A5=E5=8F=8A=E7=AE=80?= =?UTF-8?q?=E4=BB=8B=E9=99=90=E5=AE=9A=E5=AD=97=E6=95=B0=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/softapplications/show.html.erb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/softapplications/show.html.erb b/app/views/softapplications/show.html.erb index c0234831a..a5c3fb596 100644 --- a/app/views/softapplications/show.html.erb +++ b/app/views/softapplications/show.html.erb @@ -10,7 +10,7 @@

<%= notice %>

-
+
@@ -48,9 +48,9 @@
-
+
应用简介:
-
<%= @softapplication.description %>
+
<%= @softapplication.description.truncate(150, omission: '...') %>
From 0791c35df1f30bd2703ace3d32899a7e7bda016f Mon Sep 17 00:00:00 2001 From: yanxd Date: Tue, 22 Apr 2014 08:56:26 +0800 Subject: [PATCH 05/54] =?UTF-8?q?=E8=B5=9E=E8=B8=A9=E5=85=B3=E8=81=94?= =?UTF-8?q?=E5=85=B3=E7=B3=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/bid.rb | 1 + app/models/contest.rb | 1 + app/models/issue.rb | 3 ++- app/models/praise_tread.rb | 2 ++ 4 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/models/bid.rb b/app/models/bid.rb index fd389c15f..e58e640a0 100644 --- a/app/models/bid.rb +++ b/app/models/bid.rb @@ -29,6 +29,7 @@ class Bid < ActiveRecord::Base has_many :courses, :through => :homework_for_courses, :source => :project has_many :homeworks, :class_name => 'HomeworkAttach', :dependent => :destroy has_many :join_in_contests, :dependent => :destroy + has_many :praise_tread, as: :praise_tread_object, dependent: :destroy # has_many :fork_homework, :class_name => 'Bid', :conditions => "#{Bid.table_name}.parent_id = #{id}" diff --git a/app/models/contest.rb b/app/models/contest.rb index edc252574..c3eea7e74 100644 --- a/app/models/contest.rb +++ b/app/models/contest.rb @@ -12,6 +12,7 @@ class Contest < ActiveRecord::Base has_many :acts, :class_name => 'Activity', :as => :act, :dependent => :destroy has_many :join_in_competitions, foreign_key: 'competition_id', :dependent => :destroy has_many :join_in_contests, class_name: 'JoinInCompetition', foreign_key: 'competition_id', :dependent => :destroy + has_many :praise_tread, as: :praise_tread_object, dependent: :destroy diff --git a/app/models/issue.rb b/app/models/issue.rb index 43bc6537d..b69ac246c 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -45,7 +45,8 @@ class Issue < ActiveRecord::Base # added by fq has_many :acts, :class_name => 'Activity', :as => :act, :dependent => :destroy - # end + # end + has_many :praise_tread, as: :praise_tread_object, dependent: :destroy acts_as_nested_set :scope => 'root_id', :dependent => :destroy diff --git a/app/models/praise_tread.rb b/app/models/praise_tread.rb index 901a31660..c27e1fc9f 100644 --- a/app/models/praise_tread.rb +++ b/app/models/praise_tread.rb @@ -1,4 +1,6 @@ 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 end From ded3da6670bde0d1ef19586bf5f89f82659b9576 Mon Sep 17 00:00:00 2001 From: Wen Date: Tue, 22 Apr 2014 09:54:56 +0800 Subject: [PATCH 06/54] =?UTF-8?q?=E7=94=A8=E6=88=B7=E8=AF=84=E5=88=86?= =?UTF-8?q?=E7=90=86=E8=AE=BA=E4=B8=8A=E5=AE=8C=E6=88=90=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/helpers/user_score_helper.rb | 38 +++++++++++++++++++++++++++++--- app/views/test/index.html.erb | 16 +++++++++----- 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/app/helpers/user_score_helper.rb b/app/helpers/user_score_helper.rb index 4dc4d4c6e..4c9a126f7 100644 --- a/app/helpers/user_score_helper.rb +++ b/app/helpers/user_score_helper.rb @@ -24,7 +24,28 @@ module UserScoreHelper issues.each do |issue| issue_c = issue_c + issue.journals.where("user_id <> ?", user.id).count end - issue_c = issue_c + Journal.where("user_id = ?", user.id) + issue_c = issue_c + Journal.where("user_id = ?", user.id).count + ############################ + memos = Memo.where('author_id = ? AND parent_id IS NOT NULL', user.id) + + memos.each do |m| + if Memo.find(m.parent_id).author.id != user.id + issue_c = issue_c + 1 + else + issue_c = issue_c - 1 + end + end + + + pmemos = Memo.where('author_id = ? AND parent_id IS NULL', user.id) + pmemos.each do |pm| + issue_c = issue_c + pm.replies_count + end + ############################ + + issue_c = issue_c + JournalsForMessage.where('user_id = ? AND reply_id IS NOT NULL AND reply_id <> ?', user.id, user.id).count + JournalsForMessage.where('reply_id = ? AND user_id <> ?', user.id, user.id).count + + return issue_c end @@ -91,7 +112,7 @@ module UserScoreHelper - tread_user_count = PraiseTread.where('praise_or_tread = ?, user_id = ?', 0, user.id).count + tread_user_count = PraiseTread.where('praise_or_tread = ? AND user_id = ?', 0, user.id).count skill_score = skill_score - 0.5 * tread_user_count @@ -139,13 +160,24 @@ module UserScoreHelper best_answer_num = 0 + isManager = 0 + members = Member.where('user_id = ?', user.id) + members.each do |m| + roles = m.member_roles + roles.each do |r| + if r.role_id == 3 + isManager = 1 + end + end + end + level = 0 if max_praise_num > 4 level = 1 elseif commit_count > 0 and commit_count < 101 level = 1 - elseif commit_count > 100 + elseif commit_count > 100 or isManager == 1 level = 2 end diff --git a/app/views/test/index.html.erb b/app/views/test/index.html.erb index 93225f513..43101bb4f 100644 --- a/app/views/test/index.html.erb +++ b/app/views/test/index.html.erb @@ -1,12 +1,16 @@

test

-<% PraiseTreadCache.where('object_id = 47').each do |p| %> + +<% memos=Memo.where('author_id = 5 AND parent_id IS NOT NULL') %> +<% memos.each do |m|%> + - <%if p.praise_num < 0 or p.praise_num == 2%> - <%= p.praise_num %> - <%end%> - - + <% if Memo.find(m.parent_id).author_id != 5 %> + <%=m.subject%> + <% end %> +> + <% end %> +

From bc068eb12b5016e24f8de398c9a60f2e37cceac1 Mon Sep 17 00:00:00 2001 From: wanglinchun Date: Tue, 22 Apr 2014 10:59:50 +0800 Subject: [PATCH 07/54] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=8F=82=E8=B5=9B?= =?UTF-8?q?=E5=BA=94=E7=94=A8=E7=9A=84=E5=88=A0=E9=99=A4=E5=92=8C=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E5=8A=9F=E8=83=BD=E4=BB=A5=E5=8F=8A=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E7=9B=B8=E5=BA=94=E7=9A=84=E5=88=A0=E9=99=A4=E5=92=8C=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E6=9D=83=E9=99=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Gemfile.lock | 2 +- .../softapplications_controller.rb | 30 ++++++++- app/models/attachment.rb | 2 +- app/models/softapplication.rb | 11 +++- .../contests/_list_softapplications.html.erb | 1 + app/views/layouts/_base_footer.html.erb | 63 ++++++++++++------- app/views/softapplications/index.html.erb | 2 +- 7 files changed, 79 insertions(+), 32 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 40caae261..42cb62272 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -75,7 +75,7 @@ GEM rake (>= 0.8.7) rdoc (~> 3.4) thor (>= 0.14.6, < 2.0) - rake (10.1.0) + rake (10.0.4) rdoc (3.12.2) json (~> 1.4) ruby-openid (2.1.8) diff --git a/app/controllers/softapplications_controller.rb b/app/controllers/softapplications_controller.rb index 9f14aa118..9163f5473 100644 --- a/app/controllers/softapplications_controller.rb +++ b/app/controllers/softapplications_controller.rb @@ -1,4 +1,8 @@ class SoftapplicationsController < ApplicationController + before_filter :find_softapplication, only: [:edit, :update, :destroy] + before_filter :editable, only: [:edit, :update] + before_filter :destroyable, only: :destroy + # GET /softapplications # GET /softapplications.json def index @@ -71,7 +75,7 @@ class SoftapplicationsController < ApplicationController # PUT /softapplications/1 # PUT /softapplications/1.json def update - @softapplication = Softapplication.find(params[:id]) + # @softapplication = Softapplication.find(params[:id]) respond_to do |format| if @softapplication.update_attributes(params[:softapplication]) @@ -92,11 +96,11 @@ class SoftapplicationsController < ApplicationController # DELETE /softapplications/1 # DELETE /softapplications/1.json def destroy - @softapplication = Softapplication.find(params[:id]) + # @softapplication = Softapplication.find(params[:id]) @softapplication.destroy respond_to do |format| - format.html { redirect_to softapplications_url } + format.html { redirect_to :back } format.json { head :no_content } end end @@ -192,4 +196,24 @@ class SoftapplicationsController < ApplicationController #format.api { render_api_ok } end end + + private + def find_softapplication + @softapplication = Softapplication.find_by_id(params[:id]) + end + + def editable + unless @softapplication.editable_by? User.current + render_403 + return false + end + end + + def destroyable + unless @softapplication.destroyable_by? User.current + render_403 + return false + end + end + end diff --git a/app/models/attachment.rb b/app/models/attachment.rb index 919760ee3..3ce64d695 100644 --- a/app/models/attachment.rb +++ b/app/models/attachment.rb @@ -181,7 +181,7 @@ class Attachment < ActiveRecord::Base end def pack? - !!(self.filename =~ /\.(zip|rar|tar|gz)$/i) + !!(self.filename =~ /\.(zip|rar|tar|gz|exe)$/i) end def thumbnailable? diff --git a/app/models/softapplication.rb b/app/models/softapplication.rb index 205ede48b..6782b2436 100644 --- a/app/models/softapplication.rb +++ b/app/models/softapplication.rb @@ -7,7 +7,7 @@ class Softapplication < ActiveRecord::Base has_many :journals_for_messages, :as => :jour, :dependent => :destroy has_many :contesting_softapplications, :dependent => :destroy belongs_to :user - belongs_to :contest + has_many :contests, :through => :contesting_softapplications def add_jour(user, notes, reference_user_id = 0, options = {}) if options.count == 0 @@ -21,6 +21,13 @@ class Softapplication < ActiveRecord::Base def set_commit(commit) self.update_attribute(:commit, commit) end - + + def editable_by? usr + usr.admin? || self.user == usr + end + + def destroyable_by? usr + self.user == usr || usr.admin? + end end diff --git a/app/views/contests/_list_softapplications.html.erb b/app/views/contests/_list_softapplications.html.erb index 29c985b7e..5646f5d12 100644 --- a/app/views/contests/_list_softapplications.html.erb +++ b/app/views/contests/_list_softapplications.html.erb @@ -8,6 +8,7 @@ <%= link_to(c_softapplication.softapplication.name, softapplication_path(c_softapplication.softapplication)) %> + <%= link_to '删除', c_softapplication.softapplication, method: :delete, data: { confirm: '您确定要删除吗?' } %>
diff --git a/app/views/layouts/_base_footer.html.erb b/app/views/layouts/_base_footer.html.erb index bba5b2166..a941a7d1f 100644 --- a/app/views/layouts/_base_footer.html.erb +++ b/app/views/layouts/_base_footer.html.erb @@ -1,28 +1,43 @@
+
+ <%= debug(params) if Rails.env.development? %> + +
diff --git a/app/views/softapplications/index.html.erb b/app/views/softapplications/index.html.erb index be9245876..16a206508 100644 --- a/app/views/softapplications/index.html.erb +++ b/app/views/softapplications/index.html.erb @@ -1,4 +1,4 @@ -

Listing softapplications

+

参赛应用

From 00e62ec8f7fa5ab479bcf620957b527b1229d8a7 Mon Sep 17 00:00:00 2001 From: Wen Date: Tue, 22 Apr 2014 14:53:25 +0800 Subject: [PATCH 08/54] =?UTF-8?q?=E7=94=A8=E6=88=B7=E8=AF=84=E5=88=86?= =?UTF-8?q?=E7=90=86=E8=AE=BA=E4=B8=8A=E5=AE=8C=E6=88=90=E7=89=88.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/test_controller.rb | 2 + app/controllers/user_score_controller.rb | 6 +++ app/helpers/user_score_helper.rb | 53 +++++++++++++------ app/models/user.rb | 4 +- app/views/test/index.html.erb | 23 +++++--- test/functional/user_score_controller_test.rb | 7 +++ 6 files changed, 70 insertions(+), 25 deletions(-) create mode 100644 app/controllers/user_score_controller.rb create mode 100644 test/functional/user_score_controller_test.rb diff --git a/app/controllers/test_controller.rb b/app/controllers/test_controller.rb index cb28f4e66..0623dbee2 100644 --- a/app/controllers/test_controller.rb +++ b/app/controllers/test_controller.rb @@ -1,4 +1,6 @@ class TestController < ApplicationController + + helper :UserScore def zip homeworks_attach_path = [] diff --git a/app/controllers/user_score_controller.rb b/app/controllers/user_score_controller.rb new file mode 100644 index 000000000..875229e89 --- /dev/null +++ b/app/controllers/user_score_controller.rb @@ -0,0 +1,6 @@ +class UserScoreController < ApplicationController + helper :UserScoreHelper + + + +end diff --git a/app/helpers/user_score_helper.rb b/app/helpers/user_score_helper.rb index 4c9a126f7..5b455a01b 100644 --- a/app/helpers/user_score_helper.rb +++ b/app/helpers/user_score_helper.rb @@ -51,7 +51,7 @@ module UserScoreHelper end def calculate_influence_count(user) - watcher_count = watcher_users(User.current.id).count + watcher_count = Watcher.where("watchable_type = 'principal' AND watchable_id = ?", user.id).count end def calculate_skill_count(user) @@ -92,13 +92,17 @@ module UserScoreHelper if level == 0 skill_score = praise_count - 0.5 * tread_count - elseif level == 1 + end + if level == 1 skill_score = 2 * praise_count - 1.5 * tread_count - elseif level == 2 + end + if level == 2 skill_socre = 3 * praise_count - 2.5 * tread_count - elseif level == 3 + end + if level == 3 skill_socre = 4 * praise_count - 3.5 * tread_count - elseif level == 4 + end + if level == 4 skill_socre = 5 * praise_count - 4.5 * tread_count end @@ -175,9 +179,11 @@ module UserScoreHelper if max_praise_num > 4 level = 1 - elseif commit_count > 0 and commit_count < 101 + end + if commit_count > 0 and commit_count < 101 level = 1 - elseif commit_count > 100 or isManager == 1 + end + if commit_count > 100 or isManager == 1 level = 2 end @@ -195,13 +201,13 @@ module UserScoreHelper # end # file_count = user.file_commit.count # issue_count = Issue.where('author_id = ?', user.id).count - f = user.user_score.file - i = user.user_score.issue - f_max = UserScore.find_max_file - f_min = UserScore.find_min_file - i_max = UserScore.find_max_issue - i_min = UserScore.find_min_issue - score = 100 * ((f - f_min)/(f_max - f_min) + (i - i_min)/(i_max - i_min)) + #f = user.user_score.file + #i = user.user_score.issue + #f_max = UserScore.find_max_file + #f_min = UserScore.find_min_file + #i_max = UserScore.find_max_issue + #i_min = UserScore.find_min_issue + #score = 100 * ((f - f_min)/(f_max - f_min) + (i - i_min)/(i_max - i_min)) end def calculate_file(user) @@ -216,8 +222,14 @@ module UserScoreHelper issue_details_count = 0 issues = Issue.where('assigned_to_id = ?', user.id) + change_count = 0 issues.each do |issue| - change_count = issue.journals.where("prop_key = ?", "done_ratio").count + js = issue.journals + js.each do |j| + change_count = change_count + j.details.where("prop_key = ?", "done_ratio").count + end + + issue_details_count = change_count + issue_details_count end @@ -233,7 +245,9 @@ module UserScoreHelper file = calculate_file(user) issue = calculate_issue(user) level = calculate_level(user) - user.user_score << UserScore.new(:collaboration => collaboration, :influence => influence, :skill => skill, + #user.user_score << UserScore.new(:collaboration => collaboration, :influence => influence, :skill => skill, + # :activity => activity, :file => file, :issue => issue, :level => level) + UserScore.new(:collaboration => collaboration, :influence => influence, :skill => skill, :activity => activity, :file => file, :issue => issue, :level => level) end @@ -241,12 +255,17 @@ module UserScoreHelper collaboration = calculate_collaboration_count(user) influence = calculate_influence_count(user) skill = calculate_skill_count(user) - activity = calculate_activity_count(user) file = calculate_file(user) issue = calculate_issue(user) + + ##activity = calculate_activity_count(user) + level = calculate_level(user) user.user_score.update_attributes(:collaboration => collaboration, :influence => influence, :skill => skill, :activity => activity, :file => file, :issue => issue, :level => level) end + + + end diff --git a/app/models/user.rb b/app/models/user.rb index 1809c3a98..20624888a 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -96,7 +96,7 @@ class User < Principal has_many :students_for_courses has_many :courses, :through => :students_for_courses, :source => :project has_many :acts, :class_name => 'Activity', :as => :act, :dependent => :destroy - has_many :file_commit, :class_name => 'Attachment', :foreign_key => 'author_id', :conditions => "container_tpye = 'Project' or container_type = 'Version'" + has_many :file_commit, :class_name => 'Attachment', :foreign_key => 'author_id', :conditions => "container_type = 'Project' or container_type = 'Version'" #### # added by bai has_many :join_in_contests, :dependent => :destroy @@ -105,7 +105,7 @@ class User < Principal has_many :wiki_contents, :foreign_key => 'author_id' has_many :journals has_many :messages, :foreign_key => 'author_id' - has_one :user_socre, :dependent => :destroy + has_one :user_score, :dependent => :destroy # end ######added by nie diff --git a/app/views/test/index.html.erb b/app/views/test/index.html.erb index 43101bb4f..5b435085a 100644 --- a/app/views/test/index.html.erb +++ b/app/views/test/index.html.erb @@ -1,15 +1,26 @@

test

-<% memos=Memo.where('author_id = 5 AND parent_id IS NOT NULL') %> -<% memos.each do |m|%> +<% users = User.all%> +
- <% if Memo.find(m.parent_id).author_id != 5 %> - - <% end %> -> + + +<% users.each do |user| %> + + + + + + + + + + + <% end %> +
<%=m.subject%>
nameCISfilecountissuecountlevel
<%= user.lastname %><%= user.firstname %><%= calculate_collaboration_count(user) %><%= calculate_influence_count(user) %><%= calculate_skill_count(user) %><%= calculate_file(user) %><%= calculate_issue(user) %><%= calculate_level(user) %>

diff --git a/test/functional/user_score_controller_test.rb b/test/functional/user_score_controller_test.rb new file mode 100644 index 000000000..bf56a2076 --- /dev/null +++ b/test/functional/user_score_controller_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class UserScoreControllerTest < ActionController::TestCase + # test "the truth" do + # assert true + # end +end From 3dbe7c5896bb519e645001f480cdd912ca2eb356 Mon Sep 17 00:00:00 2001 From: Wen Date: Tue, 22 Apr 2014 15:25:50 +0800 Subject: [PATCH 09/54] =?UTF-8?q?=E8=AF=BE=E7=A8=8B=E7=9A=84=E5=AD=A6?= =?UTF-8?q?=E6=A0=A1ID=E8=87=AA=E5=8A=A8=E8=AE=BE=E7=BD=AE=E4=B8=BA?= =?UTF-8?q?=E5=BC=80=E8=AF=BE=E6=95=99=E5=B8=88=E7=9A=84=E5=AD=A6=E6=A0=A1?= =?UTF-8?q?ID=20=E5=8E=BB=E6=8E=89=E8=AF=BE=E7=A8=8B=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E7=95=8C=E9=9D=A2=E4=B8=8A=E7=9A=84=E5=AD=A6=E6=A0=A1=E9=80=89?= =?UTF-8?q?=E6=8B=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/projects_controller.rb | 3 ++- app/views/projects/_course_form.html.erb | 6 ------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 3f771bf77..98f6316ad 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -392,7 +392,8 @@ class ProjectsController < ApplicationController # added by bai @course.term = params[:term] @course.time = params[:time] - @course.school_id = params[:occupation] + #@course.school_id = params[:occupation] + @course.school_id = User.current.user_extensions.school_id @course.setup_time = params[:setup_time] @course.endup_time = params[:endup_time] @course.class_period = params[:class_period] diff --git a/app/views/projects/_course_form.html.erb b/app/views/projects/_course_form.html.erb index 944157a9b..017c4e6ee 100644 --- a/app/views/projects/_course_form.html.erb +++ b/app/views/projects/_course_form.html.erb @@ -284,13 +284,7 @@ - -

- <%=l(:label_new_course_school)%>*    - <%= select_tag "province", options_from_collection_for_select(School.find_by_sql("select distinct province from schools"), :province, :province), :onclick => "get_options(this.value)" %> - <%= select_tag "occupation" %> -

From 05c0d2a5ac576c3fc84997eca557985f824cda30 Mon Sep 17 00:00:00 2001 From: wanglinchun Date: Tue, 22 Apr 2014 19:27:31 +0800 Subject: [PATCH 10/54] =?UTF-8?q?=E6=9B=BF=E6=8D=A2=E7=AB=9E=E8=B5=9B?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E9=A6=96=E9=A1=B5=E4=B8=AD=E7=AB=9E=E8=B5=9B?= =?UTF-8?q?=E5=92=8C=E5=BA=94=E7=94=A8=E7=9A=84=E5=9B=BE=E6=A0=87=E5=B9=B6?= =?UTF-8?q?=E8=B0=83=E6=95=B4=E7=9B=B8=E5=BA=94=E7=9A=84=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../softapplications_controller.rb | 2 +- .../contests/_list_softapplications.html.erb | 1 - app/views/softapplications/_form.html.erb | 97 +++++++++--------- app/views/softapplications/edit.html.erb | 10 +- app/views/softapplications/new.html.erb | 73 +------------ app/views/softapplications/show.html.erb | 4 + app/views/welcome/contest.html.erb | 16 +-- config/locales/zh.yml | 1 + public/images/app1.png | Bin 0 -> 4441 bytes public/images/contest1.png | Bin 0 -> 4794 bytes 10 files changed, 72 insertions(+), 132 deletions(-) create mode 100644 public/images/app1.png create mode 100644 public/images/contest1.png diff --git a/app/controllers/softapplications_controller.rb b/app/controllers/softapplications_controller.rb index 9163f5473..5153a01d4 100644 --- a/app/controllers/softapplications_controller.rb +++ b/app/controllers/softapplications_controller.rb @@ -100,7 +100,7 @@ class SoftapplicationsController < ApplicationController @softapplication.destroy respond_to do |format| - format.html { redirect_to :back } + format.html { redirect_to home_path } format.json { head :no_content } end end diff --git a/app/views/contests/_list_softapplications.html.erb b/app/views/contests/_list_softapplications.html.erb index 5646f5d12..29c985b7e 100644 --- a/app/views/contests/_list_softapplications.html.erb +++ b/app/views/contests/_list_softapplications.html.erb @@ -8,7 +8,6 @@ <%= link_to(c_softapplication.softapplication.name, softapplication_path(c_softapplication.softapplication)) %> - <%= link_to '删除', c_softapplication.softapplication, method: :delete, data: { confirm: '您确定要删除吗?' } %>
diff --git a/app/views/softapplications/_form.html.erb b/app/views/softapplications/_form.html.erb index 5a046801f..f45125ea2 100644 --- a/app/views/softapplications/_form.html.erb +++ b/app/views/softapplications/_form.html.erb @@ -1,64 +1,69 @@ -<%= form_for(@softapplication) do |f| %> +<%= form_for(softapplication) do |f| %> - <% if @softapplication.errors.any? %> + <% if softapplication.errors.any? %>
-

<%= pluralize(@softapplication.errors.count, "error") %> prohibited this softapplication from being saved:

+

<%= pluralize(softapplication.errors.count, "error") %> prohibited this softapplication from being saved:

    - <% @softapplication.errors.full_messages.each do |msg| %> + <% softapplication.errors.full_messages.each do |msg| %>
  • <%= msg %>
  • <% end %>
<% end %> - - - <%= l(:label_softapplication_name) %> - * : - <%= f.text_field :name, :required => true, :size => 60, :style => "width:400px;" %> - <%= l(:label_softapplication_name_condition)%> -

+
+ + + <%= l(:label_softapplication_name) %> + * : <%= f.text_field :name, :required => true, :size => 60, :style => "width:400px;" %> + <%= l(:label_softapplication_name_condition)%> + +
+
+ + + <%= l(:label_softapplication_version_available) %> + * : <%= f.text_field :android_min_version_available, :required => true, :size => 60, :style => "width:400px;" %> - - <%= l(:label_softapplication_version_available) %> - * : - <%= f.text_field :android_min_version_available, :required => true, :size => 60, :style => "width:400px;" %> + +
+
+ + + <%= l(:label_softapplication_type) %> -

+ * : <%= f.text_field :app_type_name, :required => true, :size => 60, :style => "width:400px;" %> - - <%= l(:label_softapplication_type) %> - * : - <%= f.text_field :app_type_name, :required => true, :size => 60, :style => "width:400px;" %> + +
+
+ + + <%= l(:label_softapplication_description) %> + * : <%= f.text_field :description, :required => true, :size => 60, :style => "width:400px;" %> -

+ +
+
+ + <%= l(:label_softapplication_developers) %> + * : <%= f.text_field :application_developers, :required => true, :size => 60, :style => "width:400px;" %> - - <%= l(:label_softapplication_description) %> - * : - <%= f.text_field :description, :required => true, :size => 60, :style => "width:400px;" %> - -

- - -
-
- <%=l(:label_upload_softapplication_packets)%> :
-

- <%= render :partial => 'attachments/form' %> -

-
-
- -
-
- <%=l(:label_upload_softapplication_photo)%> :(<%=l(:label_upload_softapplication_photo_condition)%>)
-

- <%= render :partial => 'attachments/form' %> -

-
-
+ +
+
+
+ 上传应用软件包和应用截图 + <%= render_flash_messages %> +

+ <%= render :partial => 'attachments/form' %> +

+

(<%=l(:label_upload_softapplication_photo_condition)%>)

+ +
+

+
<%= submit_tag l(:button_create), :onclick => "return true" %>
<% end %> diff --git a/app/views/softapplications/edit.html.erb b/app/views/softapplications/edit.html.erb index f93e091d2..c9e0c6f66 100644 --- a/app/views/softapplications/edit.html.erb +++ b/app/views/softapplications/edit.html.erb @@ -1,6 +1,8 @@ -

Editing softapplication

+

<%= l(:label_edit_softapplication)%>

+ +<%= render partial: 'form', locals:{softapplication: @softapplication} %> + + -<%= render 'form' %> -<%= link_to 'Show', @softapplication %> | -<%= link_to 'Back', softapplications_path %> diff --git a/app/views/softapplications/new.html.erb b/app/views/softapplications/new.html.erb index d5ff2c9c2..1112fcfa4 100644 --- a/app/views/softapplications/new.html.erb +++ b/app/views/softapplications/new.html.erb @@ -1,76 +1,5 @@

<%= l(:label_release_softapplication)%>

- +<%= render partial: 'form', locals:{softapplication: @softapplication} %> -
- <%= form_for Softapplication.new, :url => {:controller => 'softapplications', :action => 'create'}, :update => "bidding_project_list", :complete => '$("#put-bid-form").hide();', :html => {:multipart => true, :id => 'add_homework_form'} do |f| %> -
- - - <%= l(:label_softapplication_name) %> - * : <%= f.text_field :name, :required => true, :size => 60, :style => "width:400px;" %> - <%= l(:label_softapplication_name_condition)%> - -
-
- - - <%= l(:label_softapplication_version_available) %> - * : <%= f.text_field :android_min_version_available, :required => true, :size => 60, :style => "width:400px;" %> - - -
-
- - - <%= l(:label_softapplication_type) %> - - * : <%= f.text_field :app_type_name, :required => true, :size => 60, :style => "width:400px;" %> - - -
-
- - - <%= l(:label_softapplication_description) %> - * : <%= f.text_field :description, :required => true, :size => 60, :style => "width:400px;" %> - - -
-
- - - <%= l(:label_softapplication_developers) %> - * : <%= f.text_field :application_developers, :required => true, :size => 60, :style => "width:400px;" %> - - -
-
-
- 上传应用软件包和应用截图 - <%= render_flash_messages %> -

- <%= render :partial => 'attachments/form' %> -

-

(<%=l(:label_upload_softapplication_photo_condition)%>)

- -
-

-
<%= submit_tag l(:button_create), :onclick => "return true" %>
- -
- <% end %> -
\ No newline at end of file diff --git a/app/views/softapplications/show.html.erb b/app/views/softapplications/show.html.erb index a5c3fb596..d5681c4ea 100644 --- a/app/views/softapplications/show.html.erb +++ b/app/views/softapplications/show.html.erb @@ -18,6 +18,10 @@ + diff --git a/app/views/welcome/contest.html.erb b/app/views/welcome/contest.html.erb index f283bd759..6ef2b4796 100644 --- a/app/views/welcome/contest.html.erb +++ b/app/views/welcome/contest.html.erb @@ -142,18 +142,18 @@
  • - <%= image_tag('/images/039.gif')%> + <%= image_tag('/images/contest1.png')%>
    -
    +
    <%= link_to(contest.name, contest.event_url, :class => "d-g-blue d-p-project-name", :title => "#{contest.name}", :target => "_blank") %>
    -
    +
    ><%=contest.description.truncate(50, omission: '...')%>

    -
    +
    发布时间:<%=format_time contest.created_on %>
    @@ -204,18 +204,18 @@
  • - <%= image_tag('/images/009.gif')%> + <%= image_tag('/images/app1.png')%>
    -
    +
    <%= link_to(softapplication.name, softapplication_path(softapplication.id), :class => "d-g-blue d-p-project-name", :title => "#{softapplication.name}", :target => "_blank") %>
    -
    +
    ><%=softapplication.description.truncate(50, omission: '...')%>

    -
    +
    发布时间:<%=format_time softapplication.created_at %>
    diff --git a/config/locales/zh.yml b/config/locales/zh.yml index 079ad450d..c32c62c05 100644 --- a/config/locales/zh.yml +++ b/config/locales/zh.yml @@ -1855,6 +1855,7 @@ zh: label_release_add_contest_succeed: 该应用发布并添加成功. label_add_contest_succeed_fail: 添加失败,该应用已参赛. label_no_ftapplication: 暂无应用 + label_edit_softapplication: 修改应用 \ No newline at end of file diff --git a/public/images/app1.png b/public/images/app1.png new file mode 100644 index 0000000000000000000000000000000000000000..3342781acd7be2b0a01a8b359d4a74d0ba775404 GIT binary patch literal 4441 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 pcFNM^UH~-@J+h%%912{q0Y`G(d}Hg Date: Tue, 22 Apr 2014 20:23:15 +0800 Subject: [PATCH 11/54] =?UTF-8?q?=E5=BA=94=E7=94=A8=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=89=80=E5=B1=9E=E7=AB=9E=E8=B5=9B=E5=8F=8A?= =?UTF-8?q?=E7=9B=B8=E5=BA=94=E9=93=BE=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/softapplications/show.html.erb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/views/softapplications/show.html.erb b/app/views/softapplications/show.html.erb index d5681c4ea..51195dfcf 100644 --- a/app/views/softapplications/show.html.erb +++ b/app/views/softapplications/show.html.erb @@ -25,7 +25,8 @@
  • - + <% contest = @softapplication.contests.first %> + @@ -42,7 +43,7 @@ - + From 60bc3bb1b2da1d6d80dde15e9691f307926cf4c8 Mon Sep 17 00:00:00 2001 From: yanxd Date: Wed, 23 Apr 2014 08:46:40 +0800 Subject: [PATCH 12/54] seem_rateable to lib, using Engine setting routes --- Gemfile | 2 +- app/controllers/ratings_controller.rb | 15 --- config/routes.rb | 3 +- lib/plugins/seems_rateable-master/.gitignore | 21 ---- lib/plugins/seems_rateable-master/Rakefile | 32 ----- .../seems_rateable/application_controller.rb | 4 - .../seems_rateable/application_helper.rb | 4 - .../helpers/seems_rateable/ratings_helper.rb | 4 - .../app/models/seems_rateable/rate.rb | 6 - .../seems_rateable/application.html.erb | 14 --- .../install/install_generator.rb | 39 ------ .../templates/cached_ratings_migration.rb | 17 --- .../lib/seems_rateable/engine.rb | 17 --- .../lib/seems_rateable/errors.rb | 21 ---- .../lib/seems_rateable/helpers.rb | 27 ----- .../lib/seems_rateable/model.rb | 111 ------------------ .../lib/tasks/seems_rateable_tasks.rake | 4 - .../Gemfile | 0 .../MIT-LICENSE | 0 .../README.md | 12 +- lib/seems_rateable/Rakefile | 17 +++ .../images/seems_rateable/bg_jRatingInfos.png | Bin .../assets/images/seems_rateable/small.png | Bin .../assets/images/seems_rateable/stars.png | Bin .../javascripts/seems_rateable/application.js | 0 .../seems_rateable/application.css | 54 ++++----- .../seems_rateable/application_controller.rb | 7 ++ .../seems_rateable/ratings_controller.rb | 13 ++ .../models/seems_rateable/cached_rating.rb | 2 +- .../app/models/seems_rateable/rate.rb | 6 + .../bin/rails | 0 .../config/routes.rb | 0 .../install/install_generator.rb | 42 +++++++ .../templates/cached_ratings_migration.rb | 17 +++ .../install/templates/initializer.rb | 0 .../install/templates/jRating.js.erb | 6 +- .../install/templates/rateable.js.erb | 4 +- .../install/templates/rates_migration.rb | 2 +- .../lib/seems_rateable.rb | 4 +- .../lib/seems_rateable/engine.rb | 16 +++ .../lib/seems_rateable/errors.rb | 21 ++++ .../lib/seems_rateable/helpers.rb | 27 +++++ .../lib/seems_rateable/model.rb | 91 ++++++++++++++ .../lib/seems_rateable/routes.rb | 0 .../lib/seems_rateable/version.rb | 2 +- .../seems_rateable.gemspec | 0 public/images/footer_logo/inforbus.png | Bin 6154 -> 56477 bytes public/images/footer_logo/iscas.png | Bin 4857 -> 53769 bytes public/javascripts/seems_rateable/jRating.js | 2 +- public/javascripts/seems_rateable/rateable.js | 2 +- 50 files changed, 306 insertions(+), 382 deletions(-) delete mode 100644 app/controllers/ratings_controller.rb delete mode 100644 lib/plugins/seems_rateable-master/.gitignore delete mode 100644 lib/plugins/seems_rateable-master/Rakefile delete mode 100644 lib/plugins/seems_rateable-master/app/controllers/seems_rateable/application_controller.rb delete mode 100644 lib/plugins/seems_rateable-master/app/helpers/seems_rateable/application_helper.rb delete mode 100644 lib/plugins/seems_rateable-master/app/helpers/seems_rateable/ratings_helper.rb delete mode 100644 lib/plugins/seems_rateable-master/app/models/seems_rateable/rate.rb delete mode 100644 lib/plugins/seems_rateable-master/app/views/layouts/seems_rateable/application.html.erb delete mode 100644 lib/plugins/seems_rateable-master/lib/generators/seems_rateable/install/install_generator.rb delete mode 100644 lib/plugins/seems_rateable-master/lib/generators/seems_rateable/install/templates/cached_ratings_migration.rb delete mode 100644 lib/plugins/seems_rateable-master/lib/seems_rateable/engine.rb delete mode 100644 lib/plugins/seems_rateable-master/lib/seems_rateable/errors.rb delete mode 100644 lib/plugins/seems_rateable-master/lib/seems_rateable/helpers.rb delete mode 100644 lib/plugins/seems_rateable-master/lib/seems_rateable/model.rb delete mode 100644 lib/plugins/seems_rateable-master/lib/tasks/seems_rateable_tasks.rake rename lib/{plugins/seems_rateable-master => seems_rateable}/Gemfile (100%) rename lib/{plugins/seems_rateable-master => seems_rateable}/MIT-LICENSE (100%) rename lib/{plugins/seems_rateable-master => seems_rateable}/README.md (95%) create mode 100644 lib/seems_rateable/Rakefile rename lib/{plugins/seems_rateable-master => seems_rateable}/app/assets/images/seems_rateable/bg_jRatingInfos.png (100%) rename lib/{plugins/seems_rateable-master => seems_rateable}/app/assets/images/seems_rateable/small.png (100%) rename lib/{plugins/seems_rateable-master => seems_rateable}/app/assets/images/seems_rateable/stars.png (100%) rename lib/{plugins/seems_rateable-master => seems_rateable}/app/assets/javascripts/seems_rateable/application.js (100%) rename lib/{plugins/seems_rateable-master => seems_rateable}/app/assets/stylesheets/seems_rateable/application.css (60%) create mode 100644 lib/seems_rateable/app/controllers/seems_rateable/application_controller.rb create mode 100644 lib/seems_rateable/app/controllers/seems_rateable/ratings_controller.rb rename lib/{plugins/seems_rateable-master => seems_rateable}/app/models/seems_rateable/cached_rating.rb (60%) create mode 100644 lib/seems_rateable/app/models/seems_rateable/rate.rb rename lib/{plugins/seems_rateable-master => seems_rateable}/bin/rails (100%) rename lib/{plugins/seems_rateable-master => seems_rateable}/config/routes.rb (100%) create mode 100644 lib/seems_rateable/lib/generators/seems_rateable/install/install_generator.rb create mode 100644 lib/seems_rateable/lib/generators/seems_rateable/install/templates/cached_ratings_migration.rb rename lib/{plugins/seems_rateable-master => seems_rateable}/lib/generators/seems_rateable/install/templates/initializer.rb (100%) rename lib/{plugins/seems_rateable-master => seems_rateable}/lib/generators/seems_rateable/install/templates/jRating.js.erb (95%) rename lib/{plugins/seems_rateable-master => seems_rateable}/lib/generators/seems_rateable/install/templates/rateable.js.erb (93%) rename lib/{plugins/seems_rateable-master => seems_rateable}/lib/generators/seems_rateable/install/templates/rates_migration.rb (98%) rename lib/{plugins/seems_rateable-master => seems_rateable}/lib/seems_rateable.rb (85%) create mode 100644 lib/seems_rateable/lib/seems_rateable/engine.rb create mode 100644 lib/seems_rateable/lib/seems_rateable/errors.rb create mode 100644 lib/seems_rateable/lib/seems_rateable/helpers.rb create mode 100644 lib/seems_rateable/lib/seems_rateable/model.rb rename lib/{plugins/seems_rateable-master => seems_rateable}/lib/seems_rateable/routes.rb (100%) rename lib/{plugins/seems_rateable-master => seems_rateable}/lib/seems_rateable/version.rb (54%) rename lib/{plugins/seems_rateable-master => seems_rateable}/seems_rateable.gemspec (100%) diff --git a/Gemfile b/Gemfile index b20c8653a..0ea40e013 100644 --- a/Gemfile +++ b/Gemfile @@ -6,7 +6,7 @@ unless RUBY_PLATFORM =~ /w32/ gem 'rubyzip' gem 'zip-zip' end -gem 'seems_rateable' +gem 'seems_rateable', path: 'lib/seems_rateable' gem "rails", "3.2.13" gem "jquery-rails", "~> 2.0.2" gem "i18n", "~> 0.6.0" diff --git a/app/controllers/ratings_controller.rb b/app/controllers/ratings_controller.rb deleted file mode 100644 index 5ae478af8..000000000 --- a/app/controllers/ratings_controller.rb +++ /dev/null @@ -1,15 +0,0 @@ -require_dependency "seems_rateable/application_controller" - -class RatingsController < ::ApplicationController - def create - raise NoCurrentUserInstanceError unless current_user - - obj = params[:kls].classify.constantize.find(params[:idBox]) - begin - obj.rate(params[:rate].to_i, current_user.id, params[:dimension]) - render :json => true - rescue Errors::AlreadyRatedError - render :json => {:error => true} - end - end -end diff --git a/config/routes.rb b/config/routes.rb index 54d9124f0..bf6f3ceee 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -16,7 +16,8 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. RedmineApp::Application.routes.draw do - resources :ratings, :only => :create + mount SeemsRateable::Engine => '/rateable', :as => :rateable + namespace :zipdown do match 'assort' end diff --git a/lib/plugins/seems_rateable-master/.gitignore b/lib/plugins/seems_rateable-master/.gitignore deleted file mode 100644 index f372f8d4f..000000000 --- a/lib/plugins/seems_rateable-master/.gitignore +++ /dev/null @@ -1,21 +0,0 @@ -*.gem -*.rbc -.bundle -.config -.yardoc -Gemfile.lock -InstalledFiles -_yardoc -coverage -doc/ -lib/bundler/man -pkg -rdoc -spec/reports -test/tmp -test/version_tmp -tmp -.project -.rvmrc -spec -test diff --git a/lib/plugins/seems_rateable-master/Rakefile b/lib/plugins/seems_rateable-master/Rakefile deleted file mode 100644 index c2ef03737..000000000 --- a/lib/plugins/seems_rateable-master/Rakefile +++ /dev/null @@ -1,32 +0,0 @@ -begin - require 'bundler/setup' -rescue LoadError - puts 'You must `gem install bundler` and `bundle install` to run rake tasks' -end - -require 'rdoc/task' - -RDoc::Task.new(:rdoc) do |rdoc| - rdoc.rdoc_dir = 'rdoc' - rdoc.title = 'SeemsRateable' - rdoc.options << '--line-numbers' - rdoc.rdoc_files.include('README.rdoc') - rdoc.rdoc_files.include('lib/**/*.rb') -end - -APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__) -load 'rails/tasks/engine.rake' -Bundler::GemHelper.install_tasks - -APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__) -load 'rails/tasks/engine.rake' - -Dir[File.join(File.dirname(__FILE__), 'tasks/**/*.rake')].each {|f| load f } -require 'rspec/core' -require 'rspec/core/rake_task' - -task :default => :spec - - - - diff --git a/lib/plugins/seems_rateable-master/app/controllers/seems_rateable/application_controller.rb b/lib/plugins/seems_rateable-master/app/controllers/seems_rateable/application_controller.rb deleted file mode 100644 index cd94242dd..000000000 --- a/lib/plugins/seems_rateable-master/app/controllers/seems_rateable/application_controller.rb +++ /dev/null @@ -1,4 +0,0 @@ -module SeemsRateable - class ApplicationController < ActionController::Base - end -end diff --git a/lib/plugins/seems_rateable-master/app/helpers/seems_rateable/application_helper.rb b/lib/plugins/seems_rateable-master/app/helpers/seems_rateable/application_helper.rb deleted file mode 100644 index 596eeb4c9..000000000 --- a/lib/plugins/seems_rateable-master/app/helpers/seems_rateable/application_helper.rb +++ /dev/null @@ -1,4 +0,0 @@ -module SeemsRateable - module ApplicationHelper - end -end diff --git a/lib/plugins/seems_rateable-master/app/helpers/seems_rateable/ratings_helper.rb b/lib/plugins/seems_rateable-master/app/helpers/seems_rateable/ratings_helper.rb deleted file mode 100644 index 91c7411c4..000000000 --- a/lib/plugins/seems_rateable-master/app/helpers/seems_rateable/ratings_helper.rb +++ /dev/null @@ -1,4 +0,0 @@ -module SeemsRateable - module RatingsHelper - end -end diff --git a/lib/plugins/seems_rateable-master/app/models/seems_rateable/rate.rb b/lib/plugins/seems_rateable-master/app/models/seems_rateable/rate.rb deleted file mode 100644 index f9db806a3..000000000 --- a/lib/plugins/seems_rateable-master/app/models/seems_rateable/rate.rb +++ /dev/null @@ -1,6 +0,0 @@ -module SeemsRateable - class Rate < ActiveRecord::Base - belongs_to :rater, :class_name => SeemsRateable::Engine.config.owner_class - belongs_to :rateable, :polymorphic => true - end -end diff --git a/lib/plugins/seems_rateable-master/app/views/layouts/seems_rateable/application.html.erb b/lib/plugins/seems_rateable-master/app/views/layouts/seems_rateable/application.html.erb deleted file mode 100644 index 3c63ba433..000000000 --- a/lib/plugins/seems_rateable-master/app/views/layouts/seems_rateable/application.html.erb +++ /dev/null @@ -1,14 +0,0 @@ - - - - SeemsRateable - <%= stylesheet_link_tag "seems_rateable/application", media: "all" %> - <%= javascript_include_tag "seems_rateable/application" %> - <%= csrf_meta_tags %> - - - -<%= yield %> - - - diff --git a/lib/plugins/seems_rateable-master/lib/generators/seems_rateable/install/install_generator.rb b/lib/plugins/seems_rateable-master/lib/generators/seems_rateable/install/install_generator.rb deleted file mode 100644 index 9a3aac0a5..000000000 --- a/lib/plugins/seems_rateable-master/lib/generators/seems_rateable/install/install_generator.rb +++ /dev/null @@ -1,39 +0,0 @@ -require 'rails/generators/migration' -require 'fileutils' - -module SeemsRateable - module Generators - class InstallGenerator < ::Rails::Generators::Base - include Rails::Generators::Migration - source_root File.expand_path('../templates', __FILE__) - - def self.next_migration_number(path) - unless @prev_migration_nr - @prev_migration_nr = Time.now.utc.strftime("%Y%m%d%H%M%S").to_i - else - @prev_migration_nr += 1 - end - @prev_migration_nr.to_s - end - - desc "generating migration files" - def copy_migrations - migration_template "rates_migration.rb", "db/migrate/create_seems_rateable_rates.rb" - migration_template "cached_ratings_migration.rb", "db/migrate/create_seems_rateable_cached_ratings.rb" - end - - desc "generating initializer" - def copy_initializer - template "initializer.rb", "config/initializers/seems_rateable.rb" - end - - desc "generating javascript files" - def copy_javascript_asset - Dir.mkdir "app/assets/javascripts/rateable" unless File.directory?("app/assets/javascripts/rateable") - copy_file "rateable.js.erb", "app/assets/javascripts/rateable/rateable.js.erb" unless File.exists?("app/assets/javascripts/rateable/rateable.js.erb") - copy_file "jRating.js.erb", "app/assets/javascripts/rateable/jRating.js.erb" unless File.exists?("app/assets/javascripts/rateable/jRating.js.erb") - end - - end - end -end diff --git a/lib/plugins/seems_rateable-master/lib/generators/seems_rateable/install/templates/cached_ratings_migration.rb b/lib/plugins/seems_rateable-master/lib/generators/seems_rateable/install/templates/cached_ratings_migration.rb deleted file mode 100644 index 1b91bdadc..000000000 --- a/lib/plugins/seems_rateable-master/lib/generators/seems_rateable/install/templates/cached_ratings_migration.rb +++ /dev/null @@ -1,17 +0,0 @@ -class CreateSeemsRateableCachedRatings < ActiveRecord::Migration - def self.up - create_table :seems_rateable_cached_ratings do |t| - t.belongs_to :cacheable, :polymorphic => true - t.float :avg, :null => false - t.integer :cnt, :null => false - t.string :dimension - t.integer :cacheable_id, :limit => 8 - t.string :cacheable_type - t.timestamps - end - end - - def self.down - drop_table :cached_ratings - end -end diff --git a/lib/plugins/seems_rateable-master/lib/seems_rateable/engine.rb b/lib/plugins/seems_rateable-master/lib/seems_rateable/engine.rb deleted file mode 100644 index 185d6f9d9..000000000 --- a/lib/plugins/seems_rateable-master/lib/seems_rateable/engine.rb +++ /dev/null @@ -1,17 +0,0 @@ -module SeemsRateable - class Engine < ::Rails::Engine - isolate_namespace SeemsRateable - - config.generators do |g| - g.test_framework :rspec, :fixture => false - g.fixture_replacement :factory_girl, :dir => 'spec/factories' - end - - initializer :seems_rateable do - ActiveRecord::Base.send :include, SeemsRateable::Model - ActionView::Base.send :include, SeemsRateable::Helpers - ActionDispatch::Routing::Mapper.send :include, SeemsRateable::Routes - end - - end -end diff --git a/lib/plugins/seems_rateable-master/lib/seems_rateable/errors.rb b/lib/plugins/seems_rateable-master/lib/seems_rateable/errors.rb deleted file mode 100644 index 8a83059ba..000000000 --- a/lib/plugins/seems_rateable-master/lib/seems_rateable/errors.rb +++ /dev/null @@ -1,21 +0,0 @@ -module SeemsRateable - module Errors - class InvalidRateableObjectError < StandardError - def to_s - "Stated object is not rateable. Add 'seems_rateable' to your object's class model." - end - end - - class NoCurrentUserInstanceError < StandardError - def to_s - "User instance current_user is not available." - end - end - - class AlreadyRatedError < StandardError - def to_s - "User has already rated an object." - end - end - end -end diff --git a/lib/plugins/seems_rateable-master/lib/seems_rateable/helpers.rb b/lib/plugins/seems_rateable-master/lib/seems_rateable/helpers.rb deleted file mode 100644 index 399f06fd8..000000000 --- a/lib/plugins/seems_rateable-master/lib/seems_rateable/helpers.rb +++ /dev/null @@ -1,27 +0,0 @@ -module SeemsRateable - module Helpers - def rating_for(obj, opts={}) - raise Errors::InvalidRateableObjectError unless obj.class.respond_to?(:rateable?) - - options = { - :dimension => nil, - :static => false, - :class => 'rateable', - :id => nil - }.update(opts) - - content_tag :div, "", "data-average" => obj.average(options[:dimension]) ? obj.average(options[:dimension]).avg : 0, :id => options[:id], - :class => "#{options[:class]}#{jdisabled?(options[:static])}", - "data-id" => obj.id, "data-kls" => obj.class.name, "data-dimension" => options[:dimension] - end - - def seems_rateable_stylesheet - stylesheet_link_tag "seems_rateable/application", media: "all", "data-turbolinks-track" => true - end - - private - def jdisabled?(option) - " jDisabled" if option || !current_user - end - end -end diff --git a/lib/plugins/seems_rateable-master/lib/seems_rateable/model.rb b/lib/plugins/seems_rateable-master/lib/seems_rateable/model.rb deleted file mode 100644 index fa1b7af11..000000000 --- a/lib/plugins/seems_rateable-master/lib/seems_rateable/model.rb +++ /dev/null @@ -1,111 +0,0 @@ -require 'active_support/concern' -module SeemsRateable - module Model - extend ActiveSupport::Concern - - def rate(stars, user_id, dimension=nil) - if !has_rated?(user_id, dimension) - self.rates.create do |r| - r.stars = stars - r.rater_id = user_id - end - update_overall_average_rating(stars, dimension) - elsif has_rated?(user_id, dimension) && can_update? - update_users_rating(stars, user_id, dimension) - else - raise Errors::AlreadyRatedError - end - end - - def update_overall_average_rating(stars, dimension=nil) - if average(dimension).nil? - CachedRating.create do |r| - r.avg = stars - r.dimension = dimension - r.cacheable_id = self.id - r.cacheable_type = self.class.name - r.cnt = 1 - end - else - r = average(dimension) - r.avg = (r.avg * r.cnt + stars) / (r.cnt+1) - r.cnt += 1 - r.save! - end - end - - def update_users_rating(stars, user_id, dimension=nil) - obj = rates(dimension).where(:rater_id => user_id).first - current_record = average(dimension) - current_record.avg = (current_record.avg*current_record.cnt - obj.stars + stars) / (current_record.cnt) - current_record.save! - obj.stars = stars - obj.save! - end - - - def average(dimension=nil) - if dimension.nil? - self.send "rate_average_without_dimension" - else - self.send "#{dimension}_average" - end - end - - def rates(dimension=nil) - if dimension.nil? - self.send "rates_without_dimension" - else - self.send "#{dimension}_rates" - end - end - - def raters(dimension=nil) - if dimension.nil? - self.send "raters_without_dimension" - else - self.send "#{dimension}_raters" - end - end - - def has_rated?(user_id, dimension=nil) - record = self.rates(dimension).where(:rater_id => user_id) - record.empty? ? false : true - end - - def can_update? - self.class.can_update? - end - - module ClassMethods - def seems_rateable(opts={}) - #has_many :rates_without_dimension, -> { where(dimension: nil) }, :as => :rateable, :class_name => SeemsRateable::Rate, :dependent => :destroy - has_many :rates_without_dimension, :conditions => { dimension: nil }, :as => :rateable, :class_name => SeemsRateable::Rate, :dependent => :destroy - has_many :raters_without_dimension, :through => :rates_without_dimension, :source => :rater - has_one :rate_average_without_dimension, :conditions => { dimension: nil }, :as => :cacheable, :class_name => SeemsRateable::CachedRating, :dependent => :destroy - - @permission = opts[:allow_update] ? true : false - - def self.can_update? - @permission - end - - def self.rateable? - true - end - - if opts[:dimensions].is_a?(Array) - opts[:dimensions].each do |dimension| - has_many :"#{dimension}_rates", :conditions => { dimension: dimension.to_s }, :dependent => :destroy, :class_name => SeemsRateable::Rate, :as => :rateable - has_many :"#{dimension}_raters", :through => :"#{dimension}_rates", :source => :rater - has_one :"#{dimension}_average", :conditions => { dimension: dimension.to_s }, :as => :cacheable, :class_name => SeemsRateable::CachedRating, :dependent => :destroy - end - end - end - - def seems_rateable_rater - has_many :ratings_given, :class_name => SeemsRateable::Rate, :foreign_key => :rater_id - end - end - end -end diff --git a/lib/plugins/seems_rateable-master/lib/tasks/seems_rateable_tasks.rake b/lib/plugins/seems_rateable-master/lib/tasks/seems_rateable_tasks.rake deleted file mode 100644 index 98c5403ac..000000000 --- a/lib/plugins/seems_rateable-master/lib/tasks/seems_rateable_tasks.rake +++ /dev/null @@ -1,4 +0,0 @@ -# desc "Explaining what the task does" -# task :seems_rateable do -# # Task goes here -# end diff --git a/lib/plugins/seems_rateable-master/Gemfile b/lib/seems_rateable/Gemfile similarity index 100% rename from lib/plugins/seems_rateable-master/Gemfile rename to lib/seems_rateable/Gemfile diff --git a/lib/plugins/seems_rateable-master/MIT-LICENSE b/lib/seems_rateable/MIT-LICENSE similarity index 100% rename from lib/plugins/seems_rateable-master/MIT-LICENSE rename to lib/seems_rateable/MIT-LICENSE diff --git a/lib/plugins/seems_rateable-master/README.md b/lib/seems_rateable/README.md similarity index 95% rename from lib/plugins/seems_rateable-master/README.md rename to lib/seems_rateable/README.md index 3e78d0250..aacc7407b 100644 --- a/lib/plugins/seems_rateable-master/README.md +++ b/lib/seems_rateable/README.md @@ -45,7 +45,7 @@ Don't forget to run $ rake db:migrate -To prepare model add seems_rateable to your rateable model file. You can also pass a hash of options to +To prepare model add seems_rateable to your rateable model file. You can also pass a hash of options to customize the functionality
      @@ -76,7 +76,7 @@ And to object's raters e.g @object.raters(:quantity) To track user's given ratings add seems_rateable_rater to your rater model. -If your rater class is not "User"(e.g "Client" or "Customer") change configuration in initializer generated by this engine. +If your rater class is not "User"(e.g "Client" or "Customer") change configuration in initializer generated by this engine. Now you can access user's ratings by @user.ratings_given ### Usage @@ -84,13 +84,13 @@ Now you can access user's ratings by @user.ratings_given To display star rating use helper method rating_for in your view #index.html.erb - + rating_for @post - + rating_for @post, :dimension => :quality, :class => 'post', :id => 'list' - + rating_for @post, :static => true - + You can specify these options :
      • :dimensionThe dimension of the object
      • diff --git a/lib/seems_rateable/Rakefile b/lib/seems_rateable/Rakefile new file mode 100644 index 000000000..cc267251e --- /dev/null +++ b/lib/seems_rateable/Rakefile @@ -0,0 +1,17 @@ +begin + require 'bundler/setup' +rescue LoadError + puts 'You must `gem install bundler` and `bundle install` to run rake tasks' +end + +require 'rdoc/task' + +RDoc::Task.new(:rdoc) do |rdoc| + rdoc.rdoc_dir = 'rdoc' + rdoc.title = 'SeemsRateable' + rdoc.options << '--line-numbers' + rdoc.rdoc_files.include('README.md') + rdoc.rdoc_files.include('lib/**/*.rb') +end + +Bundler::GemHelper.install_tasks diff --git a/lib/plugins/seems_rateable-master/app/assets/images/seems_rateable/bg_jRatingInfos.png b/lib/seems_rateable/app/assets/images/seems_rateable/bg_jRatingInfos.png similarity index 100% rename from lib/plugins/seems_rateable-master/app/assets/images/seems_rateable/bg_jRatingInfos.png rename to lib/seems_rateable/app/assets/images/seems_rateable/bg_jRatingInfos.png diff --git a/lib/plugins/seems_rateable-master/app/assets/images/seems_rateable/small.png b/lib/seems_rateable/app/assets/images/seems_rateable/small.png similarity index 100% rename from lib/plugins/seems_rateable-master/app/assets/images/seems_rateable/small.png rename to lib/seems_rateable/app/assets/images/seems_rateable/small.png diff --git a/lib/plugins/seems_rateable-master/app/assets/images/seems_rateable/stars.png b/lib/seems_rateable/app/assets/images/seems_rateable/stars.png similarity index 100% rename from lib/plugins/seems_rateable-master/app/assets/images/seems_rateable/stars.png rename to lib/seems_rateable/app/assets/images/seems_rateable/stars.png diff --git a/lib/plugins/seems_rateable-master/app/assets/javascripts/seems_rateable/application.js b/lib/seems_rateable/app/assets/javascripts/seems_rateable/application.js similarity index 100% rename from lib/plugins/seems_rateable-master/app/assets/javascripts/seems_rateable/application.js rename to lib/seems_rateable/app/assets/javascripts/seems_rateable/application.js diff --git a/lib/plugins/seems_rateable-master/app/assets/stylesheets/seems_rateable/application.css b/lib/seems_rateable/app/assets/stylesheets/seems_rateable/application.css similarity index 60% rename from lib/plugins/seems_rateable-master/app/assets/stylesheets/seems_rateable/application.css rename to lib/seems_rateable/app/assets/stylesheets/seems_rateable/application.css index 64099e546..aeb6475f3 100644 --- a/lib/plugins/seems_rateable-master/app/assets/stylesheets/seems_rateable/application.css +++ b/lib/seems_rateable/app/assets/stylesheets/seems_rateable/application.css @@ -20,43 +20,43 @@ .jRatingAverage { - background-color:#f62929; - position:relative; - top:0; - left:0; - z-index:2; - height:100%; + background-color:#f62929; + position:relative; + top:0; + left:0; + z-index:2; + height:100%; } .jRatingColor { - background-color:#FFD400; /* bgcolor of the stars*/ - position:relative; - top:0; - left:0; - z-index:2; - height:100%; + background-color:#FFD400; /* bgcolor of the stars*/ + position:relative; + top:0; + left:0; + z-index:2; + height:100%; } /** Div containing the stars **/ .jStar { - position:relative; - left:0; - z-index:3; + position:relative; + left:0; + z-index:3; } /** P containing the rate informations **/ p.jRatingInfos { - position: absolute; - z-index:9999; - background: transparent url('bg_jRatingInfos.png') no-repeat; - color: #CACACA; - display: none; - width: 91px; - height: 29px; - font-size:16px; - text-align:center; - padding-top:5px; + position: absolute; + z-index:9999; + background: transparent url('bg_jRatingInfos.png') no-repeat; + color: #CACACA; + display: none; + width: 91px; + height: 29px; + font-size:16px; + text-align:center; + padding-top:5px; } p.jRatingInfos span.maxRate { - color:#c9c9c9; - font-size:14px; + color:#c9c9c9; + font-size:14px; } diff --git a/lib/seems_rateable/app/controllers/seems_rateable/application_controller.rb b/lib/seems_rateable/app/controllers/seems_rateable/application_controller.rb new file mode 100644 index 000000000..7f0af9fc5 --- /dev/null +++ b/lib/seems_rateable/app/controllers/seems_rateable/application_controller.rb @@ -0,0 +1,7 @@ +module SeemsRateable + class ApplicationController < ::ApplicationController + rescue_from SeemsRateable::Errors::AlreadyRatedError do |exception| + render :json => {:error => true} + end + end +end diff --git a/lib/seems_rateable/app/controllers/seems_rateable/ratings_controller.rb b/lib/seems_rateable/app/controllers/seems_rateable/ratings_controller.rb new file mode 100644 index 000000000..f96dfdc84 --- /dev/null +++ b/lib/seems_rateable/app/controllers/seems_rateable/ratings_controller.rb @@ -0,0 +1,13 @@ +require_dependency "seems_rateable/application_controller" + +module SeemsRateable + class RatingsController < ApplicationController + def create + raise NoCurrentUserInstanceError unless current_user + obj = params[:kls].classify.constantize.find(params[:idBox]) + obj.rate(params[:rate].to_i, current_user.id, params[:dimension]) + + render :json => true + end + end +end diff --git a/lib/plugins/seems_rateable-master/app/models/seems_rateable/cached_rating.rb b/lib/seems_rateable/app/models/seems_rateable/cached_rating.rb similarity index 60% rename from lib/plugins/seems_rateable-master/app/models/seems_rateable/cached_rating.rb rename to lib/seems_rateable/app/models/seems_rateable/cached_rating.rb index fa56e7d44..c48ff0734 100644 --- a/lib/plugins/seems_rateable-master/app/models/seems_rateable/cached_rating.rb +++ b/lib/seems_rateable/app/models/seems_rateable/cached_rating.rb @@ -1,5 +1,5 @@ module SeemsRateable class CachedRating < ActiveRecord::Base - belongs_to :cacheable, :polymorphic => true + belongs_to :cacheable, :polymorphic => true end end diff --git a/lib/seems_rateable/app/models/seems_rateable/rate.rb b/lib/seems_rateable/app/models/seems_rateable/rate.rb new file mode 100644 index 000000000..8259ca1e7 --- /dev/null +++ b/lib/seems_rateable/app/models/seems_rateable/rate.rb @@ -0,0 +1,6 @@ +module SeemsRateable + class Rate < ActiveRecord::Base + belongs_to :rater, :class_name => SeemsRateable::Engine.config.owner_class + belongs_to :rateable, :polymorphic => true + end +end diff --git a/lib/plugins/seems_rateable-master/bin/rails b/lib/seems_rateable/bin/rails similarity index 100% rename from lib/plugins/seems_rateable-master/bin/rails rename to lib/seems_rateable/bin/rails diff --git a/lib/plugins/seems_rateable-master/config/routes.rb b/lib/seems_rateable/config/routes.rb similarity index 100% rename from lib/plugins/seems_rateable-master/config/routes.rb rename to lib/seems_rateable/config/routes.rb diff --git a/lib/seems_rateable/lib/generators/seems_rateable/install/install_generator.rb b/lib/seems_rateable/lib/generators/seems_rateable/install/install_generator.rb new file mode 100644 index 000000000..613bdac72 --- /dev/null +++ b/lib/seems_rateable/lib/generators/seems_rateable/install/install_generator.rb @@ -0,0 +1,42 @@ +require 'rails/generators/migration' +require 'fileutils' + +module SeemsRateable + module Generators + class InstallGenerator < ::Rails::Generators::Base + include Rails::Generators::Migration + source_root File.expand_path('../templates', __FILE__) + + def self.next_migration_number(path) + unless @prev_migration_nr + @prev_migration_nr = Time.now.utc.strftime("%Y%m%d%H%M%S").to_i + else + @prev_migration_nr += 1 + end + @prev_migration_nr.to_s + end + + def routegen + route("seems_rateable") + end + + desc "generating migration files" + def copy_migrations + migration_template "rates_migration.rb", "db/migrate/create_seems_rateable_rates.rb" + migration_template "cached_ratings_migration.rb", "db/migrate/create_seems_rateable_cached_ratings.rb" + end + + desc "generating initializer" + def copy_initializer + template "initializer.rb", "config/initializers/seems_rateable.rb" + end + + desc "generating javascript files" + def copy_javascript_asset + Dir.mkdir "app/assets/javascripts/rateable" unless File.directory?("app/assets/javascripts/rateable") + copy_file "rateable.js.erb", "app/assets/javascripts/rateable/rateable.js.erb" unless File.exists?("app/assets/javascripts/rateable/rateable.js.erb") + copy_file "jRating.js.erb", "app/assets/javascripts/rateable/jRating.js.erb" unless File.exists?("app/assets/javascripts/rateable/jRating.js.erb") + end + end + end +end diff --git a/lib/seems_rateable/lib/generators/seems_rateable/install/templates/cached_ratings_migration.rb b/lib/seems_rateable/lib/generators/seems_rateable/install/templates/cached_ratings_migration.rb new file mode 100644 index 000000000..e3e7ab2ee --- /dev/null +++ b/lib/seems_rateable/lib/generators/seems_rateable/install/templates/cached_ratings_migration.rb @@ -0,0 +1,17 @@ +class CreateSeemsRateableCachedRatings < ActiveRecord::Migration + def self.up + create_table :seems_rateable_cached_ratings do |t| + t.belongs_to :cacheable, :polymorphic => true + t.float :avg, :null => false + t.integer :cnt, :null => false + t.string :dimension + t.integer :cacheable_id, :limit => 8 + t.string :cacheable_type + t.timestamps + end + end + + def self.down + drop_table :cached_ratings + end +end diff --git a/lib/plugins/seems_rateable-master/lib/generators/seems_rateable/install/templates/initializer.rb b/lib/seems_rateable/lib/generators/seems_rateable/install/templates/initializer.rb similarity index 100% rename from lib/plugins/seems_rateable-master/lib/generators/seems_rateable/install/templates/initializer.rb rename to lib/seems_rateable/lib/generators/seems_rateable/install/templates/initializer.rb diff --git a/lib/plugins/seems_rateable-master/lib/generators/seems_rateable/install/templates/jRating.js.erb b/lib/seems_rateable/lib/generators/seems_rateable/install/templates/jRating.js.erb similarity index 95% rename from lib/plugins/seems_rateable-master/lib/generators/seems_rateable/install/templates/jRating.js.erb rename to lib/seems_rateable/lib/generators/seems_rateable/install/templates/jRating.js.erb index 4f43a4f97..b5b778889 100644 --- a/lib/plugins/seems_rateable-master/lib/generators/seems_rateable/install/templates/jRating.js.erb +++ b/lib/seems_rateable/lib/generators/seems_rateable/install/templates/jRating.js.erb @@ -12,9 +12,9 @@ $.fn.jRating = function(op) { var defaults = { /** String vars **/ - bigStarsPath : '<%= image_path "seems_rateable/stars.png" %>', // path of the icon stars.png - smallStarsPath : '<%= image_path "seems_rateable/small.png" %>', // path of the icon small.png - path : '<%= SeemsRateable::Engine.routes.url_helpers.ratings_path %>', + bigStarsPath : 'images/seems_rateable/stars.png', // path of the icon stars.png + smallStarsPath : 'images/seems_rateable/small.png', // path of the icon small.png + path : '/ratings', type : 'big', // can be set to 'small' or 'big' /** Boolean vars **/ diff --git a/lib/plugins/seems_rateable-master/lib/generators/seems_rateable/install/templates/rateable.js.erb b/lib/seems_rateable/lib/generators/seems_rateable/install/templates/rateable.js.erb similarity index 93% rename from lib/plugins/seems_rateable-master/lib/generators/seems_rateable/install/templates/rateable.js.erb rename to lib/seems_rateable/lib/generators/seems_rateable/install/templates/rateable.js.erb index da6cc3097..e926601d2 100644 --- a/lib/plugins/seems_rateable-master/lib/generators/seems_rateable/install/templates/rateable.js.erb +++ b/lib/seems_rateable/lib/generators/seems_rateable/install/templates/rateable.js.erb @@ -11,7 +11,7 @@ $(document).ready(function(){ //showRateInfo:false, //Rate info panel, set true to display //rateInfosX : 45, //In pixel - Absolute left position of the information box during mousemove. //rateInfosY : 5, //In pixel - Absolute top position of the information box during mousemove. - path : '<%= SeemsRateable::Engine.routes.url_helpers.ratings_path %>', + path : '/ratings', onSuccess : function(element, rate){ //something like -> //alert('success'); @@ -21,5 +21,5 @@ $(document).ready(function(){ $('You have already rated!').insertAfter(element) } }); - + }); diff --git a/lib/plugins/seems_rateable-master/lib/generators/seems_rateable/install/templates/rates_migration.rb b/lib/seems_rateable/lib/generators/seems_rateable/install/templates/rates_migration.rb similarity index 98% rename from lib/plugins/seems_rateable-master/lib/generators/seems_rateable/install/templates/rates_migration.rb rename to lib/seems_rateable/lib/generators/seems_rateable/install/templates/rates_migration.rb index 40303f11c..21990b0ad 100644 --- a/lib/plugins/seems_rateable-master/lib/generators/seems_rateable/install/templates/rates_migration.rb +++ b/lib/seems_rateable/lib/generators/seems_rateable/install/templates/rates_migration.rb @@ -15,4 +15,4 @@ class CreateSeemsRateableRates < ActiveRecord::Migration def self.down drop_table :rates end -end +end diff --git a/lib/plugins/seems_rateable-master/lib/seems_rateable.rb b/lib/seems_rateable/lib/seems_rateable.rb similarity index 85% rename from lib/plugins/seems_rateable-master/lib/seems_rateable.rb rename to lib/seems_rateable/lib/seems_rateable.rb index 5f84a8b8c..2939d773f 100644 --- a/lib/plugins/seems_rateable-master/lib/seems_rateable.rb +++ b/lib/seems_rateable/lib/seems_rateable.rb @@ -1,8 +1,10 @@ begin - require 'rails' + require 'rails' rescue LoadError end +require "jquery-rails" + require "seems_rateable/engine" require "seems_rateable/errors" require "seems_rateable/helpers" diff --git a/lib/seems_rateable/lib/seems_rateable/engine.rb b/lib/seems_rateable/lib/seems_rateable/engine.rb new file mode 100644 index 000000000..f32ccb929 --- /dev/null +++ b/lib/seems_rateable/lib/seems_rateable/engine.rb @@ -0,0 +1,16 @@ +module SeemsRateable + class Engine < ::Rails::Engine + isolate_namespace SeemsRateable + + config.generators do |g| + g.test_framework :rspec, :fixture => false + g.fixture_replacement :factory_girl, :dir => 'spec/factories' + end + + initializer :seems_rateable do + ActiveRecord::Base.send :include, SeemsRateable::Model + ActionView::Base.send :include, SeemsRateable::Helpers + ActionDispatch::Routing::Mapper.send :include, SeemsRateable::Routes + end + end +end diff --git a/lib/seems_rateable/lib/seems_rateable/errors.rb b/lib/seems_rateable/lib/seems_rateable/errors.rb new file mode 100644 index 000000000..9fcb0c380 --- /dev/null +++ b/lib/seems_rateable/lib/seems_rateable/errors.rb @@ -0,0 +1,21 @@ +module SeemsRateable + module Errors + class InvalidRateableObjectError < StandardError + def to_s + "Stated object is not rateable. Add 'seems_rateable' to your object's class model." + end + end + + class NoCurrentUserInstanceError < StandardError + def to_s + "User instance current_user is not available." + end + end + + class AlreadyRatedError < StandardError + def to_s + "User has already rated an object." + end + end + end +end diff --git a/lib/seems_rateable/lib/seems_rateable/helpers.rb b/lib/seems_rateable/lib/seems_rateable/helpers.rb new file mode 100644 index 000000000..3d79adf79 --- /dev/null +++ b/lib/seems_rateable/lib/seems_rateable/helpers.rb @@ -0,0 +1,27 @@ +module SeemsRateable + module Helpers + def rating_for(obj, opts={}) + raise Errors::InvalidRateableObjectError unless obj.class.respond_to?(:rateable?) + + options = { + :dimension => nil, + :static => false, + :class => 'rateable', + :id => nil + }.update(opts) + + content_tag :div, "", "data-average" => obj.average(options[:dimension]) ? obj.average(options[:dimension]).avg : 0, :id => options[:id], + :class => "#{options[:class]}#{jdisabled?(options[:static])}", + "data-id" => obj.id, "data-kls" => obj.class.name, "data-dimension" => options[:dimension] + end + + def seems_rateable_stylesheet + stylesheet_link_tag "seems_rateable/application", media: "all", "data-turbolinks-track" => true + end + + private + def jdisabled?(option) + " jDisabled" if option || !current_user + end + end +end diff --git a/lib/seems_rateable/lib/seems_rateable/model.rb b/lib/seems_rateable/lib/seems_rateable/model.rb new file mode 100644 index 000000000..b4ebbb196 --- /dev/null +++ b/lib/seems_rateable/lib/seems_rateable/model.rb @@ -0,0 +1,91 @@ +require 'active_support/concern' + +module SeemsRateable + module Model + extend ActiveSupport::Concern + + def rate(stars, user_id, dimension=nil) + if !has_rated?(user_id, dimension) + self.rates.create do |r| + r.stars = stars + r.rater_id = user_id + r.dimension = dimension + end + update_overall_average_rating(stars, dimension) + elsif has_rated?(user_id, dimension) && can_update? + update_users_rating(stars, user_id, dimension) + else + raise Errors::AlreadyRatedError + end + end + + def update_overall_average_rating(stars, dimension=nil) + r = average(dimension) + if r.nil? + self.rate_averages.create do |r| + r.avg = stars + r.dimension = dimension + r.cnt = 1 + end + else + r.avg = (r.avg * r.cnt + stars) / (r.cnt+1) + r.cnt += 1 + r.save! + r + end + end + + def update_users_rating(stars, user_id, dimension=nil) + obj = rates(dimension).where(:rater_id => user_id).first + current_record = average(dimension) + current_record.avg = (current_record.avg*current_record.cnt - obj.stars + stars) / (current_record.cnt) + current_record.save! + obj.stars = stars + obj.save! + end + + + def average(dimension=nil) + rate_averages.where(dimension: dimension).first + end + + def rates(dimension=nil) + rates_all.where(dimension: dimension) + end + + def raters(dimension=nil) + raters_all.where('seems_rateable_rates.dimension = ?', dimension) + end + + def has_rated?(user_id, dimension=nil) + record = self.rates(dimension).where(:rater_id => user_id) + record.empty? ? false : true + end + + def can_update? + self.class.can_update? + end + + module ClassMethods + def seems_rateable(opts={}) + has_many :rates_all, :as => :rateable, :class_name => SeemsRateable::Rate, :dependent => :destroy + has_many :raters_all, :through => :rates_all, :class_name => SeemsRateable::Engine.config.owner_class, :source => :rater + has_many :rate_averages, :as => :cacheable, :class_name => SeemsRateable::CachedRating, :dependent => :destroy + + self.class_variable_set(:@@permission, opts[:allow_update] ? true : false) + + def self.can_update? + self.class_variable_get(:@@permission) + end + + def self.rateable? + true + end + end + + def seems_rateable_rater + has_many :ratings_given, :class_name => SeemsRateable::Rate, :foreign_key => :rater_id + end + end + end +end diff --git a/lib/plugins/seems_rateable-master/lib/seems_rateable/routes.rb b/lib/seems_rateable/lib/seems_rateable/routes.rb similarity index 100% rename from lib/plugins/seems_rateable-master/lib/seems_rateable/routes.rb rename to lib/seems_rateable/lib/seems_rateable/routes.rb diff --git a/lib/plugins/seems_rateable-master/lib/seems_rateable/version.rb b/lib/seems_rateable/lib/seems_rateable/version.rb similarity index 54% rename from lib/plugins/seems_rateable-master/lib/seems_rateable/version.rb rename to lib/seems_rateable/lib/seems_rateable/version.rb index 180e47824..8a635c656 100644 --- a/lib/plugins/seems_rateable-master/lib/seems_rateable/version.rb +++ b/lib/seems_rateable/lib/seems_rateable/version.rb @@ -1,3 +1,3 @@ module SeemsRateable - VERSION = "1.0.9" + VERSION = "1.0.13" end diff --git a/lib/plugins/seems_rateable-master/seems_rateable.gemspec b/lib/seems_rateable/seems_rateable.gemspec similarity index 100% rename from lib/plugins/seems_rateable-master/seems_rateable.gemspec rename to lib/seems_rateable/seems_rateable.gemspec diff --git a/public/images/footer_logo/inforbus.png b/public/images/footer_logo/inforbus.png index ba1ce65f95b9342a859c2d2dfce9521fc09f90c2..f756b12d287cfbacbfe3996c69482f65c545d2fd 100644 GIT binary patch literal 56477 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 delta 6069 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 diff --git a/public/images/footer_logo/iscas.png b/public/images/footer_logo/iscas.png index f3cbac371f21ab19c19a48b88384279c390cef76..9e1be99e34231be477bc240d3372bad45fad6c6e 100644 GIT binary patch literal 53769 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 delta 4762 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 diff --git a/public/javascripts/seems_rateable/jRating.js b/public/javascripts/seems_rateable/jRating.js index 85612d066..9c4fedeb0 100644 --- a/public/javascripts/seems_rateable/jRating.js +++ b/public/javascripts/seems_rateable/jRating.js @@ -14,7 +14,7 @@ /** String vars **/ bigStarsPath : '/images/seems_rateable/stars.png', // path of the icon stars.png smallStarsPath : '/images/seems_rateable/small.png', // path of the icon small.png - path : '/ratings', + path : '/rateable/ratings', type : 'big', // can be set to 'small' or 'big' /** Boolean vars **/ diff --git a/public/javascripts/seems_rateable/rateable.js b/public/javascripts/seems_rateable/rateable.js index e926601d2..25377f3f0 100644 --- a/public/javascripts/seems_rateable/rateable.js +++ b/public/javascripts/seems_rateable/rateable.js @@ -11,7 +11,7 @@ $(document).ready(function(){ //showRateInfo:false, //Rate info panel, set true to display //rateInfosX : 45, //In pixel - Absolute left position of the information box during mousemove. //rateInfosY : 5, //In pixel - Absolute top position of the information box during mousemove. - path : '/ratings', + path : '/rateable/ratings', onSuccess : function(element, rate){ //something like -> //alert('success'); From b318166c15df004e4675c70c02a4257e77a4f673 Mon Sep 17 00:00:00 2001 From: wanglinchun Date: Wed, 23 Apr 2014 09:18:43 +0800 Subject: [PATCH 13/54] =?UTF-8?q?=E7=BB=99=E5=8F=82=E4=B8=8E=E7=AB=9E?= =?UTF-8?q?=E8=B5=9B=E7=9A=84=E5=BA=94=E7=94=A8=E9=A1=B5=E9=9D=A2=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E5=AF=BC=E8=88=AA=E6=9D=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ..._base_softapplication_top_content.html.erb | 20 ++++++++++++ app/views/layouts/base_contest.html.erb | 30 ++++++++--------- app/views/layouts/base_newcontest.html.erb | 32 +++++++++---------- app/views/softapplications/show.html.erb | 1 + 4 files changed, 52 insertions(+), 31 deletions(-) create mode 100644 app/views/layouts/_base_softapplication_top_content.html.erb diff --git a/app/views/layouts/_base_softapplication_top_content.html.erb b/app/views/layouts/_base_softapplication_top_content.html.erb new file mode 100644 index 000000000..064e84cf0 --- /dev/null +++ b/app/views/layouts/_base_softapplication_top_content.html.erb @@ -0,0 +1,20 @@ +
        +
    <%= @softapplication.name %> + <%= link_to '删除', softapplication_path(@softapplication), method: :delete, data: { confirm: '您确定要删除吗?' } if @softapplication.destroyable_by? User.current %>  + <%= link_to '编辑', edit_softapplication_path(@softapplication), method: :get if @softapplication.destroyable_by? User.current %> +
    所属类别:<%= @softapplication.app_type_name %>
    所属类别:<%= @softapplication.app_type_name %>发布时间:<%=format_time @softapplication.created_at %>所属竞赛:<%= contest ? link_to(contest.name, show_contest_contest_path(contest)) : '尚未加入竞赛'%>
    发布人员:<%= @softapplication.user.name %>
    平均评分: <%= rating_for @softapplication, :static => true, dimension: :quality, class: 'rateable div_inline' %>发布时间:<%=format_time @softapplication.created_at %>
    + + + + + + + + + + +
    创新竞赛社区<%= l(:label_user_location) %> :
    <%=link_to request.host()+"/contests", :controller=>'contests', :action=>'index' %><%=link_to l(:field_homepage), home_path %> > + <%=link_to l(:label_contest_innovate), :controller=>'contests', :action=>'index' %> > + + <% contest = @softapplication.contests.first %><%= contest ? link_to(contest.name, show_contest_contest_path(contest)) : '尚未加入竞赛'%> + + +
    +
    \ No newline at end of file diff --git a/app/views/layouts/base_contest.html.erb b/app/views/layouts/base_contest.html.erb index b4ba3dd4b..2bda701fe 100644 --- a/app/views/layouts/base_contest.html.erb +++ b/app/views/layouts/base_contest.html.erb @@ -26,23 +26,23 @@
    - - - + + + - - + +
    创新竞赛社区<%= l(:label_user_location) %> : - - 创新竞赛社区<%= l(:label_user_location) %> : + +
    <%=link_to request.host()+"/contest", :controller => 'bids', :action => 'contest' %><%=link_to l(:field_homepage), home_path %> > <%=link_to l(:label_contest_innovate), :controller => 'bids', :action => 'contest' %> > - <%= link_to @bid.name, bid_path %><%=link_to request.host()+"/contest", :controller => 'bids', :action => 'contest' %><%=link_to l(:field_homepage), home_path %> > <%=link_to l(:label_contest_innovate), :controller => 'bids', :action => 'contest' %> > + <%= link_to @bid.name, bid_path %>
    diff --git a/app/views/layouts/base_newcontest.html.erb b/app/views/layouts/base_newcontest.html.erb index ba78cefea..147df5245 100644 --- a/app/views/layouts/base_newcontest.html.erb +++ b/app/views/layouts/base_newcontest.html.erb @@ -27,24 +27,24 @@
    - - - + + + - - + +
    创新竞赛社区<%= l(:label_user_location) %> : - - 创新竞赛社区<%= l(:label_user_location) %> : + +
    <%=link_to request.host()+"/contests", :controller=>'contests', :action=>'index' %><%=link_to l(:field_homepage), home_path %> > - <%=link_to l(:label_contest_innovate), :controller=>'contests', :action=>'index' %> > - <%= link_to @contest.name, show_contest_contest_path %> - <%=link_to request.host()+"/contests", :controller=>'contests', :action=>'index' %><%=link_to l(:field_homepage), home_path %> > + <%=link_to l(:label_contest_innovate), :controller=>'contests', :action=>'index' %> > + <%= link_to @contest.name, show_contest_contest_path %> +
    diff --git a/app/views/softapplications/show.html.erb b/app/views/softapplications/show.html.erb index 51195dfcf..b39ab6c61 100644 --- a/app/views/softapplications/show.html.erb +++ b/app/views/softapplications/show.html.erb @@ -1,3 +1,4 @@ +<%=render :partial => 'layouts/base_softapplication_top_content'%> - <%=(@project.project_type == 1) ? t(:label_user_course) : t(:label_project) %>文件共享专区 @@ -216,7 +88,9 @@ div.pagination{
    <% @preTags = %w|预设A 预设B 预设C 预设D 预设E 预设Z | %> - <%= render :partial => 'tags/tag', :locals => {:obj => file, :object_flag => "6"}%> +
    <%#需要交由浏览器异步刷新,或者一次连表查询,n+1 查询问题搞不定%> + <%= render :partial => 'tags/tag', :locals => {:obj => file, :object_flag => "6"}%> +
    diff --git a/public/themes/redpenny-master/stylesheets/application.css b/public/themes/redpenny-master/stylesheets/application.css index b73123590..306d6d113 100644 --- a/public/themes/redpenny-master/stylesheets/application.css +++ b/public/themes/redpenny-master/stylesheets/application.css @@ -2247,4 +2247,130 @@ ul.messages-for-user-reply li { .footer_text_link{ margin: 0px 5px; } -/*gcm*/ \ No newline at end of file +/*gcm*/ + +#ver-zebra, .file_table_des +{ + font-family: "Lucida Sans Unicode", "Lucida Grande", Sans-Serif; + font-size: 12px; + margin: 5px 10px; + width: 98%; + text-align: left; + border-collapse: collapse; + line-height: 20px; + font-size: 14px; +} +#ver-zebra th +{ + font-size: 14px; + font-weight: normal; + padding: 12px 15px; + border-right: 1px solid #fff; + border-left: 1px solid #fff; + color: #039; + text-align: left; +} +#ver-zebra td +{ + padding: 8px 15px; + border-right: 1px solid #fff; + border-left: 1px solid #fff; + color: #669; +} +#ver-zebra td.description { + background-color: white; + padding: 0px; + margin: 0px auto; +} +div.tags_area { + padding: 2px 10px 10px 10px; + margin: 0px; + margin-bottom: 10px; + /*border-bottom: 1px dashed #CCCCCC;*/ + overflow: hidden; + position: relative; +} +.tags_gradint { +} +.read-more{ + padding: 5px; + border-top: 4px double #ddd; + background: #fff; + color: #333; +} +.read-more a{ + padding-right: 22px; + background: url() no-repeat 100% 50%; + font-weight: bold; + text-decoration: none; +} +.read-more a:hover{ + color: #000; +} +.vzebra-odd +{ + background: #eff2ff; +} +.vzebra-even +{ + background: #e8edff; +} +#ver-zebra #vzebra-adventure, #ver-zebra #vzebra-children +{ + background: #ffffff; + border-bottom: 1px solid #c8d4fd; +} +#ver-zebra #vzebra-comedy, #ver-zebra #vzebra-action +{ + background: #ffffff; + border-bottom: 1px solid #d6dfff; +} +.filename{ + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} +div.pagination{ + margin: 10px 0px; + height: 1.5em; + text-align: left; + font-size: 13px; +} +.m5p5{ + display: inline-block; + height: auto; + color: white !important; + margin: 8px; + padding: 3px 7px; +} +.m5p5:hover { + text-decoration: none; + /*padding-bottom: 3px;*/ + /*border-bottom: 1px solid #666666;*/ + border-radius: 4px; + border: 1px solid #15bccf; + box-shadow: 3px 3px 3px #666666; +} +.relation_file_div{ + margin: 0px 25px; +} +.relation_file_div fieldset{ + margin: 0px 0px; + padding: 10px; + border-radius: 5px; + transition: all 2s linear 1s; +} +.relation_file_div input#attach_search:focus{ + border: 1px solid #1B95C6; + box-shadow: 0px 0px 4px #1B95C6; + width: 200px; +} +.relation_file_div input#attach_search{ + width: 150px; + outline: none; + border-radius: 5px; + -webkit-transition: 1s width; + -moz-transition : 1s width; + -o-transition : 1s width; + transition : 1s width; +} \ No newline at end of file From 9baa07b9a3f97b30049c50df637f9869ea39ed97 Mon Sep 17 00:00:00 2001 From: wanglinchun Date: Thu, 24 Apr 2014 20:44:35 +0800 Subject: [PATCH 37/54] =?UTF-8?q?=E8=B0=83=E6=95=B4=E5=8F=82=E8=B5=9B?= =?UTF-8?q?=E5=BA=94=E7=94=A8=E9=A1=B5=E9=9D=A2=E4=B8=AD=E4=B8=A4=E5=88=97?= =?UTF-8?q?=E7=9A=84=E6=98=BE=E7=A4=BA=EF=BC=8C=E4=B8=BB=E8=A6=81=E6=98=AF?= =?UTF-8?q?=E9=98=B2=E6=AD=A2=E5=BA=94=E7=94=A8=E4=B8=8B=E8=BD=BD=E5=92=8C?= =?UTF-8?q?=E5=BC=80=E5=8F=91=E4=BA=BA=E5=91=98=E5=AD=97=E6=95=B0=E5=A4=AA?= =?UTF-8?q?=E9=95=BF=E6=98=BE=E7=A4=BA=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=8C?= =?UTF-8?q?=E4=BD=BF=E5=85=B6=E5=8F=AF=E4=BB=A5=E8=87=AA=E5=8A=A8=E6=8D=A2?= =?UTF-8?q?=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/softapplications/show.html.erb | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/app/views/softapplications/show.html.erb b/app/views/softapplications/show.html.erb index b39ab6c61..32ab3474b 100644 --- a/app/views/softapplications/show.html.erb +++ b/app/views/softapplications/show.html.erb @@ -19,31 +19,32 @@ - - + <% contest = @softapplication.contests.first %> - + - + - - + From f4595dfcd295e807c39c619afce9d2dbc253971e Mon Sep 17 00:00:00 2001 From: yanxd Date: Fri, 25 Apr 2014 08:29:20 +0800 Subject: [PATCH 38/54] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=83=A8=E5=88=86?= =?UTF-8?q?=E6=8B=8D=E6=AE=B5project=E3=80=81course=E6=96=B9=E5=BC=8F=20pr?= =?UTF-8?q?ojectlist=20=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/projects_controller.rb | 2 +- app/helpers/application_helper.rb | 15 +++------------ app/helpers/projects_helper.rb | 2 +- 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index cd74cd08f..95fbed1d3 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -128,7 +128,7 @@ class ProjectsController < ApplicationController def index #Modified by nie - @project_type = params[:project_type] + @project_type = params[:project_type].to_i per_page_option = 10 @projects_all = Project.active.visible. diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 9d18f81c9..859b19655 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -255,26 +255,17 @@ module ApplicationHelper end classes = (ancestors.empty? ? 'root' : 'child') s << "
  • " - if params[:project_type] == "0" + if project.try(:project_type) == Project::ProjectType_project s << h(block_given? ? yield(project) : project.name) else end - # if @project.project_type == 1 - # unless Course.find_by_extra(@project.identifier).nil? - # unless Course.find_by_extra(@project.identifier).tea_id == User.current.id - # s << "" - # s << join_in_course(@project, User.current)#, ['whiteButton']) - # s << "" - # end - # end - # end - if params[:project_type] == "0" + if project.try(:project_type) == Project::ProjectType_project unless User.current.member_of?(@project) s << "" s << watcher_link(@project, User.current)#, ['whiteButton']) s << "" - end + end s << (render :partial => 'projects/project', :locals => {:project => project}).to_s else s << (render :partial => 'projects/course', :locals => {:project => project}).to_s diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 44fb5d564..5bd677bdf 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -175,7 +175,7 @@ module ProjectsHelper def render_project_hierarchy(projects) render_project_nested_lists(projects) do |project| #Modified by young - if (project.project_type==1) + if (project.try(:project_type) == Project::ProjectType_course ) s = link_to_project(project, {}, :class => "#{project.css_classes} #{User.current.member_of?(project) ? 'my-project' : nil}").html_safe else s = link_to_project(project, {}, :class => "#{project.css_classes} #{User.current.member_of?(project) ? 'my-project' : nil}") From 32294cf13183321f340c6ff88c7580f6047c538f Mon Sep 17 00:00:00 2001 From: yanxd Date: Fri, 25 Apr 2014 09:03:19 +0800 Subject: [PATCH 39/54] gemfile --- Gemfile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Gemfile b/Gemfile index 0ea40e013..bfc0b773f 100644 --- a/Gemfile +++ b/Gemfile @@ -72,6 +72,10 @@ end group :development do gem "rdoc", ">= 2.4.2" + if nil + gem 'thin' + gem 'rack-mini-profiler' + end end From cc738edf2fc306b2b1ece387d22b629e42cee362 Mon Sep 17 00:00:00 2001 From: Wen Date: Thu, 24 Apr 2014 08:58:24 +0800 Subject: [PATCH 40/54] =?UTF-8?q?=E5=AD=A6=E6=A0=A1=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=E6=90=9C=E7=B4=A2=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/school_controller.rb | 11 ++++++++++ app/views/school/index.html.erb | 31 +++++++++++++++++++++++----- config/routes.rb | 3 +++ 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/app/controllers/school_controller.rb b/app/controllers/school_controller.rb index a2f6a348c..3e12ba3b3 100644 --- a/app/controllers/school_controller.rb +++ b/app/controllers/school_controller.rb @@ -31,4 +31,15 @@ class SchoolController < ApplicationController render :text => options end + + def search_school + @school = School.where("province = ? AND name LIKE '%"+params[:key_word]+"%'", params[:province]); + + options = "" + @school.each do |s| + options << "
  • #{s.name}
  • " + end + + render :text => options + end end diff --git a/app/views/school/index.html.erb b/app/views/school/index.html.erb index ad9523025..1277c0b4b 100644 --- a/app/views/school/index.html.erb +++ b/app/views/school/index.html.erb @@ -22,17 +22,38 @@ location.href = "welcome/index?course.trustie.net&school_id="+id; } +

    全部学校

    -

    - 请选择省份:<%= select_tag "province", - options_from_collection_for_select(School.find_by_sql("select distinct province from schools"), :province, :province), - :onclick => "get_school(this.value)" %> -

    +
      +
    • 请选择省份:<%= select_tag "province", + options_from_collection_for_select(School.find_by_sql("select distinct province from schools"), :province, :province), + :onclick => "get_school(this.value)" %>
    • +
    • +
    • +
    +
      diff --git a/config/routes.rb b/config/routes.rb index 50b38d337..3c4510be9 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -585,6 +585,9 @@ RedmineApp::Application.routes.draw do post 'school/get_schoollist/:province', :to => 'school#get_schoollist' get 'school/get_schoollist/:province', :to => 'school#get_schoollist' + post 'school/search_school/', :to => 'school#search_school' + get 'school/search_school/', :to => 'school#search_school' + ######added by nie match 'tags/show_projects_tags',:to => 'tags#show_projects_tags' ########### added by liuping From 02295e5ca940f1dc62898864633e019199730128 Mon Sep 17 00:00:00 2001 From: Wen Date: Fri, 25 Apr 2014 09:29:18 +0800 Subject: [PATCH 41/54] =?UTF-8?q?=E7=BB=99=E4=B8=A5=E6=80=BB=E8=B0=83?= =?UTF-8?q?=E8=AF=95=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/school_controller.rb | 6 ++ app/views/school/index.html.erb | 5 +- app/views/school/upload_logo.html.erb | 1 + app/views/welcome/course.html.erb | 59 ++++++++++++++---- config/locales/zh.yml | 2 +- .../20140424072458_add_logolink_to_schools.rb | 5 ++ db/schema.rb | 3 +- public/images/transparent.png | Bin 0 -> 2904 bytes public/stylesheets/application.css | 9 ++- 9 files changed, 72 insertions(+), 18 deletions(-) create mode 100644 app/views/school/upload_logo.html.erb create mode 100644 db/migrate/20140424072458_add_logolink_to_schools.rb create mode 100644 public/images/transparent.png diff --git a/app/controllers/school_controller.rb b/app/controllers/school_controller.rb index 3e12ba3b3..9ef935cf7 100644 --- a/app/controllers/school_controller.rb +++ b/app/controllers/school_controller.rb @@ -1,5 +1,11 @@ class SchoolController < ApplicationController + before_filter :require_admin, :only => :upload_logo + + def upload_logo + + end + def index diff --git a/app/views/school/index.html.erb b/app/views/school/index.html.erb index 1277c0b4b..b24c3a677 100644 --- a/app/views/school/index.html.erb +++ b/app/views/school/index.html.erb @@ -19,7 +19,7 @@ @@ -13,6 +13,7 @@ @@ -19,11 +21,11 @@ url :'/school/get_options/'+encodeURIComponent(value), data :'text', success: function(data){ - - $("#schoollist").html(data); - - } + }, + complete: function() { + $("#province option").attr("disabled", true); + } } @@ -117,7 +119,7 @@ <% else %> - <%= l(:field_occupation) %> *<%= select_tag "province", options_from_collection_for_select(School.find_by_sql("select distinct province from schools"), :province, :province), :onchange => "get_options(this.value)" %> + <%= l(:field_occupation) %> *<%= select_tag "province", options_from_collection_for_select(School.find_by_sql("select distinct province from schools"), :province, :province), onclick: '$("#province option").attr("disabled", false)' %> From 12c19e2bfe2554ce5a749a969ebe7fef37992824 Mon Sep 17 00:00:00 2001 From: yanxd Date: Fri, 25 Apr 2014 15:41:12 +0800 Subject: [PATCH 50/54] =?UTF-8?q?Revert=20"jquery=20=E7=82=B9=E5=87=BB?= =?UTF-8?q?=E7=9C=81=E4=BB=BD=E5=87=BA=E5=AD=A6=E6=A0=A1"=20revert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 891fa65c160652b6b47064fc738fe2e13a571cca. --- app/views/my/account.html.erb | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/app/views/my/account.html.erb b/app/views/my/account.html.erb index 6efd76e15..9bc4cb2b5 100644 --- a/app/views/my/account.html.erb +++ b/app/views/my/account.html.erb @@ -5,8 +5,6 @@ function(){ $("#province_lean").attr("href", "#WOpenWindow") $("#province_lean").leanModal({top: 100, closeButton: ".modal_close"}); - $("#province option").attr("disabled", true); - $("#province option").click(function(){get_options(this.value);}); } ); @@ -21,11 +19,11 @@ url :'/school/get_options/'+encodeURIComponent(value), data :'text', success: function(data){ + + $("#schoollist").html(data); - }, - complete: function() { - $("#province option").attr("disabled", true); - } + + } } @@ -119,7 +117,7 @@ <% else %> - <%= l(:field_occupation) %> *<%= select_tag "province", options_from_collection_for_select(School.find_by_sql("select distinct province from schools"), :province, :province), onclick: '$("#province option").attr("disabled", false)' %> + <%= l(:field_occupation) %> *<%= select_tag "province", options_from_collection_for_select(School.find_by_sql("select distinct province from schools"), :province, :province), :onchange => "get_options(this.value)" %> From 230b377cad7af24cee323745b292efdedb353e35 Mon Sep 17 00:00:00 2001 From: yanxd Date: Fri, 25 Apr 2014 15:41:40 +0800 Subject: [PATCH 51/54] oRevert "leanmodal" oik This reverts commit edce128e6b4f0cd0265a63bb1a60db38699f3428. --- app/views/my/account.html.erb | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/app/views/my/account.html.erb b/app/views/my/account.html.erb index 9bc4cb2b5..bec07145b 100644 --- a/app/views/my/account.html.erb +++ b/app/views/my/account.html.erb @@ -3,8 +3,8 @@ @@ -13,7 +13,6 @@
    <%= @softapplication.name %> + <%= link_to '删除', softapplication_path(@softapplication), method: :delete, data: { confirm: '您确定要删除吗?' } if @softapplication.destroyable_by? User.current %>  <%= link_to '编辑', edit_softapplication_path(@softapplication), method: :get if @softapplication.destroyable_by? User.current %>
    所属类别:<%= @softapplication.app_type_name %>所属类别:<%= @softapplication.app_type_name %>所属竞赛:<%= contest ? link_to(contest.name, show_contest_contest_path(contest)) : '尚未加入竞赛'%>所属竞赛:<%= contest ? link_to(contest.name, show_contest_contest_path(contest)) : '尚未加入竞赛'%>
    发布人员:<%= @softapplication.user.name %>发布人员:<%= @softapplication.user.name %> 系统支持:<%= @softapplication.android_min_version_available %>
    + 应用下载: - <% options = {:author => true, :deletable => @softapplication.user.eql?(User.current) } %> - <%= render :partial => 'attachments/app_link', :locals => {:attachments => @app_items, :options => options} %> + + <% options = {:author => true, :deletable => @softapplication.user.eql?(User.current) } %><%= render :partial => 'attachments/app_link', :locals => {:attachments => @app_items, :options => options} %> + 开发人员:<%= @softapplication.application_developers %>
    平均评分: <%= rating_for @softapplication, :static => true, dimension: :quality, class: 'rateable div_inline' %>平均评分: <%= rating_for @softapplication, :static => true, dimension: :quality, class: 'rateable div_inline' %> 发布时间:<%=format_time @softapplication.created_at %>