From 48cb0e0450334f23d629e59b1ba0c54d639e19a6 Mon Sep 17 00:00:00 2001 From: alan <547533434@qq.com> Date: Sat, 31 Jan 2015 15:04:48 +0800 Subject: [PATCH 01/97] email verify --- Gemfile | 2 +- Gemfile.lock | 9 +++++++++ app/models/user.rb | 2 +- config/application.rb | 6 +++--- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index 037c606c8..f59c92077 100644 --- a/Gemfile +++ b/Gemfile @@ -20,7 +20,7 @@ gem "builder", "3.0.0" gem 'acts-as-taggable-on', '2.4.1' gem 'spreadsheet' gem 'ruby-ole' -#gem 'email_verifier', path: 'lib/email_verifier' +gem 'email_verifier', path: 'lib/email_verifier' group :development do gem 'grape-swagger' diff --git a/Gemfile.lock b/Gemfile.lock index 355ca422d..8c5816e13 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -12,6 +12,13 @@ PATH coderay (>= 1.0.0) erubis (>= 2.6.6) +PATH + remote: lib/email_verifier + specs: + email_verifier (0.0.7) + dnsruby (>= 1.5) + rails (>= 3.0.0) + PATH remote: lib/rack-mini-profiler specs: @@ -91,6 +98,7 @@ GEM descendants_tracker (0.0.4) thread_safe (~> 0.3, >= 0.3.1) diff-lcs (1.2.5) + dnsruby (1.57.0) equalizer (0.0.9) erubis (2.7.0) execjs (2.2.1) @@ -315,6 +323,7 @@ DEPENDENCIES capybara (~> 2.4.1) coderay (~> 1.0.6) coffee-rails (~> 3.2.1) + email_verifier! factory_girl (~> 4.4.0) faker fastercsv (~> 1.5.0) diff --git a/app/models/user.rb b/app/models/user.rb index 06f59c764..bef65fe54 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -188,7 +188,7 @@ class User < Principal validates_confirmation_of :password, :allow_nil => true validates_inclusion_of :mail_notification, :in => MAIL_NOTIFICATION_OPTIONS.collect(&:first), :allow_blank => true validate :validate_password_length - #validates_email_realness_of :mail + validates_email_realness_of :mail before_create :set_mail_notification before_save :update_hashed_password before_destroy :remove_references_before_destroy diff --git a/config/application.rb b/config/application.rb index c7f2f3ea5..647675784 100644 --- a/config/application.rb +++ b/config/application.rb @@ -17,9 +17,9 @@ module RedmineApp # -- all .rb files in that directory are automatically loaded. #verifier if email is real - # EmailVerifier.config do |config| - # config.verifier_email = "lizanle521@126.com" - # end + EmailVerifier.config do |config| + config.verifier_email = "alanlong9278@126.com" + end config.generators do |g| g.test_framework :rspec, From d61199f66b4182d0b7c8f476cab5270408ee210d Mon Sep 17 00:00:00 2001 From: alan <547533434@qq.com> Date: Sat, 31 Jan 2015 16:43:10 +0800 Subject: [PATCH 02/97] merge szzh --- Gemfile.lock | 4 ---- lib/email_verifier | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 8c5816e13..b26f17113 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -170,8 +170,6 @@ GEM metaclass (~> 0.0.1) multi_json (1.10.1) multi_xml (0.5.5) - mysql2 (0.3.11) - mysql2 (0.3.11-x86-mingw32) nenv (0.2.0) net-ldap (0.3.1) nokogiri (1.6.3) @@ -316,7 +314,6 @@ PLATFORMS DEPENDENCIES activerecord-jdbc-adapter (= 1.2.5) - activerecord-jdbcmysql-adapter acts-as-taggable-on (= 2.4.1) better_errors! builder (= 3.0.0) @@ -337,7 +334,6 @@ DEPENDENCIES jquery-rails (~> 2.0.2) kaminari mocha (~> 1.1.0) - mysql2 (= 0.3.11) net-ldap (~> 0.3.1) nokogiri (~> 1.6.3) paperclip (~> 3.5.4) diff --git a/lib/email_verifier b/lib/email_verifier index 3cabcc643..222a9bdd7 160000 --- a/lib/email_verifier +++ b/lib/email_verifier @@ -1 +1 @@ -Subproject commit 3cabcc643f36939939685e6f55273dfbf89da545 +Subproject commit 222a9bdd72014f197baf2131ab71cc41660111ed From 7391f3b5cffac583ffdd43ce94ef7d1eb23cbc12 Mon Sep 17 00:00:00 2001 From: alan <547533434@qq.com> Date: Mon, 2 Feb 2015 09:52:05 +0800 Subject: [PATCH 03/97] Merge branch 'szzh' of http://xianbo_trustie2@repository.trustie.net/xianbo/trustie2.git into szzh Conflicts: config/locales/zh.yml Signed-off-by: alan <547533434@qq.com> --- config/database.yml.example | 52 ------------------------------------- 1 file changed, 52 deletions(-) delete mode 100644 config/database.yml.example diff --git a/config/database.yml.example b/config/database.yml.example deleted file mode 100644 index 2ff6231d4..000000000 --- a/config/database.yml.example +++ /dev/null @@ -1,52 +0,0 @@ -# Default setup is given for MySQL with ruby1.9. If you're running Redmine -# with MySQL and ruby1.8, replace the adapter name with `mysql`. -# Examples for PostgreSQL, SQLite3 and SQL Server can be found at the end. -# Line indentation must be 2 spaces (no tabs). - -production: - adapter: mysql2 - database: redmine - host: localhost - username: root - password: "" - encoding: utf8 - -development: - adapter: mysql2 - database: redmine_development - host: 10.107.17.20 - username: root - password: "1234" - encoding: utf8 - -# Warning: The database defined as "test" will be erased and -# re-generated from your development database when you run "rake". -# Do not set this db to the same as development or production. -test: - adapter: mysql2 - database: redmine_test - host: 10.107.17.20 - username: root - password: "1234" - encoding: utf8 - -# PostgreSQL configuration example -#production: -# adapter: postgresql -# database: redmine -# host: localhost -# username: postgres -# password: "postgres" - -# SQLite3 configuration example -#production: -# adapter: sqlite3 -# database: db/redmine.sqlite3 - -# SQL Server configuration example -#production: -# adapter: sqlserver -# database: redmine -# host: localhost -# username: jenkins -# password: jenkins From 725b2749e2b14bf4484a39b376e2a251d38c58dc Mon Sep 17 00:00:00 2001 From: lizanle <491823689@qq.com> Date: Mon, 2 Feb 2015 09:52:50 +0800 Subject: [PATCH 04/97] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=B8=80=E4=BA=9B?= =?UTF-8?q?=E5=AF=B9=E4=BB=A3=E7=A0=81=E7=90=86=E8=A7=A3=E7=9A=84=E6=B3=A8?= =?UTF-8?q?=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/acts_as_activity_provider.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/plugins/acts_as_activity_provider/lib/acts_as_activity_provider.rb b/lib/plugins/acts_as_activity_provider/lib/acts_as_activity_provider.rb index 35d168732..5a54187b3 100644 --- a/lib/plugins/acts_as_activity_provider/lib/acts_as_activity_provider.rb +++ b/lib/plugins/acts_as_activity_provider/lib/acts_as_activity_provider.rb @@ -24,6 +24,10 @@ module Redmine module ClassMethods def acts_as_activity_provider(options = {}) + # Time 2015-01-31 13:54:34 + # Author lizanle + # Description mod.included_modules -> array + # 返回mod包含的 modules数组 unless self.included_modules.include?(Redmine::Acts::ActivityProvider::InstanceMethods) cattr_accessor :activity_provider_options send :include, Redmine::Acts::ActivityProvider::InstanceMethods From 8f5e613477b50080d0d3249c2efeb1d3e17629fe Mon Sep 17 00:00:00 2001 From: lizanle <491823689@qq.com> Date: Mon, 2 Feb 2015 09:53:14 +0800 Subject: [PATCH 05/97] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=B8=80=E4=BA=9B?= =?UTF-8?q?=E5=AF=B9=E4=BB=A3=E7=A0=81=E7=90=86=E8=A7=A3=E7=9A=84=E6=B3=A8?= =?UTF-8?q?=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/issue.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/models/issue.rb b/app/models/issue.rb index a7b1a5943..78d20dca1 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -64,7 +64,9 @@ class Issue < ActiveRecord::Base }, :url => Proc.new {|o| {:controller => 'issues', :action => 'show', :id => o}}, :type => Proc.new {|o| 'issue' + (o.closed? ? ' closed' : '') } - + # Time 2015-01-31 13:52:53 + # Author lizanle + # Description 将hash传进去 acts_as_activity_provider :find_options => {:include => [:project, :author, :tracker]}, :author_key => :author_id From aa2590d4519d3924dea381da112b266f166e7403 Mon Sep 17 00:00:00 2001 From: alan <547533434@qq.com> Date: Tue, 3 Feb 2015 10:16:46 +0800 Subject: [PATCH 06/97] Signed-off-by: alan <547533434@qq.com> --- app/models/forum.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/forum.rb b/app/models/forum.rb index e47d18b02..f5581b232 100644 --- a/app/models/forum.rb +++ b/app/models/forum.rb @@ -5,7 +5,7 @@ class Forum < ActiveRecord::Base has_many :memos, :dependent => :destroy, conditions: "parent_id IS NULL" belongs_to :creator, :class_name => "User", :foreign_key => 'creator_id' - after_create :expire_forum_cache + after_create :expire_forum_cache, :send_email after_update :expire_forum_cache before_destroy :expire_forum_cache safe_attributes 'name', @@ -23,7 +23,7 @@ class Forum < ActiveRecord::Base acts_as_taggable scope :by_join_date, order("created_at DESC") - after_create :send_email + #after_create :send_email def reset_counters! self.class.reset_counters!(id) end From d902d76ae21d7bc53bca83ef9cabecb29e0a91ae Mon Sep 17 00:00:00 2001 From: lizanle <491823689@qq.com> Date: Fri, 6 Feb 2015 10:15:18 +0800 Subject: [PATCH 07/97] =?UTF-8?q?=E5=B0=86google=E7=BB=9F=E8=AE=A1?= =?UTF-8?q?=E6=8D=A2=E4=B8=BA=E4=BA=86=E7=99=BE=E5=BA=A6=E7=BB=9F=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/layouts/_base_footer.html.erb | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/app/views/layouts/_base_footer.html.erb b/app/views/layouts/_base_footer.html.erb index 4716ed25a..0c7cca7d5 100644 --- a/app/views/layouts/_base_footer.html.erb +++ b/app/views/layouts/_base_footer.html.erb @@ -40,18 +40,15 @@
<%= debug(params) if Rails.env.development? %> - + +
From 859889b750f659daf2ee248e03e4cec25e71c56e Mon Sep 17 00:00:00 2001 From: sw <939547590@qq.com> Date: Fri, 6 Feb 2015 11:27:37 +0800 Subject: [PATCH 08/97] =?UTF-8?q?=E7=AE=80=E5=8C=96=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E5=8C=BF=E8=AF=84=E6=95=B0=E9=87=8F=E7=9A=84=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/helpers/homework_attach_helper.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/helpers/homework_attach_helper.rb b/app/helpers/homework_attach_helper.rb index 0b98283ff..72d381b28 100644 --- a/app/helpers/homework_attach_helper.rb +++ b/app/helpers/homework_attach_helper.rb @@ -140,8 +140,6 @@ module HomeworkAttachHelper ####################################################### def get_student_not_batch_homework_list bid,user HomeworkAttach.find_by_sql("SELECT * FROM(SELECT homework_attaches.*, - (SELECT AVG(stars) FROM seems_rateable_rates WHERE rateable_type = 'HomeworkAttach' AND rateable_id = homework_attaches.id AND is_teacher_score = 1) AS t_score, - (SELECT AVG(stars) FROM seems_rateable_rates WHERE rateable_type = 'HomeworkAttach' AND rateable_id = homework_attaches.id AND is_teacher_score = 0) AS s_score, (SELECT stars FROM seems_rateable_rates WHERE rateable_type = 'HomeworkAttach' AND rateable_id = homework_attaches.id AND rater_id = #{user.id} AND is_teacher_score = 0) AS m_score FROM homework_attaches INNER JOIN homework_evaluations ON homework_evaluations.homework_attach_id = homework_attaches.id From 6f9e2bad63584cdf8301bc32e507aea330632c9f Mon Sep 17 00:00:00 2001 From: alan <547533434@qq.com> Date: Fri, 6 Feb 2015 18:15:08 +0800 Subject: [PATCH 09/97] mail weekly --- Gemfile | 2 +- Gemfile.lock | 3 + app/controllers/courses_controller.rb | 1 + app/controllers/messages_controller.rb | 1 + app/controllers/news_controller.rb | 1 + app/controllers/projects_controller.rb | 2 +- app/models/journals_for_message.rb | 4 +- app/models/mailer.rb | 75 +++- app/models/user.rb | 4 +- .../mailer/send_for_user_activities.html.erb | 337 ++++++++++++++++++ .../mailer/send_for_user_activities.text.erb | 253 +++++++++++++ config/initializers/send_mail.rb | 23 ++ config/locales/zh.yml | 20 +- 13 files changed, 718 insertions(+), 8 deletions(-) create mode 100644 app/views/mailer/send_for_user_activities.html.erb create mode 100644 app/views/mailer/send_for_user_activities.text.erb create mode 100644 config/initializers/send_mail.rb diff --git a/Gemfile b/Gemfile index 037c606c8..1bc9e6629 100644 --- a/Gemfile +++ b/Gemfile @@ -21,7 +21,7 @@ gem 'acts-as-taggable-on', '2.4.1' gem 'spreadsheet' gem 'ruby-ole' #gem 'email_verifier', path: 'lib/email_verifier' - +gem 'rufus-scheduler' group :development do gem 'grape-swagger' gem 'grape-swagger-ui', git: 'https://github.com/guange2015/grape-swagger-ui.git' diff --git a/Gemfile.lock b/Gemfile.lock index 355ca422d..861c49754 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -252,6 +252,8 @@ GEM ruby-ole (1.2.11.7) ruby-openid (2.1.8) rubyzip (1.1.6) + rufus-scheduler (3.0.8) + tzinfo sass (3.3.10) sass-rails (3.2.6) railties (~> 3.2.0) @@ -339,6 +341,7 @@ DEPENDENCIES rspec-rails (= 2.13.1) ruby-ole ruby-openid (~> 2.1.4) + rufus-scheduler sass-rails (~> 3.2.3) seems_rateable! selenium-webdriver (~> 2.42.0) diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb index 61944ca2c..a55abd123 100644 --- a/app/controllers/courses_controller.rb +++ b/app/controllers/courses_controller.rb @@ -5,6 +5,7 @@ class CoursesController < ApplicationController helper :members helper :words + before_filter :authorize1, :only => [:show, :feedback] menu_item :overview menu_item :feedback, :only => :feedback menu_item :homework, :only => :homework diff --git a/app/controllers/messages_controller.rb b/app/controllers/messages_controller.rb index 8d6943f02..d2a253c2a 100644 --- a/app/controllers/messages_controller.rb +++ b/app/controllers/messages_controller.rb @@ -17,6 +17,7 @@ class MessagesController < ApplicationController include ApplicationHelper + before_filter :authorize1, :only => [:show] menu_item :boards default_search_scope :messages before_filter :find_board, :only => [:new, :preview,:edit] diff --git a/app/controllers/news_controller.rb b/app/controllers/news_controller.rb index 2df17d73f..b44e8a348 100644 --- a/app/controllers/news_controller.rb +++ b/app/controllers/news_controller.rb @@ -17,6 +17,7 @@ class NewsController < ApplicationController layout 'base_projects'# by young + before_filter :authorize1, :only => [:show] default_search_scope :news model_object News before_filter :find_model_object, :except => [:new, :create, :index] diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 02bfc9e19..5054fd5c1 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -19,7 +19,7 @@ # Description 封装代码,简化代码,格式化代码, class ProjectsController < ApplicationController layout :select_project_layout - + before_filter :authorize1, :only => [:show] menu_item :overview, :only => :show menu_item :roadmap, :only => :roadmap menu_item :settings, :only => :settings diff --git a/app/models/journals_for_message.rb b/app/models/journals_for_message.rb index c71fbaf47..39618e43b 100644 --- a/app/models/journals_for_message.rb +++ b/app/models/journals_for_message.rb @@ -22,8 +22,8 @@ class JournalsForMessage < ActiveRecord::Base :foreign_key => 'jour_id', :conditions => "#{self.table_name}.jour_type = 'Project' " belongs_to :course, - :foreign_key => 'jour_id', - :conditions => "#{self.table_name}.jour_type = 'Course' " + :foreign_key => 'jour_id' + belongs_to :jour, :polymorphic => true belongs_to :user diff --git a/app/models/mailer.rb b/app/models/mailer.rb index 2cae982a7..85ce46e8b 100644 --- a/app/models/mailer.rb +++ b/app/models/mailer.rb @@ -27,6 +27,80 @@ class Mailer < ActionMailer::Base { :host => Setting.host_name, :protocol => Setting.protocol } end + # author: alan + # 根据用户选择发送个人日报或周报 + # 发送内容: 项目【缺陷,讨论区,新闻】,课程【通知,留言,新闻】, 贴吧, 个人留言 + def send_for_user_activities(user, date_to, days) + date_from = date_to - days.days + + # 生成token用于直接点击登录 + token = Token.new(:user =>user , :action => 'autologin') + token.save + @token = token + + @user_url = url_for(my_account_url(user,:token => @token.value)) + # 查询user参加的项目及课程 + projects = user.projects + courses = user.courses + project_ids = projects.map{|project| project.id}.join(",") + course_ids = courses.map {|course| course.id}.join(",") + + # 查询user的缺陷,包括发布的,跟踪的以及被指派的缺陷 + @issues = Issue.find_by_sql("select DISTINCT i.* from issues i, watchers w + where (i.assigned_to_id = #{user.id} or i.author_id = #{user.id} + or (w.watchable_type = 'Issue' and w.watchable_id = i.id and w.user_id = #{user.id})) + and (i.created_on between #{date_from} and #{date_to}) order by i.created_on desc") + + # 查询课程作业,包括老师发布的作业,以及user提交作业 + @bids ||= [] # 老师发布的作业 + courses.each do |course| + @bids << course.homeworks.where("created_at between #{date_from} and #{date_to} order by i.created_on desc") + end + # user 提交的作业 + @homeworks = HomeworkAttach.where("user_id=#{user.id} and (created_at between #{date_from} and #{date_to})") + + # 查询user在课程。项目中发布的讨论帖子 + messages = Message.find_by_sql("select DISTINCT * from messages where author_id = #{user.id} and (created_on between #{date_from} and #{date_to}) order by i.created_on desc") + @course_messages ||= [] + @project_messages ||= [] + messages.each do |msg| + if msg.project + @project_messages << msg + elsif msg.course + @course_messages << msg + end + end + + # 查询user在课程中发布的通知,项目中发的新闻 + @course_news = News.find_by_sql("select DISTINCT n.* from news n + where n.course_id in (#{course_ids}) + and (created_on between #{date_from} and #{date_to}) order by i.created_on desc") + @project_news = News.find_by_sql("select DISTINCT n.* from news n where n.project_id in (#{project_ids}) + and (created_on between #{date_from} and #{date_to}) order by i.created_on desc") + + # 查询user在课程及个人中留言 + @course_journal_messages = JournalsForMessage.find_by_sql("select DISTINCT * from journals_for_messages where + jour_type='Course' and user_id = #{user.id} + and (created_on between #{date_from} and #{date_to}) order by i.created_on desc") + @user_journal_messages = user.journals_for_messages.where("m_parent_id IS NULL and (created_on between #{date_from} and #{date_to})").order('created_on DESC') + + # 查询课程课件更新 + @attachments ||= [] + courses.each do |course| + @attachments << course.attachments.where("created_on between #{date_from} and #{date_to}").order('created_at DESC') + end + # 查询user新建贴吧或发布帖子 + @forums = Forum.find_by_sql("select DISTINCT * from forums where creator_id = #{user.id} and (created_at between #{date_from} and #{date_to}) order by i.created_on desc") + @memos = Memo.find_by_sql("select DISTINCT m.* from memos m, forums f where (m.author_id = #{user.id} or (m.forum_id = f.id and f.creator_id = #{user.id})) + and (created_at between #{date_from} and #{date_to}) order by i.created_on desc") + if days == 1 + subject = "[ #{user.show_name} : #{date_from} - #{l(:label_day_mail)}]" + else + subject = "[ #{user.show_name} : #{l(:label_week_mail)}]" + end + mail :to => user.mail,:subject => "[ #{user.show_name} : #{l(:notice_successful_create)}]" + + end # 贴吧新建贴吧发送邮件 # example Mailer.forum(forum).deliver def forum_add(forum) @@ -140,7 +214,6 @@ class Mailer < ActionMailer::Base @author = issue.author @issue = issue user = User.find_by_mail(recipients) - token = Token.new(:user =>user , :action => 'autologin') token.save @token = token diff --git a/app/models/user.rb b/app/models/user.rb index 06f59c764..dd06db838 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -24,7 +24,7 @@ class User < Principal DEVELOPER = 3 include Redmine::SafeAttributes - + seems_rateable_rater # Different ways of displaying/sorting users USER_FORMATS = { :firstname_lastname => { @@ -149,7 +149,7 @@ class User < Principal scope :by_join_date, order("created_on DESC") ############################# added by liuping 关注 acts_as_watchable - seems_rateable_rater + has_one :user_extensions,:dependent => :destroy ## end diff --git a/app/views/mailer/send_for_user_activities.html.erb b/app/views/mailer/send_for_user_activities.html.erb new file mode 100644 index 000000000..22b071a1f --- /dev/null +++ b/app/views/mailer/send_for_user_activities.html.erb @@ -0,0 +1,337 @@ + + + + + +
+
+

<%= l(:label_course_overview)%>

+ <% unless @course_news.first.nil? %> + + <% end %> + <% if !@bids.first.nil? || !@homeworks.first.nil? %> + + <% end %> + + <% unless @course_journal_messages.first.nil? %> + + <% end %> + + <% unless @course_messages.first.nil? %> + + <% end %> + + <% unless @attachments.first.nil? %> + + <% end %> +
+ + +
+

<%= l(:label_project_overview)%>

+ <% unless @issues.first.nil? %> + + <% end %> + + <% unless @project_messages.first.nil? %> + + <% end %> + + + +
+ +
+

<%= l(:label_activities) %>

+ <% unless @user_journal_messages.first.nil? %> + + <% end %> +
+
+ <%= link_to l(:mail_footer), @user_url, :style => "margin-top:20px;color:#2775d2; margin-left:10px;" %> +
+ + +
+ diff --git a/app/views/mailer/send_for_user_activities.text.erb b/app/views/mailer/send_for_user_activities.text.erb new file mode 100644 index 000000000..03ea31ec3 --- /dev/null +++ b/app/views/mailer/send_for_user_activities.text.erb @@ -0,0 +1,253 @@ +<%= l(:label_course_overview)%> + <% unless @course_news.first.nil? %> + <%= l(:label_course_news) %> + (<%= @course_news.count %>) + + + <% @course_news.each do |course_new|%> + + ▪ + [ + + <%= link_to course_new.course.name, [:controller => 'courses', :action => 'show', :id => course_new.course_id, :token => @token.value], + :class=> "wmail_column", + :style=> "width:90px; font-weight: bold; display:block; float:left; color:#1b55a7;overflow:hidden; white-space: nowrap; text-overflow:ellipsis;" %> + ] + + <%= link_to course_new.author, user_activities_url(course_new.author,:token => @token.value), :class => "wmail_name", + :style => "color:#fe5722; float:left;display:block; margin-right:5px; margin-left:5px; width:50px; overflow:hidden; white-space: nowrap; text-overflow:ellipsis;"%> + <%= l(:label_project_notice) %> + + <%= link_to course_new.title, [:controller => 'news', :action => 'show', :id => course_new.id,:token => @token.value], + :class => 'wmail_info', + :style => "color:#5a5a5a; float:left; width:400px; margin-right:5px; display:block;color:#1b55a7;overflow:hidden; white-space: nowrap; text-overflow:ellipsis;" + %> <%= course_new.created_on %> + + <% end %> + + <% end %> + <% if !@bids.first.nil? || !@homeworks.first.nil? %> + <%= l(:label_homework_overview) %><%= @bids.count %> + <% unless @bids.first.nil?%> + <% @bids.each do |bid| %> + ▪ + [ + + <%= link_to bid.courses.first.name, [:controller => 'courses', :action => 'show', :id => bid.courses.first.id, :token => @token.value], + :class=> "wmail_column", + :style=> "width:90px; font-weight: bold; display:block; float:left; color:#1b55a7;overflow:hidden; white-space: nowrap; text-overflow:ellipsis;" %> + ] + + <%= link_to bid.author, user_activities_url(bid.author,:token => @token.value), :class => "wmail_name", + :style => "color:#fe5722; float:left;display:block; margin-right:5px; margin-left:5px; width:50px; overflow:hidden; white-space: nowrap; text-overflow:ellipsis;"%> + <%= l(:label_course_homework) %> + + <%= link_to bid.name, course_for_bid(:id => bid.id,:token => @token.value), + :class => 'wmail_info', + :style => "color:#5a5a5a; float:left; width:400px; margin-right:5px; display:block;color:#1b55a7;overflow:hidden; white-space: nowrap; text-overflow:ellipsis;" + %> + <%= bid.created_on %> + + <% end %> + <% end %> + <% unless @homeworks.first.nil? %> + <% @homeworks.each do |homework| %> + ▪[ + + <%= link_to homework.bid.courses.first.name, [:controller => 'courses', :action => 'show', :id => homework.bid.courses.first.id, :token => @token.value], + :class=> "wmail_column", + :style=> "width:90px; font-weight: bold; display:block; float:left; color:#1b55a7;overflow:hidden; white-space: nowrap; text-overflow:ellipsis;" %> + ] + + <%= link_to homework.user, user_activities_url(homework.user,:token => @token.value), :class => "wmail_name", + :style => "color:#fe5722; float:left;display:block; margin-right:5px; margin-left:5px; width:50px; overflow:hidden; white-space: nowrap; text-overflow:ellipsis;"%> + <%= l(:label_course_submit_homework) %> + + <%= link_to homework.name, course_for_bid(:id => homework.bid.id,:token => @token.value), + :class => 'wmail_info', + :style => "color:#5a5a5a; float:left; width:400px; margin-right:5px; display:block;color:#1b55a7;overflow:hidden; white-space: nowrap; text-overflow:ellipsis;" + %> + <%= homework.created_on %> + <% end %> + <% end %> + + + + <% end %> + + <% unless @course_journal_messages.first.nil? %> + + <%= l(:view_course_journals_for_messages) %> (<%= @course_journal_messages.count %>) + + + <% @course_journal_messages.each do |course_journal_message|%> + + [ + + <%= link_to course_journal_message.course.name, [:controller => 'courses', :action => 'show', :id => course_journal_message.jour_id, :token => @token.value], + :class=> "wmail_column", + :style=> "width:90px; font-weight: bold; display:block; float:left; color:#1b55a7;overflow:hidden; white-space: nowrap; text-overflow:ellipsis;" %> + ] + + <%= link_to course_journal_message.user, user_activities_url(course_journal_message.user,:token => @token.value), :class => "wmail_name", + :style => "color:#fe5722; float:left;display:block; margin-right:5px; margin-left:5px; width:50px; overflow:hidden; white-space: nowrap; text-overflow:ellipsis;"%> + <%= l(:label_send_course_journals_for_messages) %> + + <%= link_to course_journal_message.notes, [:controller => 'courses', :action => 'feedback', :id => course_journal_message.jour_id,:token => @token.value], + :class => 'wmail_info', + :style => "color:#5a5a5a; float:left; width:400px; margin-right:5px; display:block;color:#1b55a7;overflow:hidden; white-space: nowrap; text-overflow:ellipsis;" + %> + <%= course_journal_message.created_on %> + + <% end %> + + + <% end %> + + <% unless @course_messages.first.nil? %> + + <%= l(:view_borad_course) %> + (<%= @course_journal_messages.count %>) + + + <% @course_messages.each do |course_message|%> + + ▪ + [ + + <%= link_to course_message.course.name, [:controller => 'courses', :action => 'show', :id => course_message.course.id, :token => @token.value], + :class=> "wmail_column", + :style=> "width:90px; font-weight: bold; display:block; float:left; color:#1b55a7;overflow:hidden; white-space: nowrap; text-overflow:ellipsis;" %> + ] + + <%= link_to course_message.author, user_activities_url(course_message.author,:token => @token.value), :class => "wmail_name", + :style => "color:#fe5722; float:left;display:block; margin-right:5px; margin-left:5px; width:50px; overflow:hidden; white-space: nowrap; text-overflow:ellipsis;"%> + <%= l(:label_send_course_messages) %> + + <%= link_to course_message.subject,url_for(course_message.event_url(:token => @token.value)), + :class => 'wmail_info', + :style => "color:#5a5a5a; float:left; width:400px; margin-right:5px; display:block;color:#1b55a7;overflow:hidden; white-space: nowrap; text-overflow:ellipsis;" + %> + <%= course_message.created_on %> + + <% end %> + + + <% end %> + + <% unless @attachments.first.nil? %> + + <%= l(:label_course_attendingcontestwork_download) %> + (<%= @attachments.count %>) + + + <% @attachments.each do |attachment|%> + ▪[ + + <%= link_to attachment.course.name, [:controller => 'courses', :action => 'show', :id => attachment.course.id, :token => @token.value], + :class=> "wmail_column", + :style=> "width:90px; font-weight: bold; display:block; float:left; color:#1b55a7;overflow:hidden; white-space: nowrap; text-overflow:ellipsis;" %> + ] + + <%= link_to attachment.author, user_activities_url(attachment.author,:token => @token.value), :class => "wmail_name", + :style => "color:#fe5722; float:left;display:block; margin-right:5px; margin-left:5px; width:50px; overflow:hidden; white-space: nowrap; text-overflow:ellipsis;"%> + <%= l(:label_course_file_upload) %> + + <%= link_to attachment.filename,course_files_path(@course,:token => @token.value), + :class => 'wmail_info', + :style => "color:#5a5a5a; float:left; width:400px; margin-right:5px; display:block;color:#1b55a7;overflow:hidden; white-space: nowrap; text-overflow:ellipsis;" + %> + <%= course_message.created_on %> + + <% end %> + + + <% end %> + + + +<%= l(:label_project_overview)%> + <% unless @issues.first.nil? %> + + <%= l(:label_issue_tracking) %> + (<%= @issues.count %>) + + <% @issues.each do |issue|%> + ▪ + [ + + <%= link_to issue.project.name, [:controller => 'projects', :action => 'show', :id => issue.project.id, :token => @token.value], + :class=> "wmail_column", + :style=> "width:90px; font-weight: bold; display:block; float:left; color:#1b55a7;overflow:hidden; white-space: nowrap; text-overflow:ellipsis;" %> + ] + + <%= link_to issue.author, user_activities_url(issue.author,:token => @token.value), :class => "wmail_name", + :style => "color:#fe5722; float:left;display:block; margin-right:5px; margin-left:5px; width:50px; overflow:hidden; white-space: nowrap; text-overflow:ellipsis;"%> + <%= l(:label_project_issue) %> + + <%= link_to issue.subject,url_for(:controller => 'issues', :action => 'show', :id => issue.id, :token => @token.value), + :class => 'wmail_info', + :style => "color:#5a5a5a; float:left; width:400px; margin-right:5px; display:block;color:#1b55a7;overflow:hidden; white-space: nowrap; text-overflow:ellipsis;" + %> + <%= issue.created_on %> + <% end %> + + + <% end %> + + <% unless @project_messages.first.nil? %> + + <%= l(:project_moule_boards_show) %> + (<%= @course_journal_messages.count %>) + + <% @project_messages.each do |project_message|%> + ▪[ + + <%= link_to project_message.project.name, [:controller => 'projects', :action => 'show', :id => project_message.project.id, :token => @token.value], + :class=> "wmail_column", + :style=> "width:90px; font-weight: bold; display:block; float:left; color:#1b55a7;overflow:hidden; white-space: nowrap; text-overflow:ellipsis;" %> + ] + + <%= link_to project_message.author, user_activities_url(project_message.author,:token => @token.value), :class => "wmail_name", + :style => "color:#fe5722; float:left;display:block; margin-right:5px; margin-left:5px; width:50px; overflow:hidden; white-space: nowrap; text-overflow:ellipsis;"%> + <%= l(:label_send_course_messages) %> + + <%= link_to project_message.subject,url_for(project_message.event_url(:token => @token.value)), + :class => 'wmail_info', + :style => "color:#5a5a5a; float:left; width:400px; margin-right:5px; display:block;color:#1b55a7;overflow:hidden; white-space: nowrap; text-overflow:ellipsis;" + %> + <%= project_message.created_on %> + <% end %> + + + <% end %> + + + +<%= l(:label_activities) %> + <% unless @user_journal_messages.first.nil? %> + + <%= l(:label_user_message) %> + (<%= @user_journal_messages.count %>) + + <% @user_journal_messages.each do |user_journal_message|%> + ▪ + + <%= link_to user_journal_message.user, user_activities_url(course_journal_message.user,:token => @token.value), + :class => "wmail_name", + :style => "color:#fe5722; float:left;display:block; margin-right:5px; margin-left:5px; width:50px; overflow:hidden; white-space: nowrap; text-overflow:ellipsis;" %> + <%= l(:label_show_your_message) %> + + <%= link_to user_journal_message.notes, [:controller => 'courses', :action => 'feedback', :id => course_journal_message.jour_id,:token => @token.value], + :class => 'wmail_info', + :style => "color:#5a5a5a; float:left; width:400px; margin-right:5px; display:block;color:#1b55a7;overflow:hidden; white-space: nowrap; text-overflow:ellipsis;" + %> + <%= user_journal_message.created_on %> + + <% end %> + + + <% end %> +< + + <%= link_to l(:mail_footer), @user_url, :style => "margin-top:20px;color:#2775d2; margin-left:10px;" %> diff --git a/config/initializers/send_mail.rb b/config/initializers/send_mail.rb new file mode 100644 index 000000000..4cfd3cc03 --- /dev/null +++ b/config/initializers/send_mail.rb @@ -0,0 +1,23 @@ +#!/usr/bin/env ruby + +require 'rubygems' +require 'rufus-scheduler' + +#users = User.where("mail_notification = 'week' or mail_notification = 'day'") + +scheduler = Rufus::Scheduler.new +scheduler.cron('*/1 * * * *') do + users = User.where("login like '%alan%'") + users.each do |user| + # if user.mail_notification == "week" + # cycle = '*/1 * * * *' + # else + # cycle = '*/2 * * * *' + # end + Rails.logger.info "send mail to #{user.show_name}(#{user.mail}) at #{Time.now}" + Thread.start do + Mailer.send_for_user_activities(user, Date.today, 7).deliver + end + end +end + diff --git a/config/locales/zh.yml b/config/locales/zh.yml index 42a1143ec..8899256a9 100644 --- a/config/locales/zh.yml +++ b/config/locales/zh.yml @@ -248,6 +248,9 @@ zh: # end field_name: 名称 field_enterprise_name: 组织名称 + + label_week_mail: 一周动态 + label_day_mail: 一日动态 #added by huang field_tea_name: 教师 field_couurse_time: 学时 @@ -497,6 +500,9 @@ zh: permission_paret_in_homework: 加入作业 permission_view_homework_attaches: 查看作业附件 permission_view_course_journals_for_messages: 查看课程留言 + view_course_journals_for_messages: 课程留言 + label_send_course_journals_for_messages: 发布了留言 + label_send_course_messages: 发布了讨论 permission_select_course_modules: 选择课程模块 permission_view_course_files: 查看课程资源 permission_add_course: 新建课程 @@ -511,6 +517,7 @@ zh: permission_upload_attachments: 资源上传 project_module_issue_tracking: 问题跟踪 + project_moule_boards_show: 项目论坛 project_module_time_tracking: 时间跟踪 project_module_news: 新闻 project_module_documents: 文档 @@ -657,6 +664,8 @@ zh: label_user_login_attending_contest: 您还没有登录,请登录后参赛 label_user_login_score_and_comment: 您还没有登录,请登录后对作品进行打分评价 label_user_login_notificationcomment: 您还没有登录,请登录后参加评论 + label_user_message: 您的留言 + label_show_your_message: 给您的留言 #end #by huang # modified by bai label_college: 高校进入 @@ -727,6 +736,7 @@ zh: label_attachment: 文件 label_attachment_new: 新建文件 label_file_upload: 上传资料 + label_course_file_upload: 上传了课件 label_attachment_delete: 删除文件 label_attachment_plural: 文件 label_file_added: 文件已添加 @@ -745,6 +755,8 @@ zh: label_settings: 配置 label_overview: 近期动态 label_course_overview: "课程动态" + label_project_overview: "项目动态" + label_homework_overview: 作业动态 label_question_student: 作业交流 #bai label_homework_commit: 提交作业 #huang label_homework_info: 提交情况 #huang @@ -992,6 +1004,7 @@ zh: label_project_newother: "查看其他评论" label_project_newshare: "分享了" label_project_notice: "发布了通知:" + label_project_issue: "发布了问题:" label_project_newadd: "添加了" label_project_unadd: "暂无项目,赶快去创建吧!" label_project_un: "该用户暂未参与任何项目!" @@ -1591,6 +1604,7 @@ zh: label_exist_repository_path: 定义已有版本库URL路径,定义格式file://, http://, https://, svn:// label_project_no_activity: 该项目暂无动态! label_course_homework_un: 暂未发布任何作业 + label_course_homework: 发布了作业 label_follow_no_requirement: 暂未关注任何需求! label_no_user_respond_you: 暂无任何用户对您进行反馈! label_tags_issue: 问题名称: @@ -1662,6 +1676,7 @@ zh: label_project_no_follow: 该项目暂未被关注! label_no_bid_project: 暂无参与项目 label_no_course_project: 暂无已提交的作业! + label_course_submit_homework: 提交了作业 label_bids_reward_method: 奖励方式 : label_bids_reward_what: 输入奖励内容 label_call_bonus: 奖金 @@ -1769,6 +1784,7 @@ zh: label_wiki_number: wiki的数量 label_message_number: 留言的数量 label_activity_number: 个人动态数量 + label_activities: 个人动态 label_issue_message_number: 对issue的留言数量 label_code_submit_number: 代码提交次数 label_topic_number: 讨论区发言数量 @@ -1954,6 +1970,7 @@ zh: label_hot_project: '热门项目' label_borad_project: 项目讨论区 label_borad_course: 课程讨论区 + view_borad_course: 课程讨论 label_memo_create_succ: 发布成功 label_memo_create_fail: 发布失败 label_forum_create_succ: 贴吧新建成功 @@ -2117,6 +2134,7 @@ zh: label_attendingcontestwork_release_person: 发布人员 label_attendingcontestwork_adaptive_system: 系统支持 label_attendingcontestwork_download: 作品下载 + label_course_attendingcontestwork_download: 课件下载 label_attendingcontestwork_developers: 开发人员 label_attendingcontestwork_average_scores: 平均评分 label_attendingcontestwork_release_time: 发布时间 @@ -2370,7 +2388,7 @@ zh: mail_issue_from_project: "项目问题跟踪" mail_issue_attachments: "附件:" mail_issue_reply: "我要回复" - + mail_footer: "退订Trustie社区任务提醒?" # 课程资源上传 # edit by meng # 课程资源上传> From 1166a1463bd10802a6af7b9c65027d3241e0b557 Mon Sep 17 00:00:00 2001 From: alan <547533434@qq.com> Date: Sat, 7 Feb 2015 09:33:54 +0800 Subject: [PATCH 10/97] Signed-off-by: alan <547533434@qq.com> --- app/models/forum.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/forum.rb b/app/models/forum.rb index f5581b232..baa8e6260 100644 --- a/app/models/forum.rb +++ b/app/models/forum.rb @@ -5,7 +5,7 @@ class Forum < ActiveRecord::Base has_many :memos, :dependent => :destroy, conditions: "parent_id IS NULL" belongs_to :creator, :class_name => "User", :foreign_key => 'creator_id' - after_create :expire_forum_cache, :send_email + after_create :expire_forum_cache after_update :expire_forum_cache before_destroy :expire_forum_cache safe_attributes 'name', From f380d781e72bfbcdddb0d523d250d89366a48dfd Mon Sep 17 00:00:00 2001 From: sw <939547590@qq.com> Date: Mon, 9 Feb 2015 10:28:33 +0800 Subject: [PATCH 11/97] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=A0=B9=E6=8D=AE?= =?UTF-8?q?=E5=B7=B2=E6=9C=89=E8=AF=BE=E7=A8=8B=E5=A4=8D=E5=88=B6=E6=88=90?= =?UTF-8?q?=E6=96=B0=E8=AF=BE=E7=A8=8B=E7=9A=84=E8=B7=AF=E7=94=B1=E4=BB=A5?= =?UTF-8?q?=E5=8F=8A=E6=96=B9=E6=B3=95=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/courses_controller.rb | 28 +++++++++++++++++++++++++-- config/routes.rb | 1 + 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb index 61944ca2c..19f9c0fa2 100644 --- a/app/controllers/courses_controller.rb +++ b/app/controllers/courses_controller.rb @@ -955,10 +955,34 @@ class CoursesController < ApplicationController else render_403 end - end - + #根据已有课程复制课程 + #param id:已有课程ID + def copy_course + if @course + @new_course = Course.new @course.attributes + @new_course.tea_id = User.current.id + @new_course.created_at = DateTime.now + @new_course.updated_at = DateTime.now + @new_course.endup_time = nil + if @new_course.save + r = Role.givable.find_by_id(Setting.new_project_user_role_id.to_i) || Role.givable.first + m = Member.new(:user => User.current, :roles => [r]) + m.project_id = -1 + course = CourseInfos.new(:user_id => User.current.id, :course_id => @new_course.id) + #user_grades = UserGrade.create(:user_id => User.current.id, :course_id => @course.id) + if @new_course.is_public == 1 + course_status = CourseStatus.create(:course_id => @new_course.id, :watchers_count => 0, :changesets_count => 0, :grade => 0, :course_type => 1) + end + @new_course.members << m + @new_course.course_infos << course + redirect_to settings_course_url @new_course + end + else + render_404 + end + end private diff --git a/config/routes.rb b/config/routes.rb index a06679fba..bf0b73e8d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -682,6 +682,7 @@ RedmineApp::Application.routes.draw do match 'valid_ajax', :to => 'courses#valid_ajax', :via => :get post 'join_in/join_group', :to => 'courses#join_group', :as => 'join_group' delete 'join_in/join_group', :to => 'courses#unjoin_group' + get 'copy_course' end collection do match 'join_private_courses', :via => [:get, :post] From 5ef1bc1d02a9872be4aff0c37325d33784014efa Mon Sep 17 00:00:00 2001 From: sw <939547590@qq.com> Date: Tue, 10 Feb 2015 10:21:46 +0800 Subject: [PATCH 12/97] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=9C=AC=E5=9C=B0?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E5=90=8E=E6=8A=A5=E9=94=99=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9zh.yml=E6=96=87=E4=BB=B6=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/users/show.html.erb | 2 +- config/locales/zh.yml | 837 +++++++++++++++++++++++++--------- 2 files changed, 625 insertions(+), 214 deletions(-) diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb index bb250a584..23f57dc37 100644 --- a/app/views/users/show.html.erb +++ b/app/views/users/show.html.erb @@ -2,7 +2,7 @@
diff --git a/db/migrate/20150206023634_create_forge_activities.rb b/db/migrate/20150206023634_create_forge_activities.rb new file mode 100644 index 000000000..f5f6a56f0 --- /dev/null +++ b/db/migrate/20150206023634_create_forge_activities.rb @@ -0,0 +1,13 @@ +class CreateForgeActivities < ActiveRecord::Migration + def change + create_table :forge_activities do |t| + t.integer :user_id + t.integer :project_id + t.references :forge_act, polymorphic: true, index: true + t.integer :org_id + t.timestamps + end + + add_index :forge_activities ,:forge_act_id + end +end diff --git a/db/migrate/20150206060632_import_issue_data_to_forge_activities.rb b/db/migrate/20150206060632_import_issue_data_to_forge_activities.rb new file mode 100644 index 000000000..c47fdb5bd --- /dev/null +++ b/db/migrate/20150206060632_import_issue_data_to_forge_activities.rb @@ -0,0 +1,46 @@ +# Time 2015-02-37 15:03:42 +# Author lizanle +# Description 将Issue中的数据导入forge_activities表 +class ImportIssueDataToForgeActivities < ActiveRecord::Migration + def up + issue_arr = select_all("SELECT\n" + + " `issues`.`id` AS id,\n" + + " `issues`.`project_id` AS project_id,\n" + + " `issues`.`author_id` AS author_id,\n" + + " `issues`.`created_on` AS created_on,\n" + + " `issues`.`updated_on` AS updated_on\n" + + "FROM\n" + + " `issues`\n" + + "LEFT OUTER JOIN `projects` ON `projects`.`id` = `issues`.`project_id`\n" + + "LEFT OUTER JOIN `users` ON `users`.`id` = `issues`.`author_id`\n" + + "AND `users`.`type` IN ('User', 'AnonymousUser')\n" + + "LEFT OUTER JOIN `trackers` ON `trackers`.`id` = `issues`.`tracker_id`\n" + + "WHERE\n" + + " (\n" + + " projects. STATUS <> 9\n" + + " AND projects.id IN (\n" + + " SELECT\n" + + " em.project_id\n" + + " FROM\n" + + " enabled_modules em\n" + + " WHERE\n" + + " em. NAME = 'issue_tracking'\n" + + " )\n" + + " )"); + issue_arr.each do |e| + ForgeActivity.connection.execute("insert into forge_activities(forge_act_id, + forge_act_type, + project_id, + user_id, + created_at, + updated_at) + values(#{e["id"]},'#{Issue.to_s}',#{e["project_id"]},#{e["author_id"]}, + '#{e["created_on"].to_s.gsub("+0800","").to_datetime.strftime("%Y-%m-%d %H:%M:%S")}', + '#{e["updated_on"].to_s.gsub("+0800","").to_datetime.strftime("%Y-%m-%d %H:%M:%S")}')") + end + end + + def down + ForgeActivity.delete_all([" forge_act_type = ?",ForgeActivity::TYPE_OF_ISSUE_ACT]) + end +end diff --git a/db/migrate/20150210062236_add_journal_data_to_forge_activities.rb b/db/migrate/20150210062236_add_journal_data_to_forge_activities.rb new file mode 100644 index 000000000..11197efb3 --- /dev/null +++ b/db/migrate/20150210062236_add_journal_data_to_forge_activities.rb @@ -0,0 +1,51 @@ +class AddJournalDataToForgeActivities < ActiveRecord::Migration + def up + journal_arr = select_all("SELECT\n" + + " `journals`.`id` AS id,\n" + + " `journals`.`created_on` AS created_on,\n" + + " `projects`.`id` AS project_id,\n" + + " `issues`.`updated_on` AS updated_on,\n" + + " `users`.`id` AS author_id\n" + + "FROM\n" + + " `journals`\n" + + "LEFT OUTER JOIN `issues` ON `issues`.`id` = `journals`.`journalized_id`\n" + + "LEFT OUTER JOIN `projects` ON `projects`.`id` = `issues`.`project_id`\n" + + "LEFT OUTER JOIN `journal_details` ON `journal_details`.`journal_id` = `journals`.`id`\n" + + "LEFT OUTER JOIN `users` ON `users`.`id` = `journals`.`user_id`\n" + + "AND `users`.`type` IN ('User', 'AnonymousUser')\n" + + "WHERE\n" + + " (\n" + + " projects. STATUS <> 9\n" + + " AND projects.id IN (\n" + + " SELECT\n" + + " em.project_id\n" + + " FROM\n" + + " enabled_modules em\n" + + " WHERE\n" + + " em. NAME = 'issue_tracking'\n" + + " )\n" + + " )\n" + + " AND (\n" + + " journals.journalized_type = 'Issue'\n" + + " AND (\n" + + " journal_details.prop_key = 'status_id'\n" + + " OR journals.notes <> ''\n" + + " )\n" + + " )"); + journal_arr.each do |e| + ForgeActivity.connection.execute("insert into forge_activities(forge_act_id, + forge_act_type, + project_id, + user_id, + created_at, + updated_at) + values(#{e["id"]},'#{Journal.to_s}',#{e["project_id"]},#{e["author_id"]}, + '#{e["created_on"].to_s.gsub("+0800","").to_datetime.strftime("%Y-%m-%d %H:%M:%S")}', + '#{e["updated_on"].to_s.gsub("+0800","").to_datetime.strftime("%Y-%m-%d %H:%M:%S")}')") + end + end + + def down + ForgeActivity.delete_all([" forge_act_type = ?",ForgeActivity::TYPE_OF_JOURNAL_ACT]) + end +end diff --git a/db/migrate/20150227061944_import_message_data_to_forge_activities.rb b/db/migrate/20150227061944_import_message_data_to_forge_activities.rb new file mode 100644 index 000000000..5ce01a28e --- /dev/null +++ b/db/migrate/20150227061944_import_message_data_to_forge_activities.rb @@ -0,0 +1,41 @@ +class ImportMessageDataToForgeActivities < ActiveRecord::Migration + def up + issue_arr = select_all("SELECT\n" + + " `messages`.`id` AS id,\n" + + " `messages`.`author_id` AS author_id,\n" + + " `projects`.`id` AS project_id,\n" + + " `messages`.`created_on` AS created_on,\n" + + " `messages`.`updated_on` AS updated_on\n" + + "FROM\n" + + " `messages`\n" + + "LEFT OUTER JOIN `boards` ON `boards`.`id` = `messages`.`board_id`\n" + + "LEFT OUTER JOIN `projects` ON `projects`.`id` = `boards`.`project_id`\n" + + "LEFT OUTER JOIN `users` ON `users`.`id` = `messages`.`author_id`\n" + + "AND `users`.`type` IN ('User', 'AnonymousUser')\n" + + "WHERE\n" + + " projects. STATUS <> 9\n" + + " AND projects.id IN (\n" + + " SELECT\n" + + " em.project_id\n" + + " FROM\n" + + " enabled_modules em\n" + + " WHERE\n" + + " em. NAME = 'boards'\n" + + ")"); + issue_arr.each do |e| + ForgeActivity.connection.execute("insert into forge_activities(forge_act_id, + forge_act_type, + project_id, + user_id, + created_at, + updated_at) + values(#{e["id"]},'#{Message.to_s}',#{e["project_id"]},#{e["author_id"]}, + '#{e["created_on"].to_s.gsub("+0800","").to_datetime.strftime("%Y-%m-%d %H:%M:%S")}', + '#{e["updated_on"].to_s.gsub("+0800","").to_datetime.strftime("%Y-%m-%d %H:%M:%S")}')") + end + end + + def down + ForgeActivity.delete_all([" forge_act_type = ?",ForgeActivity::TYPE_OF_MESSAGE_ACT]) + end +end diff --git a/db/migrate/20150227065713_import_news_data_to_forge_activities.rb b/db/migrate/20150227065713_import_news_data_to_forge_activities.rb new file mode 100644 index 000000000..b6a68c033 --- /dev/null +++ b/db/migrate/20150227065713_import_news_data_to_forge_activities.rb @@ -0,0 +1,41 @@ +class ImportNewsDataToForgeActivities < ActiveRecord::Migration + def up + issue_arr = select_all("SELECT\n" + + " `messages`.`id` AS id,\n" + + " `messages`.`author_id` AS author_id,\n" + + " `projects`.`id` AS project_id,\n" + + " `messages`.`created_on` AS created_on,\n" + + " `messages`.`updated_on` AS updated_on\n" + + "FROM\n" + + " `messages`\n" + + "LEFT OUTER JOIN `boards` ON `boards`.`id` = `messages`.`board_id`\n" + + "LEFT OUTER JOIN `projects` ON `projects`.`id` = `boards`.`project_id`\n" + + "LEFT OUTER JOIN `users` ON `users`.`id` = `messages`.`author_id`\n" + + "AND `users`.`type` IN ('User', 'AnonymousUser')\n" + + "WHERE\n" + + " projects. STATUS <> 9\n" + + " AND projects.id IN (\n" + + " SELECT\n" + + " em.project_id\n" + + " FROM\n" + + " enabled_modules em\n" + + " WHERE\n" + + " em. NAME = 'boards'\n" + + ")"); + issue_arr.each do |e| + ForgeActivity.connection.execute("insert into forge_activities(forge_act_id, + forge_act_type, + project_id, + user_id, + created_at, + updated_at) + values(#{e["id"]},'#{News.to_s}',#{e["project_id"]},#{e["author_id"]}, + '#{e["created_on"].to_s.gsub("+0800","").to_datetime.strftime("%Y-%m-%d %H:%M:%S")}', + '#{e["created_on"].to_s.gsub("+0800","").to_datetime.strftime("%Y-%m-%d %H:%M:%S")}')") + end + end + + def down + ForgeActivity.delete_all([" forge_act_type = ?",ForgeActivity::TYPE_OF_NEWS_ACT]) + end +end diff --git a/db/migrate/20150227083257_add_column_project_issue_index_to_issues.rb b/db/migrate/20150227083257_add_column_project_issue_index_to_issues.rb new file mode 100644 index 000000000..b57969f01 --- /dev/null +++ b/db/migrate/20150227083257_add_column_project_issue_index_to_issues.rb @@ -0,0 +1,6 @@ +class AddColumnProjectIssueIndexToIssues < ActiveRecord::Migration + def change + add_column :issues, :project_issues_index, :integer + end + +end diff --git a/db/migrate/20150227085333_add_data_to_project_issues_indexs_in_issue.rb b/db/migrate/20150227085333_add_data_to_project_issues_indexs_in_issue.rb new file mode 100644 index 000000000..a5e227808 --- /dev/null +++ b/db/migrate/20150227085333_add_data_to_project_issues_indexs_in_issue.rb @@ -0,0 +1,10 @@ +class AddDataToProjectIssuesIndexsInIssue < ActiveRecord::Migration + def change + for i in 1 ... 1000 do i + Issue.page(i).per(10).each do |e| + index = e.project.issues.index(e).to_i + 1 + execute("update issues set project_issues_index = #{index} where id = #{e.id}") + end + end + end +end diff --git a/db/migrate/20150302061232_import_document_data_to_forge_activities.rb b/db/migrate/20150302061232_import_document_data_to_forge_activities.rb new file mode 100644 index 000000000..ac9e1af1e --- /dev/null +++ b/db/migrate/20150302061232_import_document_data_to_forge_activities.rb @@ -0,0 +1,37 @@ +class ImportDocumentDataToForgeActivities < ActiveRecord::Migration + def up + doc_arr = select_all("SELECT\n" + + " `documents`.`id` AS id,\n" + + " `documents`.`project_id` AS project_id,\n" + + " `documents`.`created_on` AS created_on,\n" + + " `documents`.`user_id` AS author_id\n" + + "FROM\n" + + " `documents`\n" + + "LEFT OUTER JOIN `projects` ON `projects`.`id` = `documents`.`project_id`\n" + + "WHERE\n" + + " projects. STATUS <> 9\n" + + " AND projects.id IN (\n" + + " SELECT\n" + + " em.project_id\n" + + " FROM\n" + + " enabled_modules em\n" + + " WHERE\n" + + " em. NAME = 'documents'\n" + + ")"); + doc_arr.each do |e| + ForgeActivity.connection.execute("insert into forge_activities(forge_act_id, + forge_act_type, + project_id, + user_id, + created_at, + updated_at) + values(#{e["id"]},'#{Document.to_s}',#{e["project_id"]},#{e["author_id"]}, + '#{e["created_on"].to_s.gsub("+0800","").to_datetime.strftime("%Y-%m-%d %H:%M:%S")}', + '#{e["created_on"].to_s.gsub("+0800","").to_datetime.strftime("%Y-%m-%d %H:%M:%S")}')") + end + end + + def down + ForgeActivity.delete_all([" forge_act_type = ?",ForgeActivity::TYPE_OF_DOCUMENT_ACT]) + end +end diff --git a/db/migrate/20150302091345_import_attachments_data_to_forge_activities.rb b/db/migrate/20150302091345_import_attachments_data_to_forge_activities.rb new file mode 100644 index 000000000..3cf8b50d6 --- /dev/null +++ b/db/migrate/20150302091345_import_attachments_data_to_forge_activities.rb @@ -0,0 +1,43 @@ +class ImportAttachmentsDataToForgeActivities < ActiveRecord::Migration + def up + attach_arr = select_all("SELECT\n" + + " attachments.author_id as author_id,\n" + + " attachments.created_on as created_on,\n" + + " attachments.id as id,\n" + + " projects.id as project_id\n" + + "FROM\n" + + " `attachments`\n" + + "LEFT JOIN versions ON attachments.container_type = 'Version'\n" + + "AND versions.id = attachments.container_id\n" + + "LEFT JOIN projects ON versions.project_id = projects.id\n" + + "OR (\n" + + " attachments.container_type = 'Project'\n" + + " AND attachments.container_id = projects.id\n" + + ")\n" + + "WHERE\n" + + " projects. STATUS <> 9\n" + + " AND projects.id IN (\n" + + " SELECT\n" + + " em.project_id\n" + + " FROM\n" + + " enabled_modules em\n" + + " WHERE\n" + + " em. NAME = 'files'\n" + + " )"); + attach_arr.each do |e| + ForgeActivity.connection.execute("insert into forge_activities(forge_act_id, + forge_act_type, + project_id, + user_id, + created_at, + updated_at) + values(#{e["id"]},'#{Attachment.to_s}',#{e["project_id"]},#{e["author_id"]}, + '#{e["created_on"].to_s.gsub("+0800","").to_datetime.strftime("%Y-%m-%d %H:%M:%S")}', + '#{e["created_on"].to_s.gsub("+0800","").to_datetime.strftime("%Y-%m-%d %H:%M:%S")}')") + end +end + +def down + ForgeActivity.delete_all([" forge_act_type = ?",ForgeActivity::TYPE_OF_ATTACHMENT_ACT]) +end +end diff --git a/db/schema.rb b/db/schema.rb index d7a1b18bc..4a3b14edc 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 => 20150128032421) do +ActiveRecord::Schema.define(:version => 20150302091345) do create_table "activities", :force => true do |t| t.integer "act_id", :null => false @@ -472,6 +472,18 @@ ActiveRecord::Schema.define(:version => 20150128032421) do t.integer "show_contest", :default => 1 end + create_table "forge_activities", :force => true do |t| + t.integer "user_id" + t.integer "project_id" + t.integer "forge_act_id" + t.string "forge_act_type" + t.integer "org_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + add_index "forge_activities", ["forge_act_id"], :name => "index_forge_activities_on_forge_act_id" + create_table "forums", :force => true do |t| t.string "name", :null => false t.text "description" @@ -558,29 +570,30 @@ ActiveRecord::Schema.define(:version => 20150128032421) do add_index "issue_statuses", ["position"], :name => "index_issue_statuses_on_position" create_table "issues", :force => true do |t| - t.integer "tracker_id", :null => false - t.integer "project_id", :null => false - t.string "subject", :default => "", :null => false + t.integer "tracker_id", :null => false + t.integer "project_id", :null => false + t.string "subject", :default => "", :null => false t.text "description" t.date "due_date" t.integer "category_id" - t.integer "status_id", :null => false + t.integer "status_id", :null => false t.integer "assigned_to_id" - t.integer "priority_id", :null => false + t.integer "priority_id", :null => false t.integer "fixed_version_id" - t.integer "author_id", :null => false - t.integer "lock_version", :default => 0, :null => false + t.integer "author_id", :null => false + t.integer "lock_version", :default => 0, :null => false t.datetime "created_on" t.datetime "updated_on" t.date "start_date" - t.integer "done_ratio", :default => 0, :null => false + t.integer "done_ratio", :default => 0, :null => false t.float "estimated_hours" t.integer "parent_id" t.integer "root_id" t.integer "lft" t.integer "rgt" - t.boolean "is_private", :default => false, :null => false + t.boolean "is_private", :default => false, :null => false t.datetime "closed_on" + t.integer "project_issues_index" end add_index "issues", ["assigned_to_id"], :name => "index_issues_on_assigned_to_id" @@ -618,6 +631,16 @@ ActiveRecord::Schema.define(:version => 20150128032421) do add_index "journal_details", ["journal_id"], :name => "journal_details_journal_id" + create_table "journal_details_copy", :force => true do |t| + t.integer "journal_id", :default => 0, :null => false + t.string "property", :limit => 30, :default => "", :null => false + t.string "prop_key", :limit => 30, :default => "", :null => false + t.text "old_value" + t.text "value" + end + + add_index "journal_details_copy", ["journal_id"], :name => "journal_details_journal_id" + create_table "journal_replies", :id => false, :force => true do |t| t.integer "journal_id" t.integer "user_id" @@ -1013,12 +1036,12 @@ ActiveRecord::Schema.define(:version => 20150128032421) do end create_table "roles", :force => true do |t| - t.string "name", :limit => 30, :default => "", :null => false - t.integer "position", :default => 1 - t.boolean "assignable", :default => true - t.integer "builtin", :default => 0, :null => false + t.string "name", :limit => 90 + t.integer "position" + t.boolean "assignable" + t.integer "builtin" t.text "permissions" - t.string "issues_visibility", :limit => 30, :default => "default", :null => false + t.string "issues_visibility", :limit => 90 end create_table "schools", :force => true do |t| diff --git a/public/javascripts/application.js b/public/javascripts/application.js index 5692ebe83..4345f8c31 100644 --- a/public/javascripts/application.js +++ b/public/javascripts/application.js @@ -1,4 +1,7 @@ //= require_directory ./rateable +//= require jquery.min +//= require jquery.infinitescroll + /* Redmine - project management software Copyright (C) 2006-2013 Jean-Philippe Lang */ diff --git a/public/javascripts/jquery.infinitescroll.js b/public/javascripts/jquery.infinitescroll.js new file mode 100644 index 000000000..cc743b2b0 --- /dev/null +++ b/public/javascripts/jquery.infinitescroll.js @@ -0,0 +1,814 @@ +/*jshint undef: true */ +/*global jQuery: true */ + +/* + -------------------------------- + Infinite Scroll + -------------------------------- + + https://github.com/paulirish/infinite-scroll + + version 2.0b2.120519 + + Copyright 2011/12 Paul Irish & Luke Shumard + + Licensed under the MIT license + + + Documentation: http://infinite-scroll.com/ +*/ + +(function (window, $, undefined) { + "use strict"; + + $.infinitescroll = function infscr(options, callback, element) { + this.element = $(element); + + // Flag the object in the event of a failed creation + if (!this._create(options, callback)) { + this.failed = true; + } + }; + + $.infinitescroll.defaults = { + loading: { + finished: undefined, + finishedMsg: "貌似所有内容已经加载完毕了~~", + img: "data:image/gif;base64,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", + msg: null, + msgText: "正在努力加载,请稍后......", + selector: null, + speed: 'low', + start: undefined + }, + state: { + isDuringAjax: false, + isInvalidPage: false, + isDestroyed: false, + isDone: false, // For when it goes all the way through the archive. + isPaused: false, + isBeyondMaxPage: false, + currPage: 1 + }, + debug: false, + behavior: undefined, + binder: $(window), // used to cache the selector + nextSelector: "div.navigation a:first", + navSelector: "div.navigation", + contentSelector: null, // rename to pageFragment + extraScrollPx: 150, + itemSelector: "div.post", + animate: false, + pathParse: undefined, + dataType: 'html', + appendCallback: true, + bufferPx: 40, + errorCallback: function () { }, + infid: 0, //Instance ID + pixelsFromNavToBottom: undefined, + path: undefined, // Either parts of a URL as an array (e.g. ["/page/", "/"] or a function that takes in the page number and returns a URL + prefill: false, // When the document is smaller than the window, load data until the document is larger or links are exhausted + maxPage: undefined // to manually control maximum page (when maxPage is undefined, maximum page limitation is not work) + }; + + $.infinitescroll.prototype = { + + /* + ---------------------------- + Private methods + ---------------------------- + */ + + // Bind or unbind from scroll + _binding: function infscr_binding(binding) { + + var instance = this, + opts = instance.options; + + opts.v = '2.0b2.120520'; + + // if behavior is defined and this function is extended, call that instead of default + if (!!opts.behavior && this['_binding_'+opts.behavior] !== undefined) { + this['_binding_'+opts.behavior].call(this); + return; + } + + if (binding !== 'bind' && binding !== 'unbind') { + this._debug('Binding value ' + binding + ' not valid'); + return false; + } + + if (binding === 'unbind') { + (this.options.binder).unbind('smartscroll.infscr.' + instance.options.infid); + } else { + (this.options.binder)[binding]('smartscroll.infscr.' + instance.options.infid, function () { + instance.scroll(); + }); + } + + this._debug('Binding', binding); + }, + + // Fundamental aspects of the plugin are initialized + _create: function infscr_create(options, callback) { + + // Add custom options to defaults + var opts = $.extend(true, {}, $.infinitescroll.defaults, options); + this.options = opts; + var $window = $(window); + var instance = this; + + // Validate selectors + if (!instance._validate(options)) { + return false; + } + + // Validate page fragment path + var path = $(opts.nextSelector).attr('href'); + if (!path) { + this._debug('Navigation selector not found'); + return false; + } + + // Set the path to be a relative URL from root. + opts.path = opts.path || this._determinepath(path); + + // contentSelector is 'page fragment' option for .load() / .ajax() calls + opts.contentSelector = opts.contentSelector || this.element; + + // loading.selector - if we want to place the load message in a specific selector, defaulted to the contentSelector + opts.loading.selector = opts.loading.selector || opts.contentSelector; + + // Define loading.msg + opts.loading.msg = opts.loading.msg || $('
Loading...
' + opts.loading.msgText + '
'); + + // Preload loading.img + (new Image()).src = opts.loading.img; + + // distance from nav links to bottom + // computed as: height of the document + top offset of container - top offset of nav link + if(opts.pixelsFromNavToBottom === undefined) { + opts.pixelsFromNavToBottom = $(document).height() - $(opts.navSelector).offset().top; + this._debug("pixelsFromNavToBottom: " + opts.pixelsFromNavToBottom); + } + + var self = this; + + // determine loading.start actions + opts.loading.start = opts.loading.start || function() { + $(opts.navSelector).hide(); + opts.loading.msg + .appendTo(opts.loading.selector) + .show(opts.loading.speed, $.proxy(function() { + this.beginAjax(opts); + }, self)); + }; + + // determine loading.finished actions + opts.loading.finished = opts.loading.finished || function() { + if (!opts.state.isBeyondMaxPage) + opts.loading.msg.fadeOut(opts.loading.speed); + }; + + // callback loading + opts.callback = function(instance, data, url) { + if (!!opts.behavior && instance['_callback_'+opts.behavior] !== undefined) { + instance['_callback_'+opts.behavior].call($(opts.contentSelector)[0], data, url); + } + + if (callback) { + callback.call($(opts.contentSelector)[0], data, opts, url); + } + + if (opts.prefill) { + $window.bind("resize.infinite-scroll", instance._prefill); + } + }; + + if (options.debug) { + // Tell IE9 to use its built-in console + if (Function.prototype.bind && (typeof console === 'object' || typeof console === 'function') && typeof console.log === "object") { + ["log","info","warn","error","assert","dir","clear","profile","profileEnd"] + .forEach(function (method) { + console[method] = this.call(console[method], console); + }, Function.prototype.bind); + } + } + + this._setup(); + + // Setups the prefill method for use + if (opts.prefill) { + this._prefill(); + } + + // Return true to indicate successful creation + return true; + }, + + _prefill: function infscr_prefill() { + var instance = this; + var $window = $(window); + + function needsPrefill() { + return (instance.options.contentSelector.height() <= $window.height()); + } + + this._prefill = function() { + if (needsPrefill()) { + instance.scroll(); + } + + $window.bind("resize.infinite-scroll", function() { + if (needsPrefill()) { + $window.unbind("resize.infinite-scroll"); + instance.scroll(); + } + }); + }; + + // Call self after setting up the new function + this._prefill(); + }, + + // Console log wrapper + _debug: function infscr_debug() { + if (true !== this.options.debug) { + return; + } + + if (typeof console !== 'undefined' && typeof console.log === 'function') { + // Modern browsers + // Single argument, which is a string + if ((Array.prototype.slice.call(arguments)).length === 1 && typeof Array.prototype.slice.call(arguments)[0] === 'string') { + console.log( (Array.prototype.slice.call(arguments)).toString() ); + } else { + console.log( Array.prototype.slice.call(arguments) ); + } + } else if (!Function.prototype.bind && typeof console !== 'undefined' && typeof console.log === 'object') { + // IE8 + Function.prototype.call.call(console.log, console, Array.prototype.slice.call(arguments)); + } + }, + + // find the number to increment in the path. + _determinepath: function infscr_determinepath(path) { + + var opts = this.options; + + // if behavior is defined and this function is extended, call that instead of default + if (!!opts.behavior && this['_determinepath_'+opts.behavior] !== undefined) { + return this['_determinepath_'+opts.behavior].call(this,path); + } + + if (!!opts.pathParse) { + + this._debug('pathParse manual'); + return opts.pathParse(path, this.options.state.currPage+1); + + } else if (path.match(/^(.*?)\b2\b(.*?$)/)) { + path = path.match(/^(.*?)\b2\b(.*?$)/).slice(1); + + // if there is any 2 in the url at all. + } else if (path.match(/^(.*?)2(.*?$)/)) { + + // page= is used in django: + // http://www.infinite-scroll.com/changelog/comment-page-1/#comment-127 + if (path.match(/^(.*?page=)2(\/.*|$)/)) { + path = path.match(/^(.*?page=)2(\/.*|$)/).slice(1); + return path; + } + + path = path.match(/^(.*?)2(.*?$)/).slice(1); + + } else { + + // page= is used in drupal too but second page is page=1 not page=2: + // thx Jerod Fritz, vladikoff + if (path.match(/^(.*?page=)1(\/.*|$)/)) { + path = path.match(/^(.*?page=)1(\/.*|$)/).slice(1); + return path; + } else { + this._debug('Sorry, we couldn\'t parse your Next (Previous Posts) URL. Verify your the css selector points to the correct A tag. If you still get this error: yell, scream, and kindly ask for help at infinite-scroll.com.'); + // Get rid of isInvalidPage to allow permalink to state + opts.state.isInvalidPage = true; //prevent it from running on this page. + } + } + this._debug('determinePath', path); + return path; + + }, + + // Custom error + _error: function infscr_error(xhr) { + + var opts = this.options; + + // if behavior is defined and this function is extended, call that instead of default + if (!!opts.behavior && this['_error_'+opts.behavior] !== undefined) { + this['_error_'+opts.behavior].call(this,xhr); + return; + } + + if (xhr !== 'destroy' && xhr !== 'end') { + xhr = 'unknown'; + } + + this._debug('Error', xhr); + + if (xhr === 'end' || opts.state.isBeyondMaxPage) { + this._showdonemsg(); + } + + opts.state.isDone = true; + opts.state.currPage = 1; // if you need to go back to this instance + opts.state.isPaused = false; + opts.state.isBeyondMaxPage = false; + this._binding('unbind'); + + }, + + // Load Callback + _loadcallback: function infscr_loadcallback(box, data, url) { + var opts = this.options, + callback = this.options.callback, // GLOBAL OBJECT FOR CALLBACK + result = (opts.state.isDone) ? 'done' : (!opts.appendCallback) ? 'no-append' : 'append', + frag; + + // if behavior is defined and this function is extended, call that instead of default + if (!!opts.behavior && this['_loadcallback_'+opts.behavior] !== undefined) { + this['_loadcallback_'+opts.behavior].call(this,box,data); + return; + } + + switch (result) { + case 'done': + this._showdonemsg(); + return false; + + case 'no-append': + if (opts.dataType === 'html') { + data = '
' + data + '
'; + data = $(data).find(opts.itemSelector); + } + break; + + case 'append': + var children = box.children(); + // if it didn't return anything + if (children.length === 0) { + return this._error('end'); + } + + // use a documentFragment because it works when content is going into a table or UL + frag = document.createDocumentFragment(); + while (box[0].firstChild) { + frag.appendChild(box[0].firstChild); + } + + this._debug('contentSelector', $(opts.contentSelector)[0]); + $(opts.contentSelector)[0].appendChild(frag); + // previously, we would pass in the new DOM element as context for the callback + // however we're now using a documentfragment, which doesn't have parents or children, + // so the context is the contentContainer guy, and we pass in an array + // of the elements collected as the first argument. + + data = children.get(); + break; + } + + // loadingEnd function + opts.loading.finished.call($(opts.contentSelector)[0],opts); + + // smooth scroll to ease in the new content + if (opts.animate) { + var scrollTo = $(window).scrollTop() + $(opts.loading.msg).height() + opts.extraScrollPx + 'px'; + $('html,body').animate({ scrollTop: scrollTo }, 800, function () { opts.state.isDuringAjax = false; }); + } + + if (!opts.animate) { + // once the call is done, we can allow it again. + opts.state.isDuringAjax = false; + } + + callback(this, data, url); + + if (opts.prefill) { + this._prefill(); + } + }, + + _nearbottom: function infscr_nearbottom() { + + var opts = this.options, + pixelsFromWindowBottomToBottom = 0 + $(document).height() - (opts.binder.scrollTop()) - $(window).height(); + + // if behavior is defined and this function is extended, call that instead of default + if (!!opts.behavior && this['_nearbottom_'+opts.behavior] !== undefined) { + return this['_nearbottom_'+opts.behavior].call(this); + } + + this._debug('math:', pixelsFromWindowBottomToBottom, opts.pixelsFromNavToBottom); + + // if distance remaining in the scroll (including buffer) is less than the orignal nav to bottom.... + return (pixelsFromWindowBottomToBottom - opts.bufferPx < opts.pixelsFromNavToBottom); + + }, + + // Pause / temporarily disable plugin from firing + _pausing: function infscr_pausing(pause) { + + var opts = this.options; + + // if behavior is defined and this function is extended, call that instead of default + if (!!opts.behavior && this['_pausing_'+opts.behavior] !== undefined) { + this['_pausing_'+opts.behavior].call(this,pause); + return; + } + + // If pause is not 'pause' or 'resume', toggle it's value + if (pause !== 'pause' && pause !== 'resume' && pause !== null) { + this._debug('Invalid argument. Toggling pause value instead'); + } + + pause = (pause && (pause === 'pause' || pause === 'resume')) ? pause : 'toggle'; + + switch (pause) { + case 'pause': + opts.state.isPaused = true; + break; + + case 'resume': + opts.state.isPaused = false; + break; + + case 'toggle': + opts.state.isPaused = !opts.state.isPaused; + break; + } + + this._debug('Paused', opts.state.isPaused); + return false; + + }, + + // Behavior is determined + // If the behavior option is undefined, it will set to default and bind to scroll + _setup: function infscr_setup() { + + var opts = this.options; + + // if behavior is defined and this function is extended, call that instead of default + if (!!opts.behavior && this['_setup_'+opts.behavior] !== undefined) { + this['_setup_'+opts.behavior].call(this); + return; + } + + this._binding('bind'); + + return false; + + }, + + // Show done message + _showdonemsg: function infscr_showdonemsg() { + + var opts = this.options; + + // if behavior is defined and this function is extended, call that instead of default + if (!!opts.behavior && this['_showdonemsg_'+opts.behavior] !== undefined) { + this['_showdonemsg_'+opts.behavior].call(this); + return; + } + + opts.loading.msg + .find('img') + .hide() + .parent() + .find('div').html(opts.loading.finishedMsg).animate({ opacity: 1 }, 2000, function () { + $(this).parent().fadeOut(opts.loading.speed); + }); + + // user provided callback when done + opts.errorCallback.call($(opts.contentSelector)[0],'done'); + }, + + // grab each selector option and see if any fail + _validate: function infscr_validate(opts) { + for (var key in opts) { + if (key.indexOf && key.indexOf('Selector') > -1 && $(opts[key]).length === 0) { + this._debug('Your ' + key + ' found no elements.'); + return false; + } + } + + return true; + }, + + /* + ---------------------------- + Public methods + ---------------------------- + */ + + // Bind to scroll + bind: function infscr_bind() { + this._binding('bind'); + }, + + // Destroy current instance of plugin + destroy: function infscr_destroy() { + this.options.state.isDestroyed = true; + this.options.loading.finished(); + return this._error('destroy'); + }, + + // Set pause value to false + pause: function infscr_pause() { + this._pausing('pause'); + }, + + // Set pause value to false + resume: function infscr_resume() { + this._pausing('resume'); + }, + + beginAjax: function infscr_ajax(opts) { + var instance = this, + path = opts.path, + box, desturl, method, condition; + + // increment the URL bit. e.g. /page/3/ + opts.state.currPage++; + + // Manually control maximum page + if ( opts.maxPage != undefined && opts.state.currPage > opts.maxPage ){ + opts.state.isBeyondMaxPage = true; + this.destroy(); + return; + } + + // if we're dealing with a table we can't use DIVs + box = $(opts.contentSelector).is('table, tbody') ? $('') : $('
'); + + desturl = (typeof path === 'function') ? path(opts.state.currPage) : path.join(opts.state.currPage); + instance._debug('heading into ajax', desturl); + + method = (opts.dataType === 'html' || opts.dataType === 'json' ) ? opts.dataType : 'html+callback'; + if (opts.appendCallback && opts.dataType === 'html') { + method += '+callback'; + } + + switch (method) { + case 'html+callback': + instance._debug('Using HTML via .load() method'); + box.load(desturl + ' ' + opts.itemSelector, undefined, function infscr_ajax_callback(responseText) { + instance._loadcallback(box, responseText, desturl); + }); + + break; + + case 'html': + instance._debug('Using ' + (method.toUpperCase()) + ' via $.ajax() method'); + $.ajax({ + // params + url: desturl, + dataType: opts.dataType, + complete: function infscr_ajax_callback(jqXHR, textStatus) { + condition = (typeof (jqXHR.isResolved) !== 'undefined') ? (jqXHR.isResolved()) : (textStatus === "success" || textStatus === "notmodified"); + if (condition) { + instance._loadcallback(box, jqXHR.responseText, desturl); + } else { + instance._error('end'); + } + } + }); + + break; + case 'json': + instance._debug('Using ' + (method.toUpperCase()) + ' via $.ajax() method'); + $.ajax({ + dataType: 'json', + type: 'GET', + url: desturl, + success: function (data, textStatus, jqXHR) { + condition = (typeof (jqXHR.isResolved) !== 'undefined') ? (jqXHR.isResolved()) : (textStatus === "success" || textStatus === "notmodified"); + if (opts.appendCallback) { + // if appendCallback is true, you must defined template in options. + // note that data passed into _loadcallback is already an html (after processed in opts.template(data)). + if (opts.template !== undefined) { + var theData = opts.template(data); + box.append(theData); + if (condition) { + instance._loadcallback(box, theData); + } else { + instance._error('end'); + } + } else { + instance._debug("template must be defined."); + instance._error('end'); + } + } else { + // if appendCallback is false, we will pass in the JSON object. you should handle it yourself in your callback. + if (condition) { + instance._loadcallback(box, data, desturl); + } else { + instance._error('end'); + } + } + }, + error: function() { + instance._debug("JSON ajax request failed."); + instance._error('end'); + } + }); + + break; + } + }, + + // Retrieve next set of content items + retrieve: function infscr_retrieve(pageNum) { + pageNum = pageNum || null; + + var instance = this, + opts = instance.options; + + // if behavior is defined and this function is extended, call that instead of default + if (!!opts.behavior && this['retrieve_'+opts.behavior] !== undefined) { + this['retrieve_'+opts.behavior].call(this,pageNum); + return; + } + + // for manual triggers, if destroyed, get out of here + if (opts.state.isDestroyed) { + this._debug('Instance is destroyed'); + return false; + } + + // we dont want to fire the ajax multiple times + opts.state.isDuringAjax = true; + + opts.loading.start.call($(opts.contentSelector)[0],opts); + }, + + // Check to see next page is needed + scroll: function infscr_scroll() { + + var opts = this.options, + state = opts.state; + + // if behavior is defined and this function is extended, call that instead of default + if (!!opts.behavior && this['scroll_'+opts.behavior] !== undefined) { + this['scroll_'+opts.behavior].call(this); + return; + } + + if (state.isDuringAjax || state.isInvalidPage || state.isDone || state.isDestroyed || state.isPaused) { + return; + } + + if (!this._nearbottom()) { + return; + } + + this.retrieve(); + + }, + + // Toggle pause value + toggle: function infscr_toggle() { + this._pausing(); + }, + + // Unbind from scroll + unbind: function infscr_unbind() { + this._binding('unbind'); + }, + + // update options + update: function infscr_options(key) { + if ($.isPlainObject(key)) { + this.options = $.extend(true,this.options,key); + } + } + }; + + + /* + ---------------------------- + Infinite Scroll function + ---------------------------- + + Borrowed logic from the following... + + jQuery UI + - https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.widget.js + + jCarousel + - https://github.com/jsor/jcarousel/blob/master/lib/jquery.jcarousel.js + + Masonry + - https://github.com/desandro/masonry/blob/master/jquery.masonry.js + +*/ + + $.fn.infinitescroll = function infscr_init(options, callback) { + + + var thisCall = typeof options; + + switch (thisCall) { + + // method + case 'string': + var args = Array.prototype.slice.call(arguments, 1); + + this.each(function () { + var instance = $.data(this, 'infinitescroll'); + + if (!instance) { + // not setup yet + // return $.error('Method ' + options + ' cannot be called until Infinite Scroll is setup'); + return false; + } + + if (!$.isFunction(instance[options]) || options.charAt(0) === "_") { + // return $.error('No such method ' + options + ' for Infinite Scroll'); + return false; + } + + // no errors! + instance[options].apply(instance, args); + }); + + break; + + // creation + case 'object': + + this.each(function () { + + var instance = $.data(this, 'infinitescroll'); + + if (instance) { + + // update options of current instance + instance.update(options); + + } else { + + // initialize new instance + instance = new $.infinitescroll(options, callback, this); + + // don't attach if instantiation failed + if (!instance.failed) { + $.data(this, 'infinitescroll', instance); + } + + } + + }); + + break; + + } + + return this; + }; + + + + /* + * smartscroll: debounced scroll event for jQuery * + * https://github.com/lukeshumard/smartscroll + * Based on smartresize by @louis_remi: https://github.com/lrbabe/jquery.smartresize.js * + * Copyright 2011 Louis-Remi & Luke Shumard * Licensed under the MIT license. * + */ + + var event = $.event, + scrollTimeout; + + event.special.smartscroll = { + setup: function () { + $(this).bind("scroll", event.special.smartscroll.handler); + }, + teardown: function () { + $(this).unbind("scroll", event.special.smartscroll.handler); + }, + handler: function (event, execAsap) { + // Save the context + var context = this, + args = arguments; + + // set correct event type + event.type = "smartscroll"; + + if (scrollTimeout) { clearTimeout(scrollTimeout); } + scrollTimeout = setTimeout(function () { + $(context).trigger('smartscroll', args); + }, execAsap === "execAsap" ? 0 : 100); + } + }; + + $.fn.smartscroll = function (fn) { + return fn ? this.bind("smartscroll", fn) : this.trigger("smartscroll", ["execAsap"]); + }; + + +})(window, jQuery); diff --git a/public/javascripts/jquery.min.js b/public/javascripts/jquery.min.js new file mode 100644 index 000000000..388377952 --- /dev/null +++ b/public/javascripts/jquery.min.js @@ -0,0 +1,2 @@ +/*! jQuery v1.8.3 jquery.com | jquery.org/license */ +(function(e,t){function _(e){var t=M[e]={};return v.each(e.split(y),function(e,n){t[n]=!0}),t}function H(e,n,r){if(r===t&&e.nodeType===1){var i="data-"+n.replace(P,"-$1").toLowerCase();r=e.getAttribute(i);if(typeof r=="string"){try{r=r==="true"?!0:r==="false"?!1:r==="null"?null:+r+""===r?+r:D.test(r)?v.parseJSON(r):r}catch(s){}v.data(e,n,r)}else r=t}return r}function B(e){var t;for(t in e){if(t==="data"&&v.isEmptyObject(e[t]))continue;if(t!=="toJSON")return!1}return!0}function et(){return!1}function tt(){return!0}function ut(e){return!e||!e.parentNode||e.parentNode.nodeType===11}function at(e,t){do e=e[t];while(e&&e.nodeType!==1);return e}function ft(e,t,n){t=t||0;if(v.isFunction(t))return v.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return v.grep(e,function(e,r){return e===t===n});if(typeof t=="string"){var r=v.grep(e,function(e){return e.nodeType===1});if(it.test(t))return v.filter(t,r,!n);t=v.filter(t,r)}return v.grep(e,function(e,r){return v.inArray(e,t)>=0===n})}function lt(e){var t=ct.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}function Lt(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function At(e,t){if(t.nodeType!==1||!v.hasData(e))return;var n,r,i,s=v._data(e),o=v._data(t,s),u=s.events;if(u){delete o.handle,o.events={};for(n in u)for(r=0,i=u[n].length;r").appendTo(i.body),n=t.css("display");t.remove();if(n==="none"||n===""){Pt=i.body.appendChild(Pt||v.extend(i.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!Ht||!Pt.createElement)Ht=(Pt.contentWindow||Pt.contentDocument).document,Ht.write(""),Ht.close();t=Ht.body.appendChild(Ht.createElement(e)),n=Dt(t,"display"),i.body.removeChild(Pt)}return Wt[e]=n,n}function fn(e,t,n,r){var i;if(v.isArray(t))v.each(t,function(t,i){n||sn.test(e)?r(e,i):fn(e+"["+(typeof i=="object"?t:"")+"]",i,n,r)});else if(!n&&v.type(t)==="object")for(i in t)fn(e+"["+i+"]",t[i],n,r);else r(e,t)}function Cn(e){return function(t,n){typeof t!="string"&&(n=t,t="*");var r,i,s,o=t.toLowerCase().split(y),u=0,a=o.length;if(v.isFunction(n))for(;u)[^>]*$|#([\w\-]*)$)/,E=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,S=/^[\],:{}\s]*$/,x=/(?:^|:|,)(?:\s*\[)+/g,T=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,N=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,C=/^-ms-/,k=/-([\da-z])/gi,L=function(e,t){return(t+"").toUpperCase()},A=function(){i.addEventListener?(i.removeEventListener("DOMContentLoaded",A,!1),v.ready()):i.readyState==="complete"&&(i.detachEvent("onreadystatechange",A),v.ready())},O={};v.fn=v.prototype={constructor:v,init:function(e,n,r){var s,o,u,a;if(!e)return this;if(e.nodeType)return this.context=this[0]=e,this.length=1,this;if(typeof e=="string"){e.charAt(0)==="<"&&e.charAt(e.length-1)===">"&&e.length>=3?s=[null,e,null]:s=w.exec(e);if(s&&(s[1]||!n)){if(s[1])return n=n instanceof v?n[0]:n,a=n&&n.nodeType?n.ownerDocument||n:i,e=v.parseHTML(s[1],a,!0),E.test(s[1])&&v.isPlainObject(n)&&this.attr.call(e,n,!0),v.merge(this,e);o=i.getElementById(s[2]);if(o&&o.parentNode){if(o.id!==s[2])return r.find(e);this.length=1,this[0]=o}return this.context=i,this.selector=e,this}return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e)}return v.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),v.makeArray(e,this))},selector:"",jquery:"1.8.3",length:0,size:function(){return this.length},toArray:function(){return l.call(this)},get:function(e){return e==null?this.toArray():e<0?this[this.length+e]:this[e]},pushStack:function(e,t,n){var r=v.merge(this.constructor(),e);return r.prevObject=this,r.context=this.context,t==="find"?r.selector=this.selector+(this.selector?" ":"")+n:t&&(r.selector=this.selector+"."+t+"("+n+")"),r},each:function(e,t){return v.each(this,e,t)},ready:function(e){return v.ready.promise().done(e),this},eq:function(e){return e=+e,e===-1?this.slice(e):this.slice(e,e+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(l.apply(this,arguments),"slice",l.call(arguments).join(","))},map:function(e){return this.pushStack(v.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:[].sort,splice:[].splice},v.fn.init.prototype=v.fn,v.extend=v.fn.extend=function(){var e,n,r,i,s,o,u=arguments[0]||{},a=1,f=arguments.length,l=!1;typeof u=="boolean"&&(l=u,u=arguments[1]||{},a=2),typeof u!="object"&&!v.isFunction(u)&&(u={}),f===a&&(u=this,--a);for(;a0)return;r.resolveWith(i,[v]),v.fn.trigger&&v(i).trigger("ready").off("ready")},isFunction:function(e){return v.type(e)==="function"},isArray:Array.isArray||function(e){return v.type(e)==="array"},isWindow:function(e){return e!=null&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return e==null?String(e):O[h.call(e)]||"object"},isPlainObject:function(e){if(!e||v.type(e)!=="object"||e.nodeType||v.isWindow(e))return!1;try{if(e.constructor&&!p.call(e,"constructor")&&!p.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||p.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw new Error(e)},parseHTML:function(e,t,n){var r;return!e||typeof e!="string"?null:(typeof t=="boolean"&&(n=t,t=0),t=t||i,(r=E.exec(e))?[t.createElement(r[1])]:(r=v.buildFragment([e],t,n?null:[]),v.merge([],(r.cacheable?v.clone(r.fragment):r.fragment).childNodes)))},parseJSON:function(t){if(!t||typeof t!="string")return null;t=v.trim(t);if(e.JSON&&e.JSON.parse)return e.JSON.parse(t);if(S.test(t.replace(T,"@").replace(N,"]").replace(x,"")))return(new Function("return "+t))();v.error("Invalid JSON: "+t)},parseXML:function(n){var r,i;if(!n||typeof n!="string")return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(s){r=t}return(!r||!r.documentElement||r.getElementsByTagName("parsererror").length)&&v.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&g.test(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(C,"ms-").replace(k,L)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,n,r){var i,s=0,o=e.length,u=o===t||v.isFunction(e);if(r){if(u){for(i in e)if(n.apply(e[i],r)===!1)break}else for(;s0&&e[0]&&e[a-1]||a===0||v.isArray(e));if(f)for(;u-1)a.splice(n,1),i&&(n<=o&&o--,n<=u&&u--)}),this},has:function(e){return v.inArray(e,a)>-1},empty:function(){return a=[],this},disable:function(){return a=f=n=t,this},disabled:function(){return!a},lock:function(){return f=t,n||c.disable(),this},locked:function(){return!f},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],a&&(!r||f)&&(i?f.push(t):l(t)),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!r}};return c},v.extend({Deferred:function(e){var t=[["resolve","done",v.Callbacks("once memory"),"resolved"],["reject","fail",v.Callbacks("once memory"),"rejected"],["notify","progress",v.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return v.Deferred(function(n){v.each(t,function(t,r){var s=r[0],o=e[t];i[r[1]](v.isFunction(o)?function(){var e=o.apply(this,arguments);e&&v.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[s+"With"](this===i?n:this,[e])}:n[s])}),e=null}).promise()},promise:function(e){return e!=null?v.extend(e,r):r}},i={};return r.pipe=r.then,v.each(t,function(e,s){var o=s[2],u=s[3];r[s[1]]=o.add,u&&o.add(function(){n=u},t[e^1][2].disable,t[2][2].lock),i[s[0]]=o.fire,i[s[0]+"With"]=o.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=l.call(arguments),r=n.length,i=r!==1||e&&v.isFunction(e.promise)?r:0,s=i===1?e:v.Deferred(),o=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?l.call(arguments):r,n===u?s.notifyWith(t,n):--i||s.resolveWith(t,n)}},u,a,f;if(r>1){u=new Array(r),a=new Array(r),f=new Array(r);for(;t
a",n=p.getElementsByTagName("*"),r=p.getElementsByTagName("a")[0];if(!n||!r||!n.length)return{};s=i.createElement("select"),o=s.appendChild(i.createElement("option")),u=p.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(r.getAttribute("style")),hrefNormalized:r.getAttribute("href")==="/a",opacity:/^0.5/.test(r.style.opacity),cssFloat:!!r.style.cssFloat,checkOn:u.value==="on",optSelected:o.selected,getSetAttribute:p.className!=="t",enctype:!!i.createElement("form").enctype,html5Clone:i.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",boxModel:i.compatMode==="CSS1Compat",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},u.checked=!0,t.noCloneChecked=u.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!o.disabled;try{delete p.test}catch(d){t.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",h=function(){t.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick"),p.detachEvent("onclick",h)),u=i.createElement("input"),u.value="t",u.setAttribute("type","radio"),t.radioValue=u.value==="t",u.setAttribute("checked","checked"),u.setAttribute("name","t"),p.appendChild(u),a=i.createDocumentFragment(),a.appendChild(p.lastChild),t.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,t.appendChecked=u.checked,a.removeChild(u),a.appendChild(p);if(p.attachEvent)for(l in{submit:!0,change:!0,focusin:!0})f="on"+l,c=f in p,c||(p.setAttribute(f,"return;"),c=typeof p[f]=="function"),t[l+"Bubbles"]=c;return v(function(){var n,r,s,o,u="padding:0;margin:0;border:0;display:block;overflow:hidden;",a=i.getElementsByTagName("body")[0];if(!a)return;n=i.createElement("div"),n.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px",a.insertBefore(n,a.firstChild),r=i.createElement("div"),n.appendChild(r),r.innerHTML="
t
",s=r.getElementsByTagName("td"),s[0].style.cssText="padding:0;margin:0;border:0;display:none",c=s[0].offsetHeight===0,s[0].style.display="",s[1].style.display="none",t.reliableHiddenOffsets=c&&s[0].offsetHeight===0,r.innerHTML="",r.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",t.boxSizing=r.offsetWidth===4,t.doesNotIncludeMarginInBodyOffset=a.offsetTop!==1,e.getComputedStyle&&(t.pixelPosition=(e.getComputedStyle(r,null)||{}).top!=="1%",t.boxSizingReliable=(e.getComputedStyle(r,null)||{width:"4px"}).width==="4px",o=i.createElement("div"),o.style.cssText=r.style.cssText=u,o.style.marginRight=o.style.width="0",r.style.width="1px",r.appendChild(o),t.reliableMarginRight=!parseFloat((e.getComputedStyle(o,null)||{}).marginRight)),typeof r.style.zoom!="undefined"&&(r.innerHTML="",r.style.cssText=u+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=r.offsetWidth===3,r.style.display="block",r.style.overflow="visible",r.innerHTML="
",r.firstChild.style.width="5px",t.shrinkWrapBlocks=r.offsetWidth!==3,n.style.zoom=1),a.removeChild(n),n=r=s=o=null}),a.removeChild(p),n=r=s=o=u=a=p=null,t}();var D=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;v.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(v.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?v.cache[e[v.expando]]:e[v.expando],!!e&&!B(e)},data:function(e,n,r,i){if(!v.acceptData(e))return;var s,o,u=v.expando,a=typeof n=="string",f=e.nodeType,l=f?v.cache:e,c=f?e[u]:e[u]&&u;if((!c||!l[c]||!i&&!l[c].data)&&a&&r===t)return;c||(f?e[u]=c=v.deletedIds.pop()||v.guid++:c=u),l[c]||(l[c]={},f||(l[c].toJSON=v.noop));if(typeof n=="object"||typeof n=="function")i?l[c]=v.extend(l[c],n):l[c].data=v.extend(l[c].data,n);return s=l[c],i||(s.data||(s.data={}),s=s.data),r!==t&&(s[v.camelCase(n)]=r),a?(o=s[n],o==null&&(o=s[v.camelCase(n)])):o=s,o},removeData:function(e,t,n){if(!v.acceptData(e))return;var r,i,s,o=e.nodeType,u=o?v.cache:e,a=o?e[v.expando]:v.expando;if(!u[a])return;if(t){r=n?u[a]:u[a].data;if(r){v.isArray(t)||(t in r?t=[t]:(t=v.camelCase(t),t in r?t=[t]:t=t.split(" ")));for(i=0,s=t.length;i1,null,!1))},removeData:function(e){return this.each(function(){v.removeData(this,e)})}}),v.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=v._data(e,t),n&&(!r||v.isArray(n)?r=v._data(e,t,v.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=v.queue(e,t),r=n.length,i=n.shift(),s=v._queueHooks(e,t),o=function(){v.dequeue(e,t)};i==="inprogress"&&(i=n.shift(),r--),i&&(t==="fx"&&n.unshift("inprogress"),delete s.stop,i.call(e,o,s)),!r&&s&&s.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return v._data(e,n)||v._data(e,n,{empty:v.Callbacks("once memory").add(function(){v.removeData(e,t+"queue",!0),v.removeData(e,n,!0)})})}}),v.fn.extend({queue:function(e,n){var r=2;return typeof e!="string"&&(n=e,e="fx",r--),arguments.length1)},removeAttr:function(e){return this.each(function(){v.removeAttr(this,e)})},prop:function(e,t){return v.access(this,v.prop,e,t,arguments.length>1)},removeProp:function(e){return e=v.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,s,o,u;if(v.isFunction(e))return this.each(function(t){v(this).addClass(e.call(this,t,this.className))});if(e&&typeof e=="string"){t=e.split(y);for(n=0,r=this.length;n=0)r=r.replace(" "+n[s]+" "," ");i.className=e?v.trim(r):""}}}return this},toggleClass:function(e,t){var n=typeof e,r=typeof t=="boolean";return v.isFunction(e)?this.each(function(n){v(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if(n==="string"){var i,s=0,o=v(this),u=t,a=e.split(y);while(i=a[s++])u=r?u:!o.hasClass(i),o[u?"addClass":"removeClass"](i)}else if(n==="undefined"||n==="boolean")this.className&&v._data(this,"__className__",this.className),this.className=this.className||e===!1?"":v._data(this,"__className__")||""})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;n=0)return!0;return!1},val:function(e){var n,r,i,s=this[0];if(!arguments.length){if(s)return n=v.valHooks[s.type]||v.valHooks[s.nodeName.toLowerCase()],n&&"get"in n&&(r=n.get(s,"value"))!==t?r:(r=s.value,typeof r=="string"?r.replace(R,""):r==null?"":r);return}return i=v.isFunction(e),this.each(function(r){var s,o=v(this);if(this.nodeType!==1)return;i?s=e.call(this,r,o.val()):s=e,s==null?s="":typeof s=="number"?s+="":v.isArray(s)&&(s=v.map(s,function(e){return e==null?"":e+""})),n=v.valHooks[this.type]||v.valHooks[this.nodeName.toLowerCase()];if(!n||!("set"in n)||n.set(this,s,"value")===t)this.value=s})}}),v.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,s=e.type==="select-one"||i<0,o=s?null:[],u=s?i+1:r.length,a=i<0?u:s?i:0;for(;a=0}),n.length||(e.selectedIndex=-1),n}}},attrFn:{},attr:function(e,n,r,i){var s,o,u,a=e.nodeType;if(!e||a===3||a===8||a===2)return;if(i&&v.isFunction(v.fn[n]))return v(e)[n](r);if(typeof e.getAttribute=="undefined")return v.prop(e,n,r);u=a!==1||!v.isXMLDoc(e),u&&(n=n.toLowerCase(),o=v.attrHooks[n]||(X.test(n)?F:j));if(r!==t){if(r===null){v.removeAttr(e,n);return}return o&&"set"in o&&u&&(s=o.set(e,r,n))!==t?s:(e.setAttribute(n,r+""),r)}return o&&"get"in o&&u&&(s=o.get(e,n))!==null?s:(s=e.getAttribute(n),s===null?t:s)},removeAttr:function(e,t){var n,r,i,s,o=0;if(t&&e.nodeType===1){r=t.split(y);for(;o=0}})});var $=/^(?:textarea|input|select)$/i,J=/^([^\.]*|)(?:\.(.+)|)$/,K=/(?:^|\s)hover(\.\S+|)\b/,Q=/^key/,G=/^(?:mouse|contextmenu)|click/,Y=/^(?:focusinfocus|focusoutblur)$/,Z=function(e){return v.event.special.hover?e:e.replace(K,"mouseenter$1 mouseleave$1")};v.event={add:function(e,n,r,i,s){var o,u,a,f,l,c,h,p,d,m,g;if(e.nodeType===3||e.nodeType===8||!n||!r||!(o=v._data(e)))return;r.handler&&(d=r,r=d.handler,s=d.selector),r.guid||(r.guid=v.guid++),a=o.events,a||(o.events=a={}),u=o.handle,u||(o.handle=u=function(e){return typeof v=="undefined"||!!e&&v.event.triggered===e.type?t:v.event.dispatch.apply(u.elem,arguments)},u.elem=e),n=v.trim(Z(n)).split(" ");for(f=0;f=0&&(y=y.slice(0,-1),a=!0),y.indexOf(".")>=0&&(b=y.split("."),y=b.shift(),b.sort());if((!s||v.event.customEvent[y])&&!v.event.global[y])return;n=typeof n=="object"?n[v.expando]?n:new v.Event(y,n):new v.Event(y),n.type=y,n.isTrigger=!0,n.exclusive=a,n.namespace=b.join("."),n.namespace_re=n.namespace?new RegExp("(^|\\.)"+b.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,h=y.indexOf(":")<0?"on"+y:"";if(!s){u=v.cache;for(f in u)u[f].events&&u[f].events[y]&&v.event.trigger(n,r,u[f].handle.elem,!0);return}n.result=t,n.target||(n.target=s),r=r!=null?v.makeArray(r):[],r.unshift(n),p=v.event.special[y]||{};if(p.trigger&&p.trigger.apply(s,r)===!1)return;m=[[s,p.bindType||y]];if(!o&&!p.noBubble&&!v.isWindow(s)){g=p.delegateType||y,l=Y.test(g+y)?s:s.parentNode;for(c=s;l;l=l.parentNode)m.push([l,g]),c=l;c===(s.ownerDocument||i)&&m.push([c.defaultView||c.parentWindow||e,g])}for(f=0;f=0:v.find(h,this,null,[s]).length),u[h]&&f.push(c);f.length&&w.push({elem:s,matches:f})}d.length>m&&w.push({elem:this,matches:d.slice(m)});for(r=0;r0?this.on(t,null,e,n):this.trigger(t)},Q.test(t)&&(v.event.fixHooks[t]=v.event.keyHooks),G.test(t)&&(v.event.fixHooks[t]=v.event.mouseHooks)}),function(e,t){function nt(e,t,n,r){n=n||[],t=t||g;var i,s,a,f,l=t.nodeType;if(!e||typeof e!="string")return n;if(l!==1&&l!==9)return[];a=o(t);if(!a&&!r)if(i=R.exec(e))if(f=i[1]){if(l===9){s=t.getElementById(f);if(!s||!s.parentNode)return n;if(s.id===f)return n.push(s),n}else if(t.ownerDocument&&(s=t.ownerDocument.getElementById(f))&&u(t,s)&&s.id===f)return n.push(s),n}else{if(i[2])return S.apply(n,x.call(t.getElementsByTagName(e),0)),n;if((f=i[3])&&Z&&t.getElementsByClassName)return S.apply(n,x.call(t.getElementsByClassName(f),0)),n}return vt(e.replace(j,"$1"),t,n,r,a)}function rt(e){return function(t){var n=t.nodeName.toLowerCase();return n==="input"&&t.type===e}}function it(e){return function(t){var n=t.nodeName.toLowerCase();return(n==="input"||n==="button")&&t.type===e}}function st(e){return N(function(t){return t=+t,N(function(n,r){var i,s=e([],n.length,t),o=s.length;while(o--)n[i=s[o]]&&(n[i]=!(r[i]=n[i]))})})}function ot(e,t,n){if(e===t)return n;var r=e.nextSibling;while(r){if(r===t)return-1;r=r.nextSibling}return 1}function ut(e,t){var n,r,s,o,u,a,f,l=L[d][e+" "];if(l)return t?0:l.slice(0);u=e,a=[],f=i.preFilter;while(u){if(!n||(r=F.exec(u)))r&&(u=u.slice(r[0].length)||u),a.push(s=[]);n=!1;if(r=I.exec(u))s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=r[0].replace(j," ");for(o in i.filter)(r=J[o].exec(u))&&(!f[o]||(r=f[o](r)))&&(s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=o,n.matches=r);if(!n)break}return t?u.length:u?nt.error(e):L(e,a).slice(0)}function at(e,t,r){var i=t.dir,s=r&&t.dir==="parentNode",o=w++;return t.first?function(t,n,r){while(t=t[i])if(s||t.nodeType===1)return e(t,n,r)}:function(t,r,u){if(!u){var a,f=b+" "+o+" ",l=f+n;while(t=t[i])if(s||t.nodeType===1){if((a=t[d])===l)return t.sizset;if(typeof a=="string"&&a.indexOf(f)===0){if(t.sizset)return t}else{t[d]=l;if(e(t,r,u))return t.sizset=!0,t;t.sizset=!1}}}else while(t=t[i])if(s||t.nodeType===1)if(e(t,r,u))return t}}function ft(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function lt(e,t,n,r,i){var s,o=[],u=0,a=e.length,f=t!=null;for(;u-1&&(s[f]=!(o[f]=c))}}else g=lt(g===o?g.splice(d,g.length):g),i?i(null,o,g,a):S.apply(o,g)})}function ht(e){var t,n,r,s=e.length,o=i.relative[e[0].type],u=o||i.relative[" "],a=o?1:0,f=at(function(e){return e===t},u,!0),l=at(function(e){return T.call(t,e)>-1},u,!0),h=[function(e,n,r){return!o&&(r||n!==c)||((t=n).nodeType?f(e,n,r):l(e,n,r))}];for(;a1&&ft(h),a>1&&e.slice(0,a-1).join("").replace(j,"$1"),n,a0,s=e.length>0,o=function(u,a,f,l,h){var p,d,v,m=[],y=0,w="0",x=u&&[],T=h!=null,N=c,C=u||s&&i.find.TAG("*",h&&a.parentNode||a),k=b+=N==null?1:Math.E;T&&(c=a!==g&&a,n=o.el);for(;(p=C[w])!=null;w++){if(s&&p){for(d=0;v=e[d];d++)if(v(p,a,f)){l.push(p);break}T&&(b=k,n=++o.el)}r&&((p=!v&&p)&&y--,u&&x.push(p))}y+=w;if(r&&w!==y){for(d=0;v=t[d];d++)v(x,m,a,f);if(u){if(y>0)while(w--)!x[w]&&!m[w]&&(m[w]=E.call(l));m=lt(m)}S.apply(l,m),T&&!u&&m.length>0&&y+t.length>1&&nt.uniqueSort(l)}return T&&(b=k,c=N),x};return o.el=0,r?N(o):o}function dt(e,t,n){var r=0,i=t.length;for(;r2&&(f=u[0]).type==="ID"&&t.nodeType===9&&!s&&i.relative[u[1].type]){t=i.find.ID(f.matches[0].replace($,""),t,s)[0];if(!t)return n;e=e.slice(u.shift().length)}for(o=J.POS.test(e)?-1:u.length-1;o>=0;o--){f=u[o];if(i.relative[l=f.type])break;if(c=i.find[l])if(r=c(f.matches[0].replace($,""),z.test(u[0].type)&&t.parentNode||t,s)){u.splice(o,1),e=r.length&&u.join("");if(!e)return S.apply(n,x.call(r,0)),n;break}}}return a(e,h)(r,t,s,n,z.test(e)),n}function mt(){}var n,r,i,s,o,u,a,f,l,c,h=!0,p="undefined",d=("sizcache"+Math.random()).replace(".",""),m=String,g=e.document,y=g.documentElement,b=0,w=0,E=[].pop,S=[].push,x=[].slice,T=[].indexOf||function(e){var t=0,n=this.length;for(;ti.cacheLength&&delete e[t.shift()],e[n+" "]=r},e)},k=C(),L=C(),A=C(),O="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",_=M.replace("w","w#"),D="([*^$|!~]?=)",P="\\["+O+"*("+M+")"+O+"*(?:"+D+O+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+_+")|)|)"+O+"*\\]",H=":("+M+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:"+P+")|[^:]|\\\\.)*|.*))\\)|)",B=":(even|odd|eq|gt|lt|nth|first|last)(?:\\("+O+"*((?:-\\d)?\\d*)"+O+"*\\)|)(?=[^-]|$)",j=new RegExp("^"+O+"+|((?:^|[^\\\\])(?:\\\\.)*)"+O+"+$","g"),F=new RegExp("^"+O+"*,"+O+"*"),I=new RegExp("^"+O+"*([\\x20\\t\\r\\n\\f>+~])"+O+"*"),q=new RegExp(H),R=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,U=/^:not/,z=/[\x20\t\r\n\f]*[+~]/,W=/:not\($/,X=/h\d/i,V=/input|select|textarea|button/i,$=/\\(?!\\)/g,J={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),NAME:new RegExp("^\\[name=['\"]?("+M+")['\"]?\\]"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+H),POS:new RegExp(B,"i"),CHILD:new RegExp("^:(only|nth|first|last)-child(?:\\("+O+"*(even|odd|(([+-]|)(\\d*)n|)"+O+"*(?:([+-]|)"+O+"*(\\d+)|))"+O+"*\\)|)","i"),needsContext:new RegExp("^"+O+"*[>+~]|"+B,"i")},K=function(e){var t=g.createElement("div");try{return e(t)}catch(n){return!1}finally{t=null}},Q=K(function(e){return e.appendChild(g.createComment("")),!e.getElementsByTagName("*").length}),G=K(function(e){return e.innerHTML="",e.firstChild&&typeof e.firstChild.getAttribute!==p&&e.firstChild.getAttribute("href")==="#"}),Y=K(function(e){e.innerHTML="";var t=typeof e.lastChild.getAttribute("multiple");return t!=="boolean"&&t!=="string"}),Z=K(function(e){return e.innerHTML="",!e.getElementsByClassName||!e.getElementsByClassName("e").length?!1:(e.lastChild.className="e",e.getElementsByClassName("e").length===2)}),et=K(function(e){e.id=d+0,e.innerHTML="
",y.insertBefore(e,y.firstChild);var t=g.getElementsByName&&g.getElementsByName(d).length===2+g.getElementsByName(d+0).length;return r=!g.getElementById(d),y.removeChild(e),t});try{x.call(y.childNodes,0)[0].nodeType}catch(tt){x=function(e){var t,n=[];for(;t=this[e];e++)n.push(t);return n}}nt.matches=function(e,t){return nt(e,null,null,t)},nt.matchesSelector=function(e,t){return nt(t,null,null,[e]).length>0},s=nt.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(i===1||i===9||i===11){if(typeof e.textContent=="string")return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=s(e)}else if(i===3||i===4)return e.nodeValue}else for(;t=e[r];r++)n+=s(t);return n},o=nt.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?t.nodeName!=="HTML":!1},u=nt.contains=y.contains?function(e,t){var n=e.nodeType===9?e.documentElement:e,r=t&&t.parentNode;return e===r||!!(r&&r.nodeType===1&&n.contains&&n.contains(r))}:y.compareDocumentPosition?function(e,t){return t&&!!(e.compareDocumentPosition(t)&16)}:function(e,t){while(t=t.parentNode)if(t===e)return!0;return!1},nt.attr=function(e,t){var n,r=o(e);return r||(t=t.toLowerCase()),(n=i.attrHandle[t])?n(e):r||Y?e.getAttribute(t):(n=e.getAttributeNode(t),n?typeof e[t]=="boolean"?e[t]?t:null:n.specified?n.value:null:null)},i=nt.selectors={cacheLength:50,createPseudo:N,match:J,attrHandle:G?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},find:{ID:r?function(e,t,n){if(typeof t.getElementById!==p&&!n){var r=t.getElementById(e);return r&&r.parentNode?[r]:[]}}:function(e,n,r){if(typeof n.getElementById!==p&&!r){var i=n.getElementById(e);return i?i.id===e||typeof i.getAttributeNode!==p&&i.getAttributeNode("id").value===e?[i]:t:[]}},TAG:Q?function(e,t){if(typeof t.getElementsByTagName!==p)return t.getElementsByTagName(e)}:function(e,t){var n=t.getElementsByTagName(e);if(e==="*"){var r,i=[],s=0;for(;r=n[s];s++)r.nodeType===1&&i.push(r);return i}return n},NAME:et&&function(e,t){if(typeof t.getElementsByName!==p)return t.getElementsByName(name)},CLASS:Z&&function(e,t,n){if(typeof t.getElementsByClassName!==p&&!n)return t.getElementsByClassName(e)}},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace($,""),e[3]=(e[4]||e[5]||"").replace($,""),e[2]==="~="&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),e[1]==="nth"?(e[2]||nt.error(e[0]),e[3]=+(e[3]?e[4]+(e[5]||1):2*(e[2]==="even"||e[2]==="odd")),e[4]=+(e[6]+e[7]||e[2]==="odd")):e[2]&&nt.error(e[0]),e},PSEUDO:function(e){var t,n;if(J.CHILD.test(e[0]))return null;if(e[3])e[2]=e[3];else if(t=e[4])q.test(t)&&(n=ut(t,!0))&&(n=t.indexOf(")",t.length-n)-t.length)&&(t=t.slice(0,n),e[0]=e[0].slice(0,n)),e[2]=t;return e.slice(0,3)}},filter:{ID:r?function(e){return e=e.replace($,""),function(t){return t.getAttribute("id")===e}}:function(e){return e=e.replace($,""),function(t){var n=typeof t.getAttributeNode!==p&&t.getAttributeNode("id");return n&&n.value===e}},TAG:function(e){return e==="*"?function(){return!0}:(e=e.replace($,"").toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=k[d][e+" "];return t||(t=new RegExp("(^|"+O+")"+e+"("+O+"|$)"))&&k(e,function(e){return t.test(e.className||typeof e.getAttribute!==p&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r,i){var s=nt.attr(r,e);return s==null?t==="!=":t?(s+="",t==="="?s===n:t==="!="?s!==n:t==="^="?n&&s.indexOf(n)===0:t==="*="?n&&s.indexOf(n)>-1:t==="$="?n&&s.substr(s.length-n.length)===n:t==="~="?(" "+s+" ").indexOf(n)>-1:t==="|="?s===n||s.substr(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r){return e==="nth"?function(e){var t,i,s=e.parentNode;if(n===1&&r===0)return!0;if(s){i=0;for(t=s.firstChild;t;t=t.nextSibling)if(t.nodeType===1){i++;if(e===t)break}}return i-=r,i===n||i%n===0&&i/n>=0}:function(t){var n=t;switch(e){case"only":case"first":while(n=n.previousSibling)if(n.nodeType===1)return!1;if(e==="first")return!0;n=t;case"last":while(n=n.nextSibling)if(n.nodeType===1)return!1;return!0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||nt.error("unsupported pseudo: "+e);return r[d]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?N(function(e,n){var i,s=r(e,t),o=s.length;while(o--)i=T.call(e,s[o]),e[i]=!(n[i]=s[o])}):function(e){return r(e,0,n)}):r}},pseudos:{not:N(function(e){var t=[],n=[],r=a(e.replace(j,"$1"));return r[d]?N(function(e,t,n,i){var s,o=r(e,null,i,[]),u=e.length;while(u--)if(s=o[u])e[u]=!(t[u]=s)}):function(e,i,s){return t[0]=e,r(t,null,s,n),!n.pop()}}),has:N(function(e){return function(t){return nt(e,t).length>0}}),contains:N(function(e){return function(t){return(t.textContent||t.innerText||s(t)).indexOf(e)>-1}}),enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&!!e.checked||t==="option"&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},parent:function(e){return!i.pseudos.empty(e)},empty:function(e){var t;e=e.firstChild;while(e){if(e.nodeName>"@"||(t=e.nodeType)===3||t===4)return!1;e=e.nextSibling}return!0},header:function(e){return X.test(e.nodeName)},text:function(e){var t,n;return e.nodeName.toLowerCase()==="input"&&(t=e.type)==="text"&&((n=e.getAttribute("type"))==null||n.toLowerCase()===t)},radio:rt("radio"),checkbox:rt("checkbox"),file:rt("file"),password:rt("password"),image:rt("image"),submit:it("submit"),reset:it("reset"),button:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&e.type==="button"||t==="button"},input:function(e){return V.test(e.nodeName)},focus:function(e){var t=e.ownerDocument;return e===t.activeElement&&(!t.hasFocus||t.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},active:function(e){return e===e.ownerDocument.activeElement},first:st(function(){return[0]}),last:st(function(e,t){return[t-1]}),eq:st(function(e,t,n){return[n<0?n+t:n]}),even:st(function(e,t){for(var n=0;n=0;)e.push(r);return e}),gt:st(function(e,t,n){for(var r=n<0?n+t:n;++r",e.querySelectorAll("[selected]").length||i.push("\\["+O+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||i.push(":checked")}),K(function(e){e.innerHTML="

",e.querySelectorAll("[test^='']").length&&i.push("[*^$]="+O+"*(?:\"\"|'')"),e.innerHTML="",e.querySelectorAll(":enabled").length||i.push(":enabled",":disabled")}),i=new RegExp(i.join("|")),vt=function(e,r,s,o,u){if(!o&&!u&&!i.test(e)){var a,f,l=!0,c=d,h=r,p=r.nodeType===9&&e;if(r.nodeType===1&&r.nodeName.toLowerCase()!=="object"){a=ut(e),(l=r.getAttribute("id"))?c=l.replace(n,"\\$&"):r.setAttribute("id",c),c="[id='"+c+"'] ",f=a.length;while(f--)a[f]=c+a[f].join("");h=z.test(e)&&r.parentNode||r,p=a.join(",")}if(p)try{return S.apply(s,x.call(h.querySelectorAll(p),0)),s}catch(v){}finally{l||r.removeAttribute("id")}}return t(e,r,s,o,u)},u&&(K(function(t){e=u.call(t,"div");try{u.call(t,"[test!='']:sizzle"),s.push("!=",H)}catch(n){}}),s=new RegExp(s.join("|")),nt.matchesSelector=function(t,n){n=n.replace(r,"='$1']");if(!o(t)&&!s.test(n)&&!i.test(n))try{var a=u.call(t,n);if(a||e||t.document&&t.document.nodeType!==11)return a}catch(f){}return nt(n,null,null,[t]).length>0})}(),i.pseudos.nth=i.pseudos.eq,i.filters=mt.prototype=i.pseudos,i.setFilters=new mt,nt.attr=v.attr,v.find=nt,v.expr=nt.selectors,v.expr[":"]=v.expr.pseudos,v.unique=nt.uniqueSort,v.text=nt.getText,v.isXMLDoc=nt.isXML,v.contains=nt.contains}(e);var nt=/Until$/,rt=/^(?:parents|prev(?:Until|All))/,it=/^.[^:#\[\.,]*$/,st=v.expr.match.needsContext,ot={children:!0,contents:!0,next:!0,prev:!0};v.fn.extend({find:function(e){var t,n,r,i,s,o,u=this;if(typeof e!="string")return v(e).filter(function(){for(t=0,n=u.length;t0)for(i=r;i=0:v.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){var n,r=0,i=this.length,s=[],o=st.test(e)||typeof e!="string"?v(e,t||this.context):0;for(;r-1:v.find.matchesSelector(n,e)){s.push(n);break}n=n.parentNode}}return s=s.length>1?v.unique(s):s,this.pushStack(s,"closest",e)},index:function(e){return e?typeof e=="string"?v.inArray(this[0],v(e)):v.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.prevAll().length:-1},add:function(e,t){var n=typeof e=="string"?v(e,t):v.makeArray(e&&e.nodeType?[e]:e),r=v.merge(this.get(),n);return this.pushStack(ut(n[0])||ut(r[0])?r:v.unique(r))},addBack:function(e){return this.add(e==null?this.prevObject:this.prevObject.filter(e))}}),v.fn.andSelf=v.fn.addBack,v.each({parent:function(e){var t=e.parentNode;return t&&t.nodeType!==11?t:null},parents:function(e){return v.dir(e,"parentNode")},parentsUntil:function(e,t,n){return v.dir(e,"parentNode",n)},next:function(e){return at(e,"nextSibling")},prev:function(e){return at(e,"previousSibling")},nextAll:function(e){return v.dir(e,"nextSibling")},prevAll:function(e){return v.dir(e,"previousSibling")},nextUntil:function(e,t,n){return v.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return v.dir(e,"previousSibling",n)},siblings:function(e){return v.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return v.sibling(e.firstChild)},contents:function(e){return v.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:v.merge([],e.childNodes)}},function(e,t){v.fn[e]=function(n,r){var i=v.map(this,t,n);return nt.test(e)||(r=n),r&&typeof r=="string"&&(i=v.filter(r,i)),i=this.length>1&&!ot[e]?v.unique(i):i,this.length>1&&rt.test(e)&&(i=i.reverse()),this.pushStack(i,e,l.call(arguments).join(","))}}),v.extend({filter:function(e,t,n){return n&&(e=":not("+e+")"),t.length===1?v.find.matchesSelector(t[0],e)?[t[0]]:[]:v.find.matches(e,t)},dir:function(e,n,r){var i=[],s=e[n];while(s&&s.nodeType!==9&&(r===t||s.nodeType!==1||!v(s).is(r)))s.nodeType===1&&i.push(s),s=s[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)e.nodeType===1&&e!==t&&n.push(e);return n}});var ct="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ht=/ jQuery\d+="(?:null|\d+)"/g,pt=/^\s+/,dt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,vt=/<([\w:]+)/,mt=/]","i"),Et=/^(?:checkbox|radio)$/,St=/checked\s*(?:[^=]|=\s*.checked.)/i,xt=/\/(java|ecma)script/i,Tt=/^\s*\s*$/g,Nt={option:[1,""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},Ct=lt(i),kt=Ct.appendChild(i.createElement("div"));Nt.optgroup=Nt.option,Nt.tbody=Nt.tfoot=Nt.colgroup=Nt.caption=Nt.thead,Nt.th=Nt.td,v.support.htmlSerialize||(Nt._default=[1,"X
","
"]),v.fn.extend({text:function(e){return v.access(this,function(e){return e===t?v.text(this):this.empty().append((this[0]&&this[0].ownerDocument||i).createTextNode(e))},null,e,arguments.length)},wrapAll:function(e){if(v.isFunction(e))return this.each(function(t){v(this).wrapAll(e.call(this,t))});if(this[0]){var t=v(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&e.firstChild.nodeType===1)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return v.isFunction(e)?this.each(function(t){v(this).wrapInner(e.call(this,t))}):this.each(function(){var t=v(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=v.isFunction(e);return this.each(function(n){v(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){v.nodeName(this,"body")||v(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.insertBefore(e,this.firstChild)})},before:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(e,this),"before",this.selector)}},after:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this.nextSibling)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(this,e),"after",this.selector)}},remove:function(e,t){var n,r=0;for(;(n=this[r])!=null;r++)if(!e||v.filter(e,[n]).length)!t&&n.nodeType===1&&(v.cleanData(n.getElementsByTagName("*")),v.cleanData([n])),n.parentNode&&n.parentNode.removeChild(n);return this},empty:function(){var e,t=0;for(;(e=this[t])!=null;t++){e.nodeType===1&&v.cleanData(e.getElementsByTagName("*"));while(e.firstChild)e.removeChild(e.firstChild)}return this},clone:function(e,t){return e=e==null?!1:e,t=t==null?e:t,this.map(function(){return v.clone(this,e,t)})},html:function(e){return v.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return n.nodeType===1?n.innerHTML.replace(ht,""):t;if(typeof e=="string"&&!yt.test(e)&&(v.support.htmlSerialize||!wt.test(e))&&(v.support.leadingWhitespace||!pt.test(e))&&!Nt[(vt.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(dt,"<$1>");try{for(;r1&&typeof f=="string"&&St.test(f))return this.each(function(){v(this).domManip(e,n,r)});if(v.isFunction(f))return this.each(function(i){var s=v(this);e[0]=f.call(this,i,n?s.html():t),s.domManip(e,n,r)});if(this[0]){i=v.buildFragment(e,this,l),o=i.fragment,s=o.firstChild,o.childNodes.length===1&&(o=s);if(s){n=n&&v.nodeName(s,"tr");for(u=i.cacheable||c-1;a0?this.clone(!0):this).get(),v(o[i])[t](r),s=s.concat(r);return this.pushStack(s,e,o.selector)}}),v.extend({clone:function(e,t,n){var r,i,s,o;v.support.html5Clone||v.isXMLDoc(e)||!wt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(kt.innerHTML=e.outerHTML,kt.removeChild(o=kt.firstChild));if((!v.support.noCloneEvent||!v.support.noCloneChecked)&&(e.nodeType===1||e.nodeType===11)&&!v.isXMLDoc(e)){Ot(e,o),r=Mt(e),i=Mt(o);for(s=0;r[s];++s)i[s]&&Ot(r[s],i[s])}if(t){At(e,o);if(n){r=Mt(e),i=Mt(o);for(s=0;r[s];++s)At(r[s],i[s])}}return r=i=null,o},clean:function(e,t,n,r){var s,o,u,a,f,l,c,h,p,d,m,g,y=t===i&&Ct,b=[];if(!t||typeof t.createDocumentFragment=="undefined")t=i;for(s=0;(u=e[s])!=null;s++){typeof u=="number"&&(u+="");if(!u)continue;if(typeof u=="string")if(!gt.test(u))u=t.createTextNode(u);else{y=y||lt(t),c=t.createElement("div"),y.appendChild(c),u=u.replace(dt,"<$1>"),a=(vt.exec(u)||["",""])[1].toLowerCase(),f=Nt[a]||Nt._default,l=f[0],c.innerHTML=f[1]+u+f[2];while(l--)c=c.lastChild;if(!v.support.tbody){h=mt.test(u),p=a==="table"&&!h?c.firstChild&&c.firstChild.childNodes:f[1]===""&&!h?c.childNodes:[];for(o=p.length-1;o>=0;--o)v.nodeName(p[o],"tbody")&&!p[o].childNodes.length&&p[o].parentNode.removeChild(p[o])}!v.support.leadingWhitespace&&pt.test(u)&&c.insertBefore(t.createTextNode(pt.exec(u)[0]),c.firstChild),u=c.childNodes,c.parentNode.removeChild(c)}u.nodeType?b.push(u):v.merge(b,u)}c&&(u=c=y=null);if(!v.support.appendChecked)for(s=0;(u=b[s])!=null;s++)v.nodeName(u,"input")?_t(u):typeof u.getElementsByTagName!="undefined"&&v.grep(u.getElementsByTagName("input"),_t);if(n){m=function(e){if(!e.type||xt.test(e.type))return r?r.push(e.parentNode?e.parentNode.removeChild(e):e):n.appendChild(e)};for(s=0;(u=b[s])!=null;s++)if(!v.nodeName(u,"script")||!m(u))n.appendChild(u),typeof u.getElementsByTagName!="undefined"&&(g=v.grep(v.merge([],u.getElementsByTagName("script")),m),b.splice.apply(b,[s+1,0].concat(g)),s+=g.length)}return b},cleanData:function(e,t){var n,r,i,s,o=0,u=v.expando,a=v.cache,f=v.support.deleteExpando,l=v.event.special;for(;(i=e[o])!=null;o++)if(t||v.acceptData(i)){r=i[u],n=r&&a[r];if(n){if(n.events)for(s in n.events)l[s]?v.event.remove(i,s):v.removeEvent(i,s,n.handle);a[r]&&(delete a[r],f?delete i[u]:i.removeAttribute?i.removeAttribute(u):i[u]=null,v.deletedIds.push(r))}}}}),function(){var e,t;v.uaMatch=function(e){e=e.toLowerCase();var t=/(chrome)[ \/]([\w.]+)/.exec(e)||/(webkit)[ \/]([\w.]+)/.exec(e)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(e)||/(msie) ([\w.]+)/.exec(e)||e.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(e)||[];return{browser:t[1]||"",version:t[2]||"0"}},e=v.uaMatch(o.userAgent),t={},e.browser&&(t[e.browser]=!0,t.version=e.version),t.chrome?t.webkit=!0:t.webkit&&(t.safari=!0),v.browser=t,v.sub=function(){function e(t,n){return new e.fn.init(t,n)}v.extend(!0,e,this),e.superclass=this,e.fn=e.prototype=this(),e.fn.constructor=e,e.sub=this.sub,e.fn.init=function(r,i){return i&&i instanceof v&&!(i instanceof e)&&(i=e(i)),v.fn.init.call(this,r,i,t)},e.fn.init.prototype=e.fn;var t=e(i);return e}}();var Dt,Pt,Ht,Bt=/alpha\([^)]*\)/i,jt=/opacity=([^)]*)/,Ft=/^(top|right|bottom|left)$/,It=/^(none|table(?!-c[ea]).+)/,qt=/^margin/,Rt=new RegExp("^("+m+")(.*)$","i"),Ut=new RegExp("^("+m+")(?!px)[a-z%]+$","i"),zt=new RegExp("^([-+])=("+m+")","i"),Wt={BODY:"block"},Xt={position:"absolute",visibility:"hidden",display:"block"},Vt={letterSpacing:0,fontWeight:400},$t=["Top","Right","Bottom","Left"],Jt=["Webkit","O","Moz","ms"],Kt=v.fn.toggle;v.fn.extend({css:function(e,n){return v.access(this,function(e,n,r){return r!==t?v.style(e,n,r):v.css(e,n)},e,n,arguments.length>1)},show:function(){return Yt(this,!0)},hide:function(){return Yt(this)},toggle:function(e,t){var n=typeof e=="boolean";return v.isFunction(e)&&v.isFunction(t)?Kt.apply(this,arguments):this.each(function(){(n?e:Gt(this))?v(this).show():v(this).hide()})}}),v.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Dt(e,"opacity");return n===""?"1":n}}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":v.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(!e||e.nodeType===3||e.nodeType===8||!e.style)return;var s,o,u,a=v.camelCase(n),f=e.style;n=v.cssProps[a]||(v.cssProps[a]=Qt(f,a)),u=v.cssHooks[n]||v.cssHooks[a];if(r===t)return u&&"get"in u&&(s=u.get(e,!1,i))!==t?s:f[n];o=typeof r,o==="string"&&(s=zt.exec(r))&&(r=(s[1]+1)*s[2]+parseFloat(v.css(e,n)),o="number");if(r==null||o==="number"&&isNaN(r))return;o==="number"&&!v.cssNumber[a]&&(r+="px");if(!u||!("set"in u)||(r=u.set(e,r,i))!==t)try{f[n]=r}catch(l){}},css:function(e,n,r,i){var s,o,u,a=v.camelCase(n);return n=v.cssProps[a]||(v.cssProps[a]=Qt(e.style,a)),u=v.cssHooks[n]||v.cssHooks[a],u&&"get"in u&&(s=u.get(e,!0,i)),s===t&&(s=Dt(e,n)),s==="normal"&&n in Vt&&(s=Vt[n]),r||i!==t?(o=parseFloat(s),r||v.isNumeric(o)?o||0:s):s},swap:function(e,t,n){var r,i,s={};for(i in t)s[i]=e.style[i],e.style[i]=t[i];r=n.call(e);for(i in t)e.style[i]=s[i];return r}}),e.getComputedStyle?Dt=function(t,n){var r,i,s,o,u=e.getComputedStyle(t,null),a=t.style;return u&&(r=u.getPropertyValue(n)||u[n],r===""&&!v.contains(t.ownerDocument,t)&&(r=v.style(t,n)),Ut.test(r)&&qt.test(n)&&(i=a.width,s=a.minWidth,o=a.maxWidth,a.minWidth=a.maxWidth=a.width=r,r=u.width,a.width=i,a.minWidth=s,a.maxWidth=o)),r}:i.documentElement.currentStyle&&(Dt=function(e,t){var n,r,i=e.currentStyle&&e.currentStyle[t],s=e.style;return i==null&&s&&s[t]&&(i=s[t]),Ut.test(i)&&!Ft.test(t)&&(n=s.left,r=e.runtimeStyle&&e.runtimeStyle.left,r&&(e.runtimeStyle.left=e.currentStyle.left),s.left=t==="fontSize"?"1em":i,i=s.pixelLeft+"px",s.left=n,r&&(e.runtimeStyle.left=r)),i===""?"auto":i}),v.each(["height","width"],function(e,t){v.cssHooks[t]={get:function(e,n,r){if(n)return e.offsetWidth===0&&It.test(Dt(e,"display"))?v.swap(e,Xt,function(){return tn(e,t,r)}):tn(e,t,r)},set:function(e,n,r){return Zt(e,n,r?en(e,t,r,v.support.boxSizing&&v.css(e,"boxSizing")==="border-box"):0)}}}),v.support.opacity||(v.cssHooks.opacity={get:function(e,t){return jt.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=v.isNumeric(t)?"alpha(opacity="+t*100+")":"",s=r&&r.filter||n.filter||"";n.zoom=1;if(t>=1&&v.trim(s.replace(Bt,""))===""&&n.removeAttribute){n.removeAttribute("filter");if(r&&!r.filter)return}n.filter=Bt.test(s)?s.replace(Bt,i):s+" "+i}}),v(function(){v.support.reliableMarginRight||(v.cssHooks.marginRight={get:function(e,t){return v.swap(e,{display:"inline-block"},function(){if(t)return Dt(e,"marginRight")})}}),!v.support.pixelPosition&&v.fn.position&&v.each(["top","left"],function(e,t){v.cssHooks[t]={get:function(e,n){if(n){var r=Dt(e,t);return Ut.test(r)?v(e).position()[t]+"px":r}}}})}),v.expr&&v.expr.filters&&(v.expr.filters.hidden=function(e){return e.offsetWidth===0&&e.offsetHeight===0||!v.support.reliableHiddenOffsets&&(e.style&&e.style.display||Dt(e,"display"))==="none"},v.expr.filters.visible=function(e){return!v.expr.filters.hidden(e)}),v.each({margin:"",padding:"",border:"Width"},function(e,t){v.cssHooks[e+t]={expand:function(n){var r,i=typeof n=="string"?n.split(" "):[n],s={};for(r=0;r<4;r++)s[e+$t[r]+t]=i[r]||i[r-2]||i[0];return s}},qt.test(e)||(v.cssHooks[e+t].set=Zt)});var rn=/%20/g,sn=/\[\]$/,on=/\r?\n/g,un=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,an=/^(?:select|textarea)/i;v.fn.extend({serialize:function(){return v.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?v.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||an.test(this.nodeName)||un.test(this.type))}).map(function(e,t){var n=v(this).val();return n==null?null:v.isArray(n)?v.map(n,function(e,n){return{name:t.name,value:e.replace(on,"\r\n")}}):{name:t.name,value:n.replace(on,"\r\n")}}).get()}}),v.param=function(e,n){var r,i=[],s=function(e,t){t=v.isFunction(t)?t():t==null?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};n===t&&(n=v.ajaxSettings&&v.ajaxSettings.traditional);if(v.isArray(e)||e.jquery&&!v.isPlainObject(e))v.each(e,function(){s(this.name,this.value)});else for(r in e)fn(r,e[r],n,s);return i.join("&").replace(rn,"+")};var ln,cn,hn=/#.*$/,pn=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,dn=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,vn=/^(?:GET|HEAD)$/,mn=/^\/\//,gn=/\?/,yn=/)<[^<]*)*<\/script>/gi,bn=/([?&])_=[^&]*/,wn=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,En=v.fn.load,Sn={},xn={},Tn=["*/"]+["*"];try{cn=s.href}catch(Nn){cn=i.createElement("a"),cn.href="",cn=cn.href}ln=wn.exec(cn.toLowerCase())||[],v.fn.load=function(e,n,r){if(typeof e!="string"&&En)return En.apply(this,arguments);if(!this.length)return this;var i,s,o,u=this,a=e.indexOf(" ");return a>=0&&(i=e.slice(a,e.length),e=e.slice(0,a)),v.isFunction(n)?(r=n,n=t):n&&typeof n=="object"&&(s="POST"),v.ajax({url:e,type:s,dataType:"html",data:n,complete:function(e,t){r&&u.each(r,o||[e.responseText,t,e])}}).done(function(e){o=arguments,u.html(i?v("
").append(e.replace(yn,"")).find(i):e)}),this},v.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,t){v.fn[t]=function(e){return this.on(t,e)}}),v.each(["get","post"],function(e,n){v[n]=function(e,r,i,s){return v.isFunction(r)&&(s=s||i,i=r,r=t),v.ajax({type:n,url:e,data:r,success:i,dataType:s})}}),v.extend({getScript:function(e,n){return v.get(e,t,n,"script")},getJSON:function(e,t,n){return v.get(e,t,n,"json")},ajaxSetup:function(e,t){return t?Ln(e,v.ajaxSettings):(t=e,e=v.ajaxSettings),Ln(e,t),e},ajaxSettings:{url:cn,isLocal:dn.test(ln[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":Tn},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":e.String,"text html":!0,"text json":v.parseJSON,"text xml":v.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:Cn(Sn),ajaxTransport:Cn(xn),ajax:function(e,n){function T(e,n,s,a){var l,y,b,w,S,T=n;if(E===2)return;E=2,u&&clearTimeout(u),o=t,i=a||"",x.readyState=e>0?4:0,s&&(w=An(c,x,s));if(e>=200&&e<300||e===304)c.ifModified&&(S=x.getResponseHeader("Last-Modified"),S&&(v.lastModified[r]=S),S=x.getResponseHeader("Etag"),S&&(v.etag[r]=S)),e===304?(T="notmodified",l=!0):(l=On(c,w),T=l.state,y=l.data,b=l.error,l=!b);else{b=T;if(!T||e)T="error",e<0&&(e=0)}x.status=e,x.statusText=(n||T)+"",l?d.resolveWith(h,[y,T,x]):d.rejectWith(h,[x,T,b]),x.statusCode(g),g=t,f&&p.trigger("ajax"+(l?"Success":"Error"),[x,c,l?y:b]),m.fireWith(h,[x,T]),f&&(p.trigger("ajaxComplete",[x,c]),--v.active||v.event.trigger("ajaxStop"))}typeof e=="object"&&(n=e,e=t),n=n||{};var r,i,s,o,u,a,f,l,c=v.ajaxSetup({},n),h=c.context||c,p=h!==c&&(h.nodeType||h instanceof v)?v(h):v.event,d=v.Deferred(),m=v.Callbacks("once memory"),g=c.statusCode||{},b={},w={},E=0,S="canceled",x={readyState:0,setRequestHeader:function(e,t){if(!E){var n=e.toLowerCase();e=w[n]=w[n]||e,b[e]=t}return this},getAllResponseHeaders:function(){return E===2?i:null},getResponseHeader:function(e){var n;if(E===2){if(!s){s={};while(n=pn.exec(i))s[n[1].toLowerCase()]=n[2]}n=s[e.toLowerCase()]}return n===t?null:n},overrideMimeType:function(e){return E||(c.mimeType=e),this},abort:function(e){return e=e||S,o&&o.abort(e),T(0,e),this}};d.promise(x),x.success=x.done,x.error=x.fail,x.complete=m.add,x.statusCode=function(e){if(e){var t;if(E<2)for(t in e)g[t]=[g[t],e[t]];else t=e[x.status],x.always(t)}return this},c.url=((e||c.url)+"").replace(hn,"").replace(mn,ln[1]+"//"),c.dataTypes=v.trim(c.dataType||"*").toLowerCase().split(y),c.crossDomain==null&&(a=wn.exec(c.url.toLowerCase()),c.crossDomain=!(!a||a[1]===ln[1]&&a[2]===ln[2]&&(a[3]||(a[1]==="http:"?80:443))==(ln[3]||(ln[1]==="http:"?80:443)))),c.data&&c.processData&&typeof c.data!="string"&&(c.data=v.param(c.data,c.traditional)),kn(Sn,c,n,x);if(E===2)return x;f=c.global,c.type=c.type.toUpperCase(),c.hasContent=!vn.test(c.type),f&&v.active++===0&&v.event.trigger("ajaxStart");if(!c.hasContent){c.data&&(c.url+=(gn.test(c.url)?"&":"?")+c.data,delete c.data),r=c.url;if(c.cache===!1){var N=v.now(),C=c.url.replace(bn,"$1_="+N);c.url=C+(C===c.url?(gn.test(c.url)?"&":"?")+"_="+N:"")}}(c.data&&c.hasContent&&c.contentType!==!1||n.contentType)&&x.setRequestHeader("Content-Type",c.contentType),c.ifModified&&(r=r||c.url,v.lastModified[r]&&x.setRequestHeader("If-Modified-Since",v.lastModified[r]),v.etag[r]&&x.setRequestHeader("If-None-Match",v.etag[r])),x.setRequestHeader("Accept",c.dataTypes[0]&&c.accepts[c.dataTypes[0]]?c.accepts[c.dataTypes[0]]+(c.dataTypes[0]!=="*"?", "+Tn+"; q=0.01":""):c.accepts["*"]);for(l in c.headers)x.setRequestHeader(l,c.headers[l]);if(!c.beforeSend||c.beforeSend.call(h,x,c)!==!1&&E!==2){S="abort";for(l in{success:1,error:1,complete:1})x[l](c[l]);o=kn(xn,c,n,x);if(!o)T(-1,"No Transport");else{x.readyState=1,f&&p.trigger("ajaxSend",[x,c]),c.async&&c.timeout>0&&(u=setTimeout(function(){x.abort("timeout")},c.timeout));try{E=1,o.send(b,T)}catch(k){if(!(E<2))throw k;T(-1,k)}}return x}return x.abort()},active:0,lastModified:{},etag:{}});var Mn=[],_n=/\?/,Dn=/(=)\?(?=&|$)|\?\?/,Pn=v.now();v.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Mn.pop()||v.expando+"_"+Pn++;return this[e]=!0,e}}),v.ajaxPrefilter("json jsonp",function(n,r,i){var s,o,u,a=n.data,f=n.url,l=n.jsonp!==!1,c=l&&Dn.test(f),h=l&&!c&&typeof a=="string"&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Dn.test(a);if(n.dataTypes[0]==="jsonp"||c||h)return s=n.jsonpCallback=v.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,o=e[s],c?n.url=f.replace(Dn,"$1"+s):h?n.data=a.replace(Dn,"$1"+s):l&&(n.url+=(_n.test(f)?"&":"?")+n.jsonp+"="+s),n.converters["script json"]=function(){return u||v.error(s+" was not called"),u[0]},n.dataTypes[0]="json",e[s]=function(){u=arguments},i.always(function(){e[s]=o,n[s]&&(n.jsonpCallback=r.jsonpCallback,Mn.push(s)),u&&v.isFunction(o)&&o(u[0]),u=o=t}),"script"}),v.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(e){return v.globalEval(e),e}}}),v.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),v.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=i.head||i.getElementsByTagName("head")[0]||i.documentElement;return{send:function(s,o){n=i.createElement("script"),n.async="async",e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,i){if(i||!n.readyState||/loaded|complete/.test(n.readyState))n.onload=n.onreadystatechange=null,r&&n.parentNode&&r.removeChild(n),n=t,i||o(200,"success")},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(0,1)}}}});var Hn,Bn=e.ActiveXObject?function(){for(var e in Hn)Hn[e](0,1)}:!1,jn=0;v.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&Fn()||In()}:Fn,function(e){v.extend(v.support,{ajax:!!e,cors:!!e&&"withCredentials"in e})}(v.ajaxSettings.xhr()),v.support.ajax&&v.ajaxTransport(function(n){if(!n.crossDomain||v.support.cors){var r;return{send:function(i,s){var o,u,a=n.xhr();n.username?a.open(n.type,n.url,n.async,n.username,n.password):a.open(n.type,n.url,n.async);if(n.xhrFields)for(u in n.xhrFields)a[u]=n.xhrFields[u];n.mimeType&&a.overrideMimeType&&a.overrideMimeType(n.mimeType),!n.crossDomain&&!i["X-Requested-With"]&&(i["X-Requested-With"]="XMLHttpRequest");try{for(u in i)a.setRequestHeader(u,i[u])}catch(f){}a.send(n.hasContent&&n.data||null),r=function(e,i){var u,f,l,c,h;try{if(r&&(i||a.readyState===4)){r=t,o&&(a.onreadystatechange=v.noop,Bn&&delete Hn[o]);if(i)a.readyState!==4&&a.abort();else{u=a.status,l=a.getAllResponseHeaders(),c={},h=a.responseXML,h&&h.documentElement&&(c.xml=h);try{c.text=a.responseText}catch(p){}try{f=a.statusText}catch(p){f=""}!u&&n.isLocal&&!n.crossDomain?u=c.text?200:404:u===1223&&(u=204)}}}catch(d){i||s(-1,d)}c&&s(u,f,c,l)},n.async?a.readyState===4?setTimeout(r,0):(o=++jn,Bn&&(Hn||(Hn={},v(e).unload(Bn)),Hn[o]=r),a.onreadystatechange=r):r()},abort:function(){r&&r(0,1)}}}});var qn,Rn,Un=/^(?:toggle|show|hide)$/,zn=new RegExp("^(?:([-+])=|)("+m+")([a-z%]*)$","i"),Wn=/queueHooks$/,Xn=[Gn],Vn={"*":[function(e,t){var n,r,i=this.createTween(e,t),s=zn.exec(t),o=i.cur(),u=+o||0,a=1,f=20;if(s){n=+s[2],r=s[3]||(v.cssNumber[e]?"":"px");if(r!=="px"&&u){u=v.css(i.elem,e,!0)||n||1;do a=a||".5",u/=a,v.style(i.elem,e,u+r);while(a!==(a=i.cur()/o)&&a!==1&&--f)}i.unit=r,i.start=u,i.end=s[1]?u+(s[1]+1)*n:n}return i}]};v.Animation=v.extend(Kn,{tweener:function(e,t){v.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;r-1,f={},l={},c,h;a?(l=i.position(),c=l.top,h=l.left):(c=parseFloat(o)||0,h=parseFloat(u)||0),v.isFunction(t)&&(t=t.call(e,n,s)),t.top!=null&&(f.top=t.top-s.top+c),t.left!=null&&(f.left=t.left-s.left+h),"using"in t?t.using.call(e,f):i.css(f)}},v.fn.extend({position:function(){if(!this[0])return;var e=this[0],t=this.offsetParent(),n=this.offset(),r=er.test(t[0].nodeName)?{top:0,left:0}:t.offset();return n.top-=parseFloat(v.css(e,"marginTop"))||0,n.left-=parseFloat(v.css(e,"marginLeft"))||0,r.top+=parseFloat(v.css(t[0],"borderTopWidth"))||0,r.left+=parseFloat(v.css(t[0],"borderLeftWidth"))||0,{top:n.top-r.top,left:n.left-r.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||i.body;while(e&&!er.test(e.nodeName)&&v.css(e,"position")==="static")e=e.offsetParent;return e||i.body})}}),v.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);v.fn[e]=function(i){return v.access(this,function(e,i,s){var o=tr(e);if(s===t)return o?n in o?o[n]:o.document.documentElement[i]:e[i];o?o.scrollTo(r?v(o).scrollLeft():s,r?s:v(o).scrollTop()):e[i]=s},e,i,arguments.length,null)}}),v.each({Height:"height",Width:"width"},function(e,n){v.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){v.fn[i]=function(i,s){var o=arguments.length&&(r||typeof i!="boolean"),u=r||(i===!0||s===!0?"margin":"border");return v.access(this,function(n,r,i){var s;return v.isWindow(n)?n.document.documentElement["client"+e]:n.nodeType===9?(s=n.documentElement,Math.max(n.body["scroll"+e],s["scroll"+e],n.body["offset"+e],s["offset"+e],s["client"+e])):i===t?v.css(n,r,i,u):v.style(n,r,i,u)},n,o?i:t,o,null)}})}),e.jQuery=e.$=v,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return v})})(window); \ No newline at end of file diff --git a/spec/models/forge_activity_spec.rb b/spec/models/forge_activity_spec.rb new file mode 100644 index 000000000..8e19f2014 --- /dev/null +++ b/spec/models/forge_activity_spec.rb @@ -0,0 +1,5 @@ +require 'spec_helper' + +describe ForgeActivity do + pending "add some examples to (or delete) #{__FILE__}" +end From a2d986f70c73376a00a114130af6a8436cd172f6 Mon Sep 17 00:00:00 2001 From: sw <939547590@qq.com> Date: Wed, 4 Mar 2015 16:55:25 +0800 Subject: [PATCH 34/97] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/layouts/base_projects.html.erb | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/views/layouts/base_projects.html.erb b/app/views/layouts/base_projects.html.erb index fc6713a94..9007e4c3c 100644 --- a/app/views/layouts/base_projects.html.erb +++ b/app/views/layouts/base_projects.html.erb @@ -104,10 +104,9 @@ <% if @project.project_type == 0 && project_score != 0 %> <%= l(:label_project_grade)%> : <%= link_to(project_score, {:controller => 'projects', - :action => 'show_projects_score', - :remote => true, - :id => @project.id - }, :style => "color: #EC6300;")%> + :action => 'show_projects_score', + :remote => true, + :id => @project.id}, :style => "color: #EC6300;")%> <% end %>
From 411d201fc3694b200ca5e931cde945ee6678ce98 Mon Sep 17 00:00:00 2001 From: z9hang Date: Wed, 4 Mar 2015 17:04:07 +0800 Subject: [PATCH 35/97] =?UTF-8?q?=E4=BD=9C=E4=B8=9A=E8=AF=A6=E6=83=85?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E6=B7=BB=E5=8A=A0=E7=95=99=E8=A8=80=E5=88=97?= =?UTF-8?q?=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/mobile/entities/homework.rb | 4 ++++ app/services/homework_service.rb | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/api/mobile/entities/homework.rb b/app/api/mobile/entities/homework.rb index 55883e14e..d4c34ffec 100644 --- a/app/api/mobile/entities/homework.rb +++ b/app/api/mobile/entities/homework.rb @@ -52,6 +52,10 @@ module Mobile homework_expose :created_on homework_expose :deadline + expose :jours,using: Mobile::Entities::Jours do |f, opt| + f[:jours] if f.is_a?(Hash) && f.key?(:jours) + end + expose :homework_for_anonymous_comments,using: Mobile::Entities::HomeworkAttach do |f, opt| f[:homework_for_anonymous_comments] if f.is_a?(Hash) && f.key?(:homework_for_anonymous_comments) end diff --git a/app/services/homework_service.rb b/app/services/homework_service.rb index 6287eeef5..d69617eb5 100644 --- a/app/services/homework_service.rb +++ b/app/services/homework_service.rb @@ -26,8 +26,9 @@ class HomeworkService state = @bid.comment_status #end open_anonymous_evaluation = @bid.open_anonymous_evaluation + jours = @bid.journals_for_messages.where('m_parent_id IS NULL').order('created_on DESC') {:course_name => course.name,:course_id => course.id,:id => @bid.id, :author => @bid.author,:author_real_name =>author, :homework_times => many_times, :homework_name => name, :homework_count => homework_count,:student_questions_count => student_questions_count, - :description => description, :homework_state => state,:open_anonymous_evaluation => open_anonymous_evaluation,:created_on => @bid.created_on,:deadline => @bid.deadline} + :description => description, :homework_state => state,:open_anonymous_evaluation => open_anonymous_evaluation,:created_on => @bid.created_on,:deadline => @bid.deadline,:jours => jours} end # 启动作业匿评前提示信息 From 199ef4ebe689ec593018b49f2df60b20eee20225 Mon Sep 17 00:00:00 2001 From: z9hang Date: Wed, 4 Mar 2015 17:14:09 +0800 Subject: [PATCH 36/97] =?UTF-8?q?=E5=8C=BF=E8=AF=84=E4=BD=9C=E5=93=81?= =?UTF-8?q?=E8=AF=A6=E6=83=85=E5=88=97=E8=A1=A8=E8=A1=A5=E4=B8=8Acur=5Fpag?= =?UTF-8?q?e=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/mobile/entities/anonymous_works_params.rb | 1 + app/services/homework_service.rb | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/api/mobile/entities/anonymous_works_params.rb b/app/api/mobile/entities/anonymous_works_params.rb index 95cf9215d..e6bc8f346 100644 --- a/app/api/mobile/entities/anonymous_works_params.rb +++ b/app/api/mobile/entities/anonymous_works_params.rb @@ -15,6 +15,7 @@ module Mobile anonymous_works_params_expose :m_score anonymous_works_params_expose :is_anonymous_comments anonymous_works_params_expose :cur_type + anonymous_works_params_expose :cur_page expose :jours ,using: Mobile::Entities::Jours do |f, opt| if f.is_a?(Hash) && f.key?(:jours) f[:jours] diff --git a/app/services/homework_service.rb b/app/services/homework_service.rb index d69617eb5..f9be6f79d 100644 --- a/app/services/homework_service.rb +++ b/app/services/homework_service.rb @@ -117,7 +117,7 @@ class HomeworkService @is_anonymous_comments = @bid.comment_status == 1 && !@homework.users.include?(current_user) && @homework.user != current_user && !@is_teacher #判断是不是匿评(开启匿评,当前用户不是作业的创建者或者参与者,不是老师) jours = @homework.journals_for_messages.where("is_comprehensive_evaluation = 3 or is_comprehensive_evaluation is null").order("created_on DESC")#jours留言 is null条件用以兼容历史数据 #@jour = paginateHelper jours,5 #留言 - #@cur_page = params[:cur_page] || 1 + @cur_page = params[:cur_page] || 1 @cur_type = params[:cur_type] || 5 teacher_stars_json_like = stars_to_json_like(@teacher_stars,true,@homework,true) student_stars_json_like = stars_to_json_like(@student_stars,false,@homework,(false || @is_teacher)) @@ -126,7 +126,7 @@ class HomeworkService end [@homework,{:is_teacher => @is_teacher,:m_score => @m_score,:jours => jours,:teacher_stars => teacher_stars_json_like, - :student_stars => student_stars_json_like,:is_anonymous_comments => @is_anonymous_comments,:cur_type => @cur_type}] + :student_stars => student_stars_json_like,:is_anonymous_comments => @is_anonymous_comments,:cur_type => @cur_type,:cur_page => @cur_page}] #name = @homework.name #desc = @homework.description #datetime = @homework.created_at From 7f249d29f41d0a36bcbd4956b7c6f3f0a77eb82d Mon Sep 17 00:00:00 2001 From: sw <939547590@qq.com> Date: Thu, 5 Mar 2015 08:45:32 +0800 Subject: [PATCH 37/97] =?UTF-8?q?=E4=BF=AE=E6=95=B4=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/projects/show.html.erb | 63 ++++++++++++++++++++------------ 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/app/views/projects/show.html.erb b/app/views/projects/show.html.erb index 7a06c57cd..84b3768a2 100644 --- a/app/views/projects/show.html.erb +++ b/app/views/projects/show.html.erb @@ -1,7 +1,7 @@ <% if @events_by_day.size >0 %>

- <% # 暂时隐藏时间的显示%> + <%#= l(:label_date_from_to, :start => format_date(@date_to - @days), :end => format_date(@date_to-1)) %>

@@ -12,7 +12,9 @@ <%= image_tag(url_to_avatar(e.event_author), :class => "avatar") %>
- <%= h(e.project) if @project.nil? || @project.id != e.project.id %> + + <%= h(e.project) if @project.nil? || @project.id != e.project.id %> + <% if @canShowRealName %> <%= link_to_user(e.event_author) if e.respond_to?(:event_author) %> @@ -30,10 +32,18 @@
<%= l :label_activity_time %> - :  <%= format_activity_day(day) %> <%= format_time(e.event_datetime, false) %> + :  + <%= format_activity_day(day) %> + <%= format_time(e.event_datetime, false) %> + <% if e.event_type == "issue" %>
- <%= link_to l(:label_find_all_comments), issue_path(e) %> <%= l(:label_comments_count, :count => e.journals.count) %> + + <%= link_to l(:label_find_all_comments), issue_path(e) %> + + + <%= l(:label_comments_count, :count => e.journals.count) %> +
<% end %>
@@ -48,21 +58,24 @@ <%= image_tag(url_to_avatar(@user), :class => "avatar") %>
- - <% if @canShowRealName %> - (<%= link_to_user(@user, @canShowRealName) %> - ) - <% else %> - <%= link_to_user(@user) %> - <% end %> - <%#= l(:label_new_activity) %> - - <%= l(:label_user_create_project) %> <%= link_to @project.name %> + + <% if @canShowRealName %> + (<%= link_to_user(@user, @canShowRealName) %>) + <% else %> + <%= link_to_user(@user) %> + <% end %> + <%#= l(:label_new_activity) %> + + <%= l(:label_user_create_project) %> + <%= link_to @project.name %> !
- <%= l :label_activity_time %>: <%= format_time(@project.created_on) %> + + <%= l :label_activity_time %>: + <%= format_time(@project.created_on) %> +
@@ -75,20 +88,24 @@
- <% if @canShowRealName %> - (<%= link_to_user(@user, @canShowRealName) %> - ) - <% else %> - <%= link_to_user(@user) %> - <% end %> + <% if @canShowRealName %> + (<%= link_to_user(@user, @canShowRealName) %>) + <% else %> + <%= link_to_user(@user) %> + <% end %> <%#= l(:label_new_activity) %> - <%= l(:label_user_create_project) %> <%= link_to @project.name %> + <%= @user.to_s %> + <%= l(:label_user_create_project) %> + <%= link_to @project.name %> !
- <%= l :label_activity_time %>: <%= format_time(@project.created_on) %> + + <%= l :label_activity_time %>: + <%= format_time(@project.created_on) %> +
From d01aa5f15c4ba445d3394a2922d34fd770405033 Mon Sep 17 00:00:00 2001 From: z9hang Date: Thu, 5 Mar 2015 09:26:13 +0800 Subject: [PATCH 38/97] =?UTF-8?q?=E5=85=B3=E6=B3=A8=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E9=99=90=E5=88=B6=E4=B8=8D=E8=83=BD=E5=85=B3=E6=B3=A8=E8=87=AA?= =?UTF-8?q?=E5=B7=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/services/watches_service.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/services/watches_service.rb b/app/services/watches_service.rb index 2b9bed3cd..2aab7de81 100644 --- a/app/services/watches_service.rb +++ b/app/services/watches_service.rb @@ -1,7 +1,12 @@ +#coding=utf-8 class WatchesService def watch params @current_user = User.find(params[:current_user_id]) + if params[:object_type] == 'user' && params[:current_user_id] == params[:object_id] + raise '不能关注自己!' + end @watchables = find_watchables params + if @watchables.nil? raise '404' end From bcc8abdee9e514878f91a2f6b56b34e7963457a5 Mon Sep 17 00:00:00 2001 From: sw <939547590@qq.com> Date: Thu, 5 Mar 2015 09:27:13 +0800 Subject: [PATCH 39/97] =?UTF-8?q?1=E3=80=81=E5=A2=9E=E5=8A=A0=E7=BB=84?= =?UTF-8?q?=E7=BB=87=E7=9B=B8=E5=85=B3=E6=95=B0=E6=8D=AE=E8=A1=A8=202?= =?UTF-8?q?=E3=80=81=E5=A2=9E=E5=8A=A0=E7=BB=84=E7=BB=87=E5=92=8C=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E7=9A=84=E5=85=B3=E8=81=94=E5=85=B3=E7=B3=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/organization.rb | 5 +++++ app/models/project.rb | 4 +++- db/migrate/20150305011023_create_organizations.rb | 10 ++++++++++ .../20150305011359_add_organization_to_project.rb | 9 +++++++++ db/schema.rb | 10 +++++++++- spec/models/organization_spec.rb | 5 +++++ 6 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 app/models/organization.rb create mode 100644 db/migrate/20150305011023_create_organizations.rb create mode 100644 db/migrate/20150305011359_add_organization_to_project.rb create mode 100644 spec/models/organization_spec.rb diff --git a/app/models/organization.rb b/app/models/organization.rb new file mode 100644 index 000000000..5f52dee98 --- /dev/null +++ b/app/models/organization.rb @@ -0,0 +1,5 @@ +class Organization < ActiveRecord::Base + attr_accessible :logo_link, :name + + has_many :projects +end diff --git a/app/models/project.rb b/app/models/project.rb index df403bb5c..3ac29249f 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -90,7 +90,9 @@ class Project < ActiveRecord::Base :association_foreign_key => 'custom_field_id' has_many :tags, :through => :project_tags, :class_name => 'Tag' - has_many :project_tags, :class_name => 'ProjectTags' + has_many :project_tags, :class_name => 'ProjectTags' + + belongs_to :organization # has_many :journals diff --git a/db/migrate/20150305011023_create_organizations.rb b/db/migrate/20150305011023_create_organizations.rb new file mode 100644 index 000000000..798c526c5 --- /dev/null +++ b/db/migrate/20150305011023_create_organizations.rb @@ -0,0 +1,10 @@ +class CreateOrganizations < ActiveRecord::Migration + def change + create_table :organizations do |t| + t.string :name + t.string :logo_link + + t.timestamps + end + end +end diff --git a/db/migrate/20150305011359_add_organization_to_project.rb b/db/migrate/20150305011359_add_organization_to_project.rb new file mode 100644 index 000000000..4bf8c4c88 --- /dev/null +++ b/db/migrate/20150305011359_add_organization_to_project.rb @@ -0,0 +1,9 @@ +class AddOrganizationToProject < ActiveRecord::Migration + def up + add_column :projects, :organization_id, :integer + end + + def down + remove_column :projects, :organization_id + end +end diff --git a/db/schema.rb b/db/schema.rb index d7a1b18bc..d0bee8db6 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 => 20150128032421) do +ActiveRecord::Schema.define(:version => 20150305011359) do create_table "activities", :force => true do |t| t.integer "act_id", :null => false @@ -802,6 +802,13 @@ ActiveRecord::Schema.define(:version => 20150128032421) do t.integer "project_id" end + create_table "organizations", :force => true do |t| + t.string "name" + t.string "logo_link" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + create_table "poll_answers", :force => true do |t| t.integer "poll_question_id" t.text "answer_text" @@ -926,6 +933,7 @@ ActiveRecord::Schema.define(:version => 20150128032421) do t.integer "user_id" t.integer "dts_test", :default => 0 t.string "enterprise_name" + t.integer "organization_id" end add_index "projects", ["lft"], :name => "index_projects_on_lft" diff --git a/spec/models/organization_spec.rb b/spec/models/organization_spec.rb new file mode 100644 index 000000000..6f6f99fb4 --- /dev/null +++ b/spec/models/organization_spec.rb @@ -0,0 +1,5 @@ +require 'spec_helper' + +describe Organization do + pending "add some examples to (or delete) #{__FILE__}" +end From 04dea372c573f41ed53ab46f24353bb1b9580c0a Mon Sep 17 00:00:00 2001 From: z9hang Date: Thu, 5 Mar 2015 10:09:19 +0800 Subject: [PATCH 40/97] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=84=8F=E8=A7=81?= =?UTF-8?q?=E5=8F=8D=E9=A6=88=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/mobile/apis/comments.rb | 14 ++++++++++++++ app/controllers/forums_controller.rb | 10 ++++++---- app/services/comment_service.rb | 9 +++++++++ 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/app/api/mobile/apis/comments.rb b/app/api/mobile/apis/comments.rb index a7eea735d..7a7f17d8f 100644 --- a/app/api/mobile/apis/comments.rb +++ b/app/api/mobile/apis/comments.rb @@ -72,6 +72,20 @@ module Mobile present :status, 0 end + desc ' 意见反馈' + params do + requires :token, type: String + requires :subject,type: String,desc: '意见' + end + post do + cs_params = { + memo: {:subject => params[:subject],:content => '该贴来自手机App意见反馈'}, + } + cs = CommentService.new + memo = cs.create_feedback cs_params, current_user + raise "commit failed #{memo.errors.full_messages}" if memo.new_record? + present :status, 0 + end end end diff --git a/app/controllers/forums_controller.rb b/app/controllers/forums_controller.rb index 54b8c6305..2f7092d9a 100644 --- a/app/controllers/forums_controller.rb +++ b/app/controllers/forums_controller.rb @@ -15,12 +15,14 @@ class ForumsController < ApplicationController PageLimit = 20 def create_feedback if User.current.logged? - @memo = Memo.new(params[:memo]) - @memo.forum_id = "1" - @memo.author_id = User.current.id + #@memo = Memo.new(params[:memo]) + #@memo.forum_id = "1" + #@memo.author_id = User.current.id #@forum = @memo.forum + cs = CommentService.new + @memo = cs.create_feedback params,User.current respond_to do |format| - if @memo.save + if !@memo.new_record? format.html { redirect_to forum_path(@memo.forum) } else sort_init 'updated_at', 'desc' diff --git a/app/services/comment_service.rb b/app/services/comment_service.rb index 42dc8c415..876caaaf3 100644 --- a/app/services/comment_service.rb +++ b/app/services/comment_service.rb @@ -78,4 +78,13 @@ class CommentService @jfm end + #发贴,用于意见反馈 + def create_feedback params,current_user + @memo = Memo.new(params[:memo]) + @memo.forum_id = "1" + @memo.author_id = current_user.id + @memo.save + @memo + end + end \ No newline at end of file From d1edd86e11108629c6b4cbfaccea4c0614b6e95b Mon Sep 17 00:00:00 2001 From: sw <939547590@qq.com> Date: Thu, 5 Mar 2015 10:40:10 +0800 Subject: [PATCH 41/97] =?UTF-8?q?1=E3=80=81=E4=BF=AE=E6=94=B9=E7=BB=84?= =?UTF-8?q?=E7=BB=87=E9=A6=96=E9=A1=B5=E9=A1=B9=E7=9B=AE=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=202=E3=80=81=E4=BF=AE=E6=94=B9=E6=AD=A4=E7=BB=84=E7=BB=87?= =?UTF-8?q?=E6=B2=A1=E6=9C=89=E9=A1=B9=E7=9B=AE=E6=97=B6=E7=9A=84=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/welcome_controller.rb | 36 ++++++++-------- app/views/welcome/_hot_projects_list.html.erb | 4 +- app/views/welcome/index.html.erb | 41 +++++++++---------- 3 files changed, 42 insertions(+), 39 deletions(-) diff --git a/app/controllers/welcome_controller.rb b/app/controllers/welcome_controller.rb index db2f287eb..4ee5ddbf1 100644 --- a/app/controllers/welcome_controller.rb +++ b/app/controllers/welcome_controller.rb @@ -27,28 +27,31 @@ class WelcomeController < ApplicationController def index # 企业版定制: params[:project]为传过来的参数 unless params[:organization].nil? - @cur_projects = Project.find(params[:organization]) - @organization = @cur_projects.enterprise_name - @organization_projects = (current_user.admin? || User.current.member_of?(@cur_projects)) ? Project.where("enterprise_name =? ", @organization) : Project.all_public.where("enterprise_name =? ", @organization) - @e_count = @organization_projects.count - @part_projects = [] - # 取十个 - @organization_projects.each do |obj| - break if(@organization_projects[10] == obj) - @part_projects << Project.visible.find_by_id("#{obj.id}") unless obj.id.nil? - end - # 不够十个的用最火项目替代 - @e_count < 9 ? @part_projects = find_miracle_project( 9 - @e_count, 3,"score desc") : @part_projects - # 配置文件首页定制 + @organization = Organization.find params[:organization] + @organization_projects = Project.visible.joins(:project_status).joins("LEFT JOIN project_scores ON projects.id = project_scores.project_id").where("projects.organization_id = ?", 1).order("score DESC").limit(10).all + @part_projects = @organization_projects.count < 9 ? find_miracle_project( 9 - @organization_projects.count, 3,"score desc") : [] + # @cur_projects = Project.find(params[:organization]) + # @organization = @cur_projects.enterprise_name + # @organization_projects = (current_user.admin? || User.current.member_of?(@cur_projects)) ? Project.where("enterprise_name =? ", @organization) : Project.all_public.where("enterprise_name =? ", @organization) + # @e_count = @organization_projects.count + # @part_projects = [] + # # 取十个 + # @organization_projects.each do |obj| + # break if(@organization_projects[10] == obj) + # @part_projects << Project.visible.find_by_id("#{obj.id}") unless obj.id.nil? + # end + # # 不够十个的用最火项目替代 + # @e_count < 9 ? @part_projects = find_miracle_project( 9 - @e_count, 3,"score desc") : @part_projects + # # 配置文件首页定制 @enterprise_page = FirstPage.find_by_page_type('enterprise') if @enterprise_page.nil? @enterprise_page = FirstPage.new @enterprise_page.page_type = 'enterprise' end - # 主页配置部分结束 - + # 主页配置部分结束 end # end 企业版定制结束 + if @first_page.nil? || @first_page.sort_type.nil? @projects = find_miracle_project(10, 3,"score desc") else @@ -74,7 +77,8 @@ class WelcomeController < ApplicationController @projects = @projects_all.order("score desc") end end - + rescue Exception => e + render_404 end def robots diff --git a/app/views/welcome/_hot_projects_list.html.erb b/app/views/welcome/_hot_projects_list.html.erb index 92e1469cd..d14a6901b 100644 --- a/app/views/welcome/_hot_projects_list.html.erb +++ b/app/views/welcome/_hot_projects_list.html.erb @@ -5,7 +5,9 @@
<% unless project.is_public %> - <%= l(:label_private) %> + + <%= l(:label_private) %> + <% end %> <%= link_to( project.name, project_path(project.id), :class => "d-g-blue d-p-project-name",:title => "#{project.name}" )%> (<%= link_to l(:label_project_member_amount, :count=>projectCount(project)), project_member_path(project) ,:course =>'0' %>) diff --git a/app/views/welcome/index.html.erb b/app/views/welcome/index.html.erb index 3e0a50ceb..76ca25743 100644 --- a/app/views/welcome/index.html.erb +++ b/app/views/welcome/index.html.erb @@ -35,7 +35,7 @@ <% if get_avatar?(@first_page) %> <%= image_tag(url_to_avatar(@first_page), width:@first_page.image_width,height: @first_page.image_height) %> <% else %> - <%= image_tag '/images/transparent.png', width:@first_page.image_width,height: @first_page.image_height %> + <%= image_tag @organization.logo_link, width:@first_page.image_width,height: @first_page.image_height %> <% end %> <% else %> <%= image_tag(url_to_avatar(@enterprise_page), width:@first_page.image_width,height: @first_page.image_height) %> @@ -47,9 +47,9 @@ <%= @first_page.description.html_safe %> <% end %> <% else %> - - <%= @organization %> - + + <%= @organization.name %> +
<%= @enterprise_page.title %> @@ -86,24 +86,21 @@ <% end; reset_cycle %> <% else %> - <% if @e_count == 0 %> -
<%= l(:label_enterprise_tips) %>
- <% @projects.map do |project| %> - <%= render :partial => 'hot_projects_list', :locals => {:project => project} %> - <% end %> - <% elsif @e_count < 10 %> - <% @organization_projects.map do |project| %> - <%= render :partial => 'hot_projects_list', :locals => {:project => project} %> - <% end %> -
<%= l(:label_part_enterprise_tips) %>
- <% @part_projects.map do |project| %> - <%= render :partial => 'hot_projects_list', :locals => {:project => project} %> - <% end %> - <% else %> - <% @part_projects.map do |project| %> - <%= render :partial => 'hot_projects_list', :locals => {:project => project} %> - <% end %> - <% end %> + <% if @part_projects.empty? %> + <% @projects.map do |project| %> + <%= render :partial => 'hot_projects_list', :locals => {:project => project} %> + <% end %> + <% else %> + <% @organization_projects.map do |project| %> + <%= render :partial => 'hot_projects_list', :locals => {:project => project} %> + <% end %> +
+ <%= l(:label_part_enterprise_tips) %> +
+ <% @part_projects.map do |project| %> + <%= render :partial => 'hot_projects_list', :locals => {:project => project} %> + <% end %> + <% end %> <% end %>
From dead08a0d6a220ed96516d880de481109ed0f2d7 Mon Sep 17 00:00:00 2001 From: sw <939547590@qq.com> Date: Thu, 5 Mar 2015 11:53:28 +0800 Subject: [PATCH 42/97] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E3=80=81=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E9=A1=B9=E7=9B=AE=E5=A2=9E=E5=8A=A0=E6=89=80=E5=B1=9E?= =?UTF-8?q?=E7=BB=84=E7=BB=87=E7=9A=84=E9=80=89=E6=8B=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/projects_controller.rb | 2 ++ app/helpers/projects_helper.rb | 11 +++++++ app/views/projects/_form.html.erb | 45 ++++++++++++++++++++------ app/views/projects/new.html.erb | 4 ++- config/locales/zh.yml | 2 +- 5 files changed, 53 insertions(+), 11 deletions(-) diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 41ec5fbf4..dea9c21ec 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -179,6 +179,7 @@ class ProjectsController < ApplicationController @trackers = Tracker.sorted.all @project = Project.new @project.safe_attributes = params[:project] + @project.organization_id = params[:organization_id] if validate_parent_id && @project.save @project.set_allowed_parent!(params[:project]['parent_id']) if params[:project].has_key?('parent_id') # Add current user as a project member if he is not admin @@ -404,6 +405,7 @@ class ProjectsController < ApplicationController def update @project.safe_attributes = params[:project] + @project.organization_id = params[:organization_id] #@project.dts_test = params[:project][:dts_test] if validate_parent_id && @project.save @course = Course.find_by_extra(@project.identifier) diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index fe6714186..ccc750462 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -371,4 +371,15 @@ module ProjectsHelper return projects end + + def project_organizations_id_option + type = [] + Organization.all.each do |org| + option = [] + option << org.name + option << org.id + type << option + end + type + end end diff --git a/app/views/projects/_form.html.erb b/app/views/projects/_form.html.erb index 636aadf43..d0544cadb 100644 --- a/app/views/projects/_form.html.erb +++ b/app/views/projects/_form.html.erb @@ -1,35 +1,62 @@ <%= error_messages_for 'project' %> <% unless @project.new_record? %> -

<%= render :partial=>"avatar/avatar_form",:locals=> {source:@project} %>

+

+ <%= render :partial=>"avatar/avatar_form",:locals=> {source:@project} %> +

<% end %> -

<%= f.text_field :name, :required => true, :size => 60, :style => "width:490px;" %>

+

+ <%= f.text_field :name, :required => true, :size => 60, :style => "width:490px;" %> +

<%= f.text_area :description, :rows => 8, :class => 'wiki-edit', :style => "font-size:small;width:490px;margin-left:10px;" %>

-

<%= f.text_field :enterprise_name, :size => 60, :style => "width:490px;" %>

-

<%= f.text_field :identifier, :required => true, :size => 60, :style => "width:488px;", :disabled => @project.identifier_frozen?, :maxlength => Project::IDENTIFIER_MAX_LENGTH, +

+ <%#= f.text_field :enterprise_name, :size => 60, :style => "width:490px;" %> + + <%= select_tag :organization_id,options_for_select(project_organizations_id_option,@project.organization_id),{} %> +

+

+ <%= f.text_field :identifier, :required => true, :size => 60, :style => "width:488px;", :disabled => @project.identifier_frozen?, :maxlength => Project::IDENTIFIER_MAX_LENGTH, value:"#{User.current.id.to_s + '_' +Time.now.to_s.gsub(' ','_').gsub(':','').gsub('+','')}" %> <% unless @project.identifier_frozen? %> - <%= l(:text_length_between, :min => 1, :max => Project::IDENTIFIER_MAX_LENGTH) %> <%= l(:text_project_identifier_info).html_safe %> + + <%= l(:text_length_between, :min => 1, :max => Project::IDENTIFIER_MAX_LENGTH) %> + <%= l(:text_project_identifier_info).html_safe %> + <% end %>

-

<%= f.check_box :is_public, :style => "margin-left:10px;" %>

-

<%= f.check_box :hidden_repo, :style => "margin-left:10px;" %>

+

+ + <%= f.check_box :is_public, :style => "margin-left:10px;" %> + +

+

+ + <%= f.check_box :hidden_repo, :style => "margin-left:10px;" %> + +

-

<%= f.text_field :project_type, :value => 0 %>

+

+ <%= f.text_field :project_type, :value => 0 %> +

<%= wikitoolbar_for 'project_description' %> <% @project.custom_field_values.each do |value| %> -

<%= custom_field_tag_with_label :project, value %>

+

+ <%= custom_field_tag_with_label :project, value %> +

<% end %> <%= call_hook(:view_projects_form, :project => @project, :form => f) %> diff --git a/app/views/projects/new.html.erb b/app/views/projects/new.html.erb index b68fcb5bc..57afc6c08 100644 --- a/app/views/projects/new.html.erb +++ b/app/views/projects/new.html.erb @@ -4,7 +4,9 @@ <%= labelled_form_for @project do |f| %>

<%=l(:label_project_new)%>

-

<%=raw l(:label_project_new_description)%>

+

+ <%=raw l(:label_project_new_description)%> +

<%= render :partial => 'form', :locals => { :f => f } %> <%= submit_tag l(:button_create), :class => "enterprise"%> diff --git a/config/locales/zh.yml b/config/locales/zh.yml index aa153cda6..e9efa7fba 100644 --- a/config/locales/zh.yml +++ b/config/locales/zh.yml @@ -247,7 +247,7 @@ zh: label_course_closed_tips: "确定要%{desc}课程?" # end field_name: 名称 - field_enterprise_name: 组织名称 + field_enterprise_name: 组织 label_week_mail: 一周动态 label_day_mail: 一日动态 From 3b4bf8b99d26cb870ce2e7edb0c5aa7c96471a46 Mon Sep 17 00:00:00 2001 From: sw <939547590@qq.com> Date: Thu, 5 Mar 2015 14:15:07 +0800 Subject: [PATCH 43/97] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=BB=84=E7=BB=87?= =?UTF-8?q?=E7=9A=84index=E7=95=8C=E9=9D=A2=EF=BC=8C=E4=BB=A5=E5=8F=8Ainde?= =?UTF-8?q?x=E7=95=8C=E9=9D=A2=E5=88=B0=E7=BB=84=E7=BB=87=E9=A6=96?= =?UTF-8?q?=E9=A1=B5=E7=9A=84=E8=B7=B3=E8=BD=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/organization_controller.rb | 10 +++++++ app/controllers/organizations_controller.rb | 6 ---- app/views/organization/index.html.erb | 31 +++++++++++++++++++++ app/views/organizations/index.html.erb | 23 --------------- config/routes.rb | 8 +++--- 5 files changed, 45 insertions(+), 33 deletions(-) create mode 100644 app/controllers/organization_controller.rb delete mode 100644 app/controllers/organizations_controller.rb create mode 100644 app/views/organization/index.html.erb delete mode 100644 app/views/organizations/index.html.erb diff --git a/app/controllers/organization_controller.rb b/app/controllers/organization_controller.rb new file mode 100644 index 000000000..ef0919ced --- /dev/null +++ b/app/controllers/organization_controller.rb @@ -0,0 +1,10 @@ +class OrganizationController < ApplicationController + layout 'project_base' + def index + #@projects = Project.find_by_sql("SELECT * FROM projects WHERE id IN (select MAX(id) from projects GROUP BY enterprise_name)") + @organizations = Organization.all + respond_to do |format| + format.html + end + end +end diff --git a/app/controllers/organizations_controller.rb b/app/controllers/organizations_controller.rb deleted file mode 100644 index c9cce5752..000000000 --- a/app/controllers/organizations_controller.rb +++ /dev/null @@ -1,6 +0,0 @@ -class OrganizationsController < ApplicationController - layout 'project_base' - def index - @projects = Project.find_by_sql("SELECT * FROM projects WHERE id IN (select MAX(id) from projects GROUP BY enterprise_name)") - end -end diff --git a/app/views/organization/index.html.erb b/app/views/organization/index.html.erb new file mode 100644 index 000000000..2f657831a --- /dev/null +++ b/app/views/organization/index.html.erb @@ -0,0 +1,31 @@ + + <%= l(:label_all_enterprises) %> + +
+
+ <%= l(:label_all_enterprises) %> +
+
+ <% if @organizations.empty? %> +

+ <%= l(:label_enterprise_nil) %> +

+ <% else %> + <% @organizations.each do |organization| %> + <% unless organization.name.blank? %> +
    +
  • + #{project.enterprise_name} + <%= link_to organization.name, home_path(:organization => organization.id) %> +
  • +
+ <% end %> + <% end %> + <% end %> +
+
+
+
+
    +
    +<% html_title(l(:label_enterprise_all)) -%> diff --git a/app/views/organizations/index.html.erb b/app/views/organizations/index.html.erb deleted file mode 100644 index 45813ced5..000000000 --- a/app/views/organizations/index.html.erb +++ /dev/null @@ -1,23 +0,0 @@ -<%= l(:label_all_enterprises) %> -
    -
    <%= l(:label_all_enterprises) %>
    -
    - <% if @projects.count == 0 %> -

    <%= l(:label_enterprise_nil) %>

    - <% else %> - <% @projects.each do |organization| %> - <% unless organization.enterprise_name.blank? %> -
      -
    • #{project.enterprise_name} - <%= link_to organization.enterprise_name, home_path(:organization => organization) %>
    • -
    - <% end %> - <% end %> - <% end %> -
    -
    -
    -
    -
      -
      -<% html_title(l(:label_enterprise_all)) -%> diff --git a/config/routes.rb b/config/routes.rb index bf0b73e8d..6756a713d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -26,9 +26,6 @@ # Example: :via => :get ====> :via => :get RedmineApp::Application.routes.draw do - get "organizations/index" - - #match '/contests/:id/contestnotifications', :controller => 'contestnotifications', :action => 'index' mount Mobile::API => '/api' @@ -39,6 +36,10 @@ RedmineApp::Application.routes.draw do resources :apply_project_masters delete 'apply_project_masters', :to => 'apply_project_masters#delete' + resources :organization, :only => [:index] do + + end + resources :homework_attach do collection do get 'get_homework_member_list' @@ -390,7 +391,6 @@ RedmineApp::Application.routes.draw do match '/statistics', :to => 'projects#statistics', :as => 'statistics', :via => :get # match '/investor', :controller => 'projects', :action => 'investor', :as => 'investor', :via => :get match '/homework', :to => 'projects#homework', :as => 'homework', :via => :get - match 'organizations', :to => 'organizations#index', :as => 'index', :via => :get # match '/activity', :controller => 'activities', :action => 'index', :as => 'activity', :via => :get # match '/repository', :controller => 'repositories', :action => 'show', :repository_id => nil, :path => nil, :rev => nil, :as => 'repository', :via => :get From 45fe622f26a933ed3a6c1208a94cd22d31c1c1b8 Mon Sep 17 00:00:00 2001 From: sw <939547590@qq.com> Date: Thu, 5 Mar 2015 14:42:46 +0800 Subject: [PATCH 44/97] =?UTF-8?q?1=E3=80=81=E4=BF=AE=E6=94=B9=E8=BF=9B?= =?UTF-8?q?=E5=85=A5=E7=B3=BB=E7=BB=9F=E9=A6=96=E9=A1=B5=E6=8A=A5=E9=94=99?= =?UTF-8?q?=202=E3=80=81=E5=A2=9E=E5=8A=A0=E7=BB=84=E7=BB=87=E7=9A=84?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E5=9B=BE=E7=89=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/organization/index.html.erb | 2 +- app/views/welcome/index.html.erb | 4 ++-- public/images/avatars/Organization/0 | Bin 0 -> 56368 bytes 3 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 public/images/avatars/Organization/0 diff --git a/app/views/organization/index.html.erb b/app/views/organization/index.html.erb index 2f657831a..f1c50d6ab 100644 --- a/app/views/organization/index.html.erb +++ b/app/views/organization/index.html.erb @@ -15,7 +15,7 @@ <% unless organization.name.blank? %>
      • - #{project.enterprise_name} + <%= organization.name%> <%= link_to organization.name, home_path(:organization => organization.id) %>
      diff --git a/app/views/welcome/index.html.erb b/app/views/welcome/index.html.erb index 76ca25743..eca3e4c1d 100644 --- a/app/views/welcome/index.html.erb +++ b/app/views/welcome/index.html.erb @@ -35,10 +35,10 @@ <% if get_avatar?(@first_page) %> <%= image_tag(url_to_avatar(@first_page), width:@first_page.image_width,height: @first_page.image_height) %> <% else %> - <%= image_tag @organization.logo_link, width:@first_page.image_width,height: @first_page.image_height %> + <%= image_tag '/images/transparent.png', width:@first_page.image_width,height: @first_page.image_height %> <% end %> <% else %> - <%= image_tag(url_to_avatar(@enterprise_page), width:@first_page.image_width,height: @first_page.image_height) %> + <%= image_tag(url_to_avatar(@organization), width:@first_page.image_width,height: @first_page.image_height) %> <% end %>
      diff --git a/public/images/avatars/Organization/0 b/public/images/avatars/Organization/0 new file mode 100644 index 0000000000000000000000000000000000000000..2ae1d749446d88f0516c7c1807e93a426f85264a GIT binary patch literal 56368 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 literal 0 HcmV?d00001 From 5f8595d874a4186aba2dc1be77ccd5334f481ff2 Mon Sep 17 00:00:00 2001 From: sw <939547590@qq.com> Date: Thu, 5 Mar 2015 15:27:22 +0800 Subject: [PATCH 45/97] =?UTF-8?q?admin=E9=A1=B5=E9=9D=A2=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E7=BB=84=E7=BB=87=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/admin_controller.rb | 7 +++++++ app/views/admin/organization.html.erb | 1 + config/locales/zh.yml | 1 + config/routes.rb | 1 + lib/redmine.rb | 1 + 5 files changed, 11 insertions(+) create mode 100644 app/views/admin/organization.html.erb diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb index aab9d7b69..1efbb665f 100644 --- a/app/controllers/admin_controller.rb +++ b/app/controllers/admin_controller.rb @@ -322,4 +322,11 @@ class AdminController < ApplicationController end end + #组织 + def organization + @organizations = Organization.all + respond_to do |format| + format.html + end + end end diff --git a/app/views/admin/organization.html.erb b/app/views/admin/organization.html.erb new file mode 100644 index 000000000..9d07aa0df --- /dev/null +++ b/app/views/admin/organization.html.erb @@ -0,0 +1 @@ +111 \ No newline at end of file diff --git a/config/locales/zh.yml b/config/locales/zh.yml index e9efa7fba..362838800 100644 --- a/config/locales/zh.yml +++ b/config/locales/zh.yml @@ -538,6 +538,7 @@ zh: label_project: 项目 label_activity_project: '项目: ' #added by bai + label_organization_list: 组织列表 label_project_plural: 项目列表 label_first_page_made: 首页定制 label_project_first_page: 项目托管平台首页 diff --git a/config/routes.rb b/config/routes.rb index 6756a713d..fb4e40e49 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -646,6 +646,7 @@ RedmineApp::Application.routes.draw do match 'admin/info', :via => :get match 'admin/test_email', :via => :get match 'admin/default_configuration', :via => :post + get 'admin/organization' resources :auth_sources do member do diff --git a/lib/redmine.rb b/lib/redmine.rb index cd855e01a..5cfd8bae8 100644 --- a/lib/redmine.rb +++ b/lib/redmine.rb @@ -360,6 +360,7 @@ Redmine::MenuManager.map :homework_menu do |menu| end ########end Redmine::MenuManager.map :admin_menu do |menu| + menu.push :organization, {:controller => 'admin', :action => 'organization'}, :caption => :label_organization_list menu.push :projects, {:controller => 'admin', :action => 'projects'}, :caption => :label_project_plural menu.push :users, {:controller => 'admin', :action => 'users'}, :caption => :label_user_plural menu.push :first_page_made, {:controller => 'admin',:action => 'first_page_made'},:caption => :label_first_page_made From 0b46fd99b56a67499c82b08b9399ba2dee553143 Mon Sep 17 00:00:00 2001 From: lizanle <491823689@qq.com> Date: Thu, 5 Mar 2015 17:02:03 +0800 Subject: [PATCH 46/97] ok --- .gitignore | 23 ---- Gemfile | 132 ------------------- Gemfile.lock | 348 --------------------------------------------------- 3 files changed, 503 deletions(-) delete mode 100644 .gitignore delete mode 100644 Gemfile delete mode 100644 Gemfile.lock diff --git a/.gitignore b/.gitignore deleted file mode 100644 index af337a4e7..000000000 --- a/.gitignore +++ /dev/null @@ -1,23 +0,0 @@ -*.swp -/.project -/.idea -/.bundle -*.swp -/config/database.yml -/config/configuration.yml -/files/* -/log/* -/public/tmp/* -/tmp/* -/public/cache/* -.gitignore -/config/newrelic.yml -/public/images/avatars/* -/Gemfile -/Gemfile.lock -/db/schema.rb -/Gemfile.lock -/lib/plugins/acts_as_versioned/test/debug.log -.rbenv-gemsets -.DS_Store -public/api_doc/ diff --git a/Gemfile b/Gemfile deleted file mode 100644 index 037c606c8..000000000 --- a/Gemfile +++ /dev/null @@ -1,132 +0,0 @@ -source 'http://rubygems.org' -#source 'http://ruby.sdutlinux.org/' - -unless RUBY_PLATFORM =~ /w32/ - # unix-like only - gem 'iconv' - gem 'rubyzip' - gem 'zip-zip' -end - -gem 'grape', '~> 0.9.0' -gem 'grape-entity' -gem 'seems_rateable', path: 'lib/seems_rateable' -gem "rails", "3.2.13" -gem "jquery-rails", "~> 2.0.2" -gem "i18n", "~> 0.6.0" -gem "coderay", "~> 1.0.6" -gem "fastercsv", "~> 1.5.0", :platforms => [:mri_18, :mingw_18, :jruby] -gem "builder", "3.0.0" -gem 'acts-as-taggable-on', '2.4.1' -gem 'spreadsheet' -gem 'ruby-ole' -#gem 'email_verifier', path: 'lib/email_verifier' - -group :development do - gem 'grape-swagger' - gem 'grape-swagger-ui', git: 'https://github.com/guange2015/grape-swagger-ui.git' - #gem 'puma' - gem 'better_errors', path: 'lib/better_errors' - gem 'rack-mini-profiler', path: 'lib/rack-mini-profiler' -end - -group :test do - gem "shoulda", "~> 3.5.0" - gem "mocha", "~> 1.1.0" - gem 'capybara', '~> 2.4.1' - gem 'nokogiri', '~> 1.6.3' - gem 'factory_girl', '~> 4.4.0' - gem 'selenium-webdriver', '~> 2.42.0' - - gem "faker" - # platforms :mri, :mingw do - # group :rmagick do - # # RMagick 2 supports ruby 1.9 - # # RMagick 1 would be fine for ruby 1.8 but Bundler does not support - # # different requirements for the same gem on different platforms - # gem "rmagick", ">= 2.0.0" - # end - #end -end - - gem 'rspec-rails' , '2.13.1' - gem 'guard-rspec','2.5.0' -# Gems used only for assets and not required -# in production environments by default. -group :assets do - gem 'sass-rails', '~> 3.2.3' - gem 'coffee-rails', '~> 3.2.1' - - # See https://github.com/sstephenson/execjs#readme for more supported runtimes - gem 'therubyracer', :platforms => :ruby - - gem 'uglifier', '>= 1.0.3' -end - -# Optional gem for LDAP authentication -group :ldap do - gem "net-ldap", "~> 0.3.1" -end - - -# Optional gem for OpenID authentication -group :openid do - gem "ruby-openid", "~> 2.1.4", :require => "openid" - gem "rack-openid" -end - -# Optional gem for exporting the gantt to a PNG file, not supported with jruby -platforms :jruby do - # jruby-openssl is bundled with JRuby 1.7.0 - gem "jruby-openssl" if Object.const_defined?(:JRUBY_VERSION) && JRUBY_VERSION < '1.7.0' - gem "activerecord-jdbc-adapter", "1.2.5" -end - -# Include database gems for the adapters found in the database -# configuration file -require 'erb' -require 'yaml' -database_file = File.join(File.dirname(__FILE__), "config/database.yml") -if File.exist?(database_file) - database_config = YAML::load(ERB.new(IO.read(database_file)).result) - adapters = database_config.values.map {|c| c['adapter']}.compact.uniq - if adapters.any? - adapters.each do |adapter| - case adapter - when 'mysql2' - gem "mysql2", "= 0.3.11", :platforms => [:mri, :mingw] - gem "activerecord-jdbcmysql-adapter", :platforms => :jruby - when 'mysql' - gem "mysql", "~> 2.8.1", :platforms => [:mri, :mingw] - gem "activerecord-jdbcmysql-adapter", :platforms => :jruby - when /postgresql/ - gem "pg", ">= 0.11.0", :platforms => [:mri, :mingw] - gem "activerecord-jdbcpostgresql-adapter", :platforms => :jruby - when /sqlite3/ - gem "sqlite3", :platforms => [:mri, :mingw] - gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby - when /sqlserver/ - gem "tiny_tds", "~> 0.5.1", :platforms => [:mri, :mingw] - gem "activerecord-sqlserver-adapter", :platforms => [:mri, :mingw] - else - warn("Unknown database adapter `#{adapter}` found in config/database.yml, use Gemfile.local to load your own database gems") - end - end - else - warn("No adapter found in config/database.yml, please configure it first") - end -else - warn("Please configure your config/database.yml first") -end - -local_gemfile = File.join(File.dirname(__FILE__), "Gemfile.local") -if File.exists?(local_gemfile) - puts "Loading Gemfile.local ..." if $DEBUG # `ruby -d` or `bundle -v` - instance_eval File.read(local_gemfile) -end - -# Load plugins' Gemfiles -Dir.glob File.expand_path("../plugins/*/Gemfile", __FILE__) do |file| - puts "Loading #{file} ..." if $DEBUG # `ruby -d` or `bundle -v` - instance_eval File.read(file) -end diff --git a/Gemfile.lock b/Gemfile.lock deleted file mode 100644 index 355ca422d..000000000 --- a/Gemfile.lock +++ /dev/null @@ -1,348 +0,0 @@ -GIT - remote: https://github.com/guange2015/grape-swagger-ui.git - revision: 4c33439f236c174ae0e774b3435ef2547995c21d - specs: - grape-swagger-ui (0.0.4) - railties (>= 3.1) - -PATH - remote: lib/better_errors - specs: - better_errors (1.1.0) - coderay (>= 1.0.0) - erubis (>= 2.6.6) - -PATH - remote: lib/rack-mini-profiler - specs: - rack-mini-profiler (0.9.1) - rack (>= 1.1.3) - -PATH - remote: lib/seems_rateable - specs: - seems_rateable (1.0.13) - jquery-rails - rails - -GEM - remote: http://rubygems.org/ - remote: https://rubygems.org/ - specs: - actionmailer (3.2.13) - actionpack (= 3.2.13) - mail (~> 2.5.3) - actionpack (3.2.13) - activemodel (= 3.2.13) - activesupport (= 3.2.13) - builder (~> 3.0.0) - erubis (~> 2.7.0) - journey (~> 1.0.4) - rack (~> 1.4.5) - rack-cache (~> 1.2) - rack-test (~> 0.6.1) - sprockets (~> 2.2.1) - activemodel (3.2.13) - activesupport (= 3.2.13) - builder (~> 3.0.0) - activerecord (3.2.13) - activemodel (= 3.2.13) - activesupport (= 3.2.13) - arel (~> 3.0.2) - tzinfo (~> 0.3.29) - activeresource (3.2.13) - activemodel (= 3.2.13) - activesupport (= 3.2.13) - activesupport (3.2.13) - i18n (= 0.6.1) - multi_json (~> 1.0) - acts-as-taggable-on (2.4.1) - rails (>= 3, < 5) - arel (3.0.3) - axiom-types (0.1.1) - descendants_tracker (~> 0.0.4) - ice_nine (~> 0.11.0) - thread_safe (~> 0.3, >= 0.3.1) - builder (3.0.0) - capybara (2.4.1) - mime-types (>= 1.16) - nokogiri (>= 1.3.3) - rack (>= 1.0.0) - rack-test (>= 0.5.4) - xpath (~> 2.0) - celluloid (0.16.0) - timers (~> 4.0.0) - childprocess (0.5.3) - ffi (~> 1.0, >= 1.0.11) - climate_control (0.0.3) - activesupport (>= 3.0) - cocaine (0.5.4) - climate_control (>= 0.0.3, < 1.0) - coderay (1.0.9) - coercible (1.0.0) - descendants_tracker (~> 0.0.1) - coffee-rails (3.2.2) - coffee-script (>= 2.2.0) - railties (~> 3.2.0) - coffee-script (2.3.0) - coffee-script-source - execjs - coffee-script-source (1.7.1) - descendants_tracker (0.0.4) - thread_safe (~> 0.3, >= 0.3.1) - diff-lcs (1.2.5) - equalizer (0.0.9) - erubis (2.7.0) - execjs (2.2.1) - factory_girl (4.4.0) - activesupport (>= 3.0.0) - faker (1.4.3) - i18n (~> 0.5) - fastercsv (1.5.5) - ffi (1.9.3) - ffi (1.9.3-x86-mingw32) - formatador (0.2.5) - grape (0.9.0) - activesupport - builder - hashie (>= 2.1.0) - multi_json (>= 1.3.2) - multi_xml (>= 0.5.2) - rack (>= 1.3.0) - rack-accept - rack-mount - virtus (>= 1.0.0) - grape-entity (0.4.4) - activesupport - multi_json (>= 1.3.2) - grape-swagger (0.8.0) - grape - grape-entity - guard (2.11.1) - formatador (>= 0.2.4) - listen (~> 2.7) - lumberjack (~> 1.0) - nenv (~> 0.1) - notiffany (~> 0.0) - pry (>= 0.9.12) - shellany (~> 0.0) - thor (>= 0.18.1) - guard-rspec (2.5.0) - guard (>= 1.1) - rspec (~> 2.11) - hashie (3.3.1) - hike (1.2.3) - hitimes (1.2.2) - hitimes (1.2.2-x86-mingw32) - htmlentities (4.3.2) - i18n (0.6.1) - ice_nine (0.11.0) - journey (1.0.4) - jquery-rails (2.0.3) - railties (>= 3.1.0, < 5.0) - thor (~> 0.14) - json (1.8.1) - kaminari (0.16.1) - actionpack (>= 3.0.0) - activesupport (>= 3.0.0) - libv8 (3.16.14.3) - listen (2.8.5) - celluloid (>= 0.15.2) - rb-fsevent (>= 0.9.3) - rb-inotify (>= 0.9) - lumberjack (1.0.9) - mail (2.5.4) - mime-types (~> 1.16) - treetop (~> 1.4.8) - metaclass (0.0.4) - method_source (0.8.2) - mime-types (1.25.1) - mini_portile (0.6.0) - mocha (1.1.0) - metaclass (~> 0.0.1) - multi_json (1.10.1) - multi_xml (0.5.5) - mysql2 (0.3.11) - mysql2 (0.3.11-x86-mingw32) - nenv (0.2.0) - net-ldap (0.3.1) - nokogiri (1.6.3) - mini_portile (= 0.6.0) - nokogiri (1.6.3-x86-mingw32) - mini_portile (= 0.6.0) - notiffany (0.0.3) - nenv (~> 0.1) - shellany (~> 0.0) - paperclip (3.5.4) - activemodel (>= 3.0.0) - activesupport (>= 3.0.0) - cocaine (~> 0.5.3) - mime-types - polyglot (0.3.5) - pry (0.9.12.6) - coderay (~> 1.0) - method_source (~> 0.8) - slop (~> 3.4) - pry (0.9.12.6-x86-mingw32) - coderay (~> 1.0) - method_source (~> 0.8) - slop (~> 3.4) - win32console (~> 1.3) - rack (1.4.5) - rack-accept (0.4.5) - rack (>= 0.4) - rack-cache (1.2) - rack (>= 0.4) - rack-mount (0.8.3) - rack (>= 1.0.0) - rack-openid (1.4.2) - rack (>= 1.1.0) - ruby-openid (>= 2.1.8) - rack-raw-upload (1.1.1) - multi_json - rack-ssl (1.3.4) - rack - rack-test (0.6.2) - rack (>= 1.0) - rails (3.2.13) - actionmailer (= 3.2.13) - actionpack (= 3.2.13) - activerecord (= 3.2.13) - activeresource (= 3.2.13) - activesupport (= 3.2.13) - bundler (~> 1.0) - railties (= 3.2.13) - railties (3.2.13) - actionpack (= 3.2.13) - activesupport (= 3.2.13) - rack-ssl (~> 1.3.2) - rake (>= 0.8.7) - rdoc (~> 3.4) - thor (>= 0.14.6, < 2.0) - rake (10.3.2) - rb-fsevent (0.9.4) - rb-inotify (0.9.5) - ffi (>= 0.5.0) - rdoc (3.12.2) - json (~> 1.4) - ref (1.0.5) - rich (1.4.6) - jquery-rails - kaminari - mime-types - paperclip - rack-raw-upload - rails (>= 3.2.0) - sass-rails - rspec (2.13.0) - rspec-core (~> 2.13.0) - rspec-expectations (~> 2.13.0) - rspec-mocks (~> 2.13.0) - rspec-core (2.13.1) - rspec-expectations (2.13.0) - diff-lcs (>= 1.1.3, < 2.0) - rspec-mocks (2.13.1) - rspec-rails (2.13.1) - actionpack (>= 3.0) - activesupport (>= 3.0) - railties (>= 3.0) - rspec-core (~> 2.13.0) - rspec-expectations (~> 2.13.0) - rspec-mocks (~> 2.13.0) - ruby-ole (1.2.11.7) - ruby-openid (2.1.8) - rubyzip (1.1.6) - sass (3.3.10) - sass-rails (3.2.6) - railties (~> 3.2.0) - sass (>= 3.1.10) - tilt (~> 1.3) - selenium-webdriver (2.42.0) - childprocess (>= 0.5.0) - multi_json (~> 1.0) - rubyzip (~> 1.0) - websocket (~> 1.0.4) - shellany (0.0.1) - shoulda (3.5.0) - shoulda-context (~> 1.0, >= 1.0.1) - shoulda-matchers (>= 1.4.1, < 3.0) - shoulda-context (1.2.1) - shoulda-matchers (2.6.1) - activesupport (>= 3.0.0) - slop (3.6.0) - spreadsheet (1.0.0) - ruby-ole (>= 1.0) - sprockets (2.2.2) - hike (~> 1.2) - multi_json (~> 1.0) - rack (~> 1.0) - tilt (~> 1.1, != 1.3.0) - therubyracer (0.12.1) - libv8 (~> 3.16.14.0) - ref - thor (0.19.1) - thread_safe (0.3.4) - tilt (1.4.1) - timers (4.0.1) - hitimes - treetop (1.4.15) - polyglot - polyglot (>= 0.3.1) - tzinfo (0.3.40) - uglifier (2.5.1) - execjs (>= 0.3.0) - json (>= 1.8.0) - virtus (1.0.3) - axiom-types (~> 0.1) - coercible (~> 1.0) - descendants_tracker (~> 0.0, >= 0.0.3) - equalizer (~> 0.0, >= 0.0.9) - websocket (1.0.7) - win32console (1.3.2-x86-mingw32) - xpath (2.0.0) - nokogiri (~> 1.3) - -PLATFORMS - ruby - x86-mingw32 - -DEPENDENCIES - activerecord-jdbc-adapter (= 1.2.5) - activerecord-jdbcmysql-adapter - acts-as-taggable-on (= 2.4.1) - better_errors! - builder (= 3.0.0) - capybara (~> 2.4.1) - coderay (~> 1.0.6) - coffee-rails (~> 3.2.1) - factory_girl (~> 4.4.0) - faker - fastercsv (~> 1.5.0) - grape (~> 0.9.0) - grape-entity - grape-swagger - grape-swagger-ui! - guard-rspec (= 2.5.0) - htmlentities - i18n (~> 0.6.0) - jquery-rails (~> 2.0.2) - kaminari - mocha (~> 1.1.0) - mysql2 (= 0.3.11) - net-ldap (~> 0.3.1) - nokogiri (~> 1.6.3) - paperclip (~> 3.5.4) - rack-mini-profiler! - rack-openid - rails (= 3.2.13) - rich (= 1.4.6) - rspec-rails (= 2.13.1) - ruby-ole - ruby-openid (~> 2.1.4) - sass-rails (~> 3.2.3) - seems_rateable! - selenium-webdriver (~> 2.42.0) - shoulda (~> 3.5.0) - spreadsheet - therubyracer - uglifier (>= 1.0.3) From 3c4b502e970e4950191bd164d958daa2658fad03 Mon Sep 17 00:00:00 2001 From: sw <939547590@qq.com> Date: Thu, 5 Mar 2015 17:03:44 +0800 Subject: [PATCH 47/97] =?UTF-8?q?1=E3=80=81=E4=BF=AE=E6=94=B9=E8=BF=9B?= =?UTF-8?q?=E5=85=A5=E7=BB=84=E7=BB=87=E4=B8=BB=E9=A1=B5=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E6=98=BE=E7=A4=BA=E4=B8=8D=E6=AD=A3=E7=A1=AE?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=202=E3=80=81admin=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=BB=84=E7=BB=87=E5=88=97=E8=A1=A8=E6=98=BE?= =?UTF-8?q?=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/welcome_controller.rb | 2 +- app/views/admin/organization.html.erb | 44 ++++++++++++++++++++++- app/views/admin/projects.html.erb | 51 +++++++++++++++++++-------- config/locales/zh.yml | 2 ++ config/routes.rb | 2 +- 5 files changed, 84 insertions(+), 17 deletions(-) diff --git a/app/controllers/welcome_controller.rb b/app/controllers/welcome_controller.rb index 4ee5ddbf1..290af0068 100644 --- a/app/controllers/welcome_controller.rb +++ b/app/controllers/welcome_controller.rb @@ -28,7 +28,7 @@ class WelcomeController < ApplicationController # 企业版定制: params[:project]为传过来的参数 unless params[:organization].nil? @organization = Organization.find params[:organization] - @organization_projects = Project.visible.joins(:project_status).joins("LEFT JOIN project_scores ON projects.id = project_scores.project_id").where("projects.organization_id = ?", 1).order("score DESC").limit(10).all + @organization_projects = Project.visible.joins(:project_status).joins("LEFT JOIN project_scores ON projects.id = project_scores.project_id").where("projects.organization_id = ?", @organization.id).order("score DESC").limit(10).all @part_projects = @organization_projects.count < 9 ? find_miracle_project( 9 - @organization_projects.count, 3,"score desc") : [] # @cur_projects = Project.find(params[:organization]) # @organization = @cur_projects.enterprise_name diff --git a/app/views/admin/organization.html.erb b/app/views/admin/organization.html.erb index 9d07aa0df..582b8b44a 100644 --- a/app/views/admin/organization.html.erb +++ b/app/views/admin/organization.html.erb @@ -1 +1,43 @@ -111 \ No newline at end of file +
      + <%= link_to l(:label_organization_new), new_organization_path, :class => 'icon icon-add' %> +
      + +

      + <%=l(:label_organization_list)%> +

      + +
      +
      + + + + + + + + + <% @organizations.each do |org|%> + "> + + + + + <% end%> + +
      + <%=l(:label_organization)%> + + <%=l(:field_created_on)%> +
      + + <%= link_to org.name,home_path(:organization => org.id) %> + + + <%= format_date(org.created_at) %> + + <%= link_to(l(:button_change), edit_organization_path(org.id), :class => 'icon icon-copy') %> + <%= link_to(l(:button_delete), organization_path(org.id), :method => :delete,:confirm => l(:text_are_you_sure), :class => 'icon icon-del') %> +
      +
      + +<% html_title(l(:label_project_plural)) -%> diff --git a/app/views/admin/projects.html.erb b/app/views/admin/projects.html.erb index 762ceae9e..4c9479a6d 100644 --- a/app/views/admin/projects.html.erb +++ b/app/views/admin/projects.html.erb @@ -2,16 +2,25 @@ <%= link_to l(:label_project_new), {:controller => 'projects', :action => 'new'}, :class => 'icon icon-add' %> -

      <%=l(:label_project_plural)%>

      +

      + <%=l(:label_project_plural)%> +

      <%= form_tag({}, :method => :get) do %> -
      <%= l(:label_filter_plural) %> - -<%= select_tag 'status', project_status_options_for_select(@status), :class => "small", :onchange => "this.form.submit(); return false;" %> - -<%= text_field_tag 'name', params[:name], :size => 30 %> -<%= submit_tag l(:button_apply), :class => "small", :name => nil %> -<%= link_to l(:button_clear), {:controller => 'admin', :action => 'projects'}, :class => 'icon icon-reload' %> +
      + + <%= l(:label_filter_plural) %> + + + <%= select_tag 'status', project_status_options_for_select(@status), :class => "small", :onchange => "this.form.submit(); return false;" %> + + <%= text_field_tag 'name', params[:name], :size => 30 %> + <%= submit_tag l(:button_apply), :class => "small", :name => nil %> + <%= link_to l(:button_clear), {:controller => 'admin', :action => 'projects'}, :class => 'icon icon-reload' %>
      <% end %>   @@ -19,17 +28,31 @@
      - - - + + + <% project_tree(@projects) do |project, level| %> <%= project.css_classes %> <%= level > 0 ? "idnt idnt-#{level}" : nil %>"> - - - + + +
      <%=l(:label_project)%><%=l(:field_is_public)%><%=l(:field_created_on)%> + <%=l(:label_project)%> + + <%=l(:field_is_public)%> + + <%=l(:field_created_on)%> +
      <%= link_to_project_settings(project, {}) %><%= checked_image project.is_public? %><%= format_date(project.created_on) %> + + <%= link_to_project_settings(project, {}) %> + + + <%= checked_image project.is_public? %> + + <%= format_date(project.created_on) %> + <%= link_to(l(:button_archive), { :controller => 'projects', :action => 'archive', :id => project, :status => params[:status] }, :data => {:confirm => l(:text_are_you_sure)}, :method => :post, :class => 'icon icon-lock') unless project.archived? %> <%= link_to(l(:button_unarchive), { :controller => 'projects', :action => 'unarchive', :id => project, :status => params[:status] }, :method => :post, :class => 'icon icon-unlock') if project.archived? && (project.parent.nil? || !project.parent.archived?) %> diff --git a/config/locales/zh.yml b/config/locales/zh.yml index 362838800..231339a8e 100644 --- a/config/locales/zh.yml +++ b/config/locales/zh.yml @@ -538,7 +538,9 @@ zh: label_project: 项目 label_activity_project: '项目: ' #added by bai + label_organization: 组织 label_organization_list: 组织列表 + label_organization_new: 新建组织 label_project_plural: 项目列表 label_first_page_made: 首页定制 label_project_first_page: 项目托管平台首页 diff --git a/config/routes.rb b/config/routes.rb index fb4e40e49..53f6f6a4b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -36,7 +36,7 @@ RedmineApp::Application.routes.draw do resources :apply_project_masters delete 'apply_project_masters', :to => 'apply_project_masters#delete' - resources :organization, :only => [:index] do + resources :organization, :except => [:show] do end From 33342998080fac0df9cc814432ab4178a91edce8 Mon Sep 17 00:00:00 2001 From: z9hang Date: Thu, 5 Mar 2015 17:37:33 +0800 Subject: [PATCH 48/97] =?UTF-8?q?app=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=88=E8=A1=A8=E6=B7=BB=E5=8A=A0=EF=BC=8C?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E9=83=A8=E5=88=86=E6=B7=BB=E5=8A=A0=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/admin_controller.rb | 5 ++ app/models/phone_app_version.rb | 3 + app/views/admin/mobile_version.html.erb | 55 +++++++++++++++++++ config/locales/zh.yml | 3 + config/routes.rb | 1 + ...0150305081132_create_phone_app_versions.rb | 10 ++++ db/schema.rb | 9 ++- lib/redmine.rb | 1 + spec/models/phone_app_version_spec.rb | 5 ++ 9 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 app/models/phone_app_version.rb create mode 100644 app/views/admin/mobile_version.html.erb create mode 100644 db/migrate/20150305081132_create_phone_app_versions.rb create mode 100644 spec/models/phone_app_version_spec.rb diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb index aab9d7b69..9cc6966c4 100644 --- a/app/controllers/admin_controller.rb +++ b/app/controllers/admin_controller.rb @@ -322,4 +322,9 @@ class AdminController < ApplicationController end end + #移动端版本管理 + def mobile_version + @versions = PhoneAppVersion.reorder('created_at desc') + end + end diff --git a/app/models/phone_app_version.rb b/app/models/phone_app_version.rb new file mode 100644 index 000000000..abf4c54e3 --- /dev/null +++ b/app/models/phone_app_version.rb @@ -0,0 +1,3 @@ +class PhoneAppVersion < ActiveRecord::Base + attr_accessible :description, :version +end diff --git a/app/views/admin/mobile_version.html.erb b/app/views/admin/mobile_version.html.erb new file mode 100644 index 000000000..293b0ec46 --- /dev/null +++ b/app/views/admin/mobile_version.html.erb @@ -0,0 +1,55 @@ +

      <%= l(:label_mobile_version) %>

      +发布新版本 +
      + +
      +
      +
      当前版本:
      + + + + + + + + + <% if @versions.count > 0 %> + "> + + + + <% end %> + +
      <%=l(:label_version_number)%><%=l(:label_version_description)%>
      <%= @versions.first.version %> + <%= @versions.first.description %> +
      + +
      + +
      历史版本:
      + + + + + + + + + <% if @versions.count > 0 %> + <% for version in @versions %> + "> + + + + <% end %> + <% end %> + +
      <%=l(:label_version_number)%><%=l(:label_version_description)%>
      <%= version.version %> + <%= version.description %> +
      + + + +<% html_title(l(:label_mobile_version)) -%> \ No newline at end of file diff --git a/config/locales/zh.yml b/config/locales/zh.yml index aa153cda6..d4ef76276 100644 --- a/config/locales/zh.yml +++ b/config/locales/zh.yml @@ -548,6 +548,8 @@ zh: label_organizer_name: 主办单位名称 label_web_footer_description: 页脚内容 label_cooperation_compnay: 合作单位 + label_version_number: 版本号 + label_version_description: 版本描述 label_web_footer_cooperation_compnay: 网站页脚合作单位 label_new_company: 添加合作单位 label_edit_company: 编辑合作单位 @@ -1073,6 +1075,7 @@ zh: label_project_copy_notifications: 复制项目时发送邮件通知 label_principal_search: "搜索用户或组:" label_user_search: "搜索用户:" + label_mobile_version: "移动端版本管理" button_check_all: 全选 button_uncheck_all: 清除 diff --git a/config/routes.rb b/config/routes.rb index bf0b73e8d..9e43c333f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -641,6 +641,7 @@ RedmineApp::Application.routes.draw do match 'admin/contest_page_made', as: :contest_page_made match 'admin/web_footer_made', as: :web_footer_made match 'admin/enterprise_page_made', as: :enterprise_page_made + match 'admin/mobile_version', as: :mobile_version match 'admin/search', :via => [:get, :post] match 'admin/plugins', :via => :get match 'admin/info', :via => :get diff --git a/db/migrate/20150305081132_create_phone_app_versions.rb b/db/migrate/20150305081132_create_phone_app_versions.rb new file mode 100644 index 000000000..1348dcd1b --- /dev/null +++ b/db/migrate/20150305081132_create_phone_app_versions.rb @@ -0,0 +1,10 @@ +class CreatePhoneAppVersions < ActiveRecord::Migration + def change + create_table :phone_app_versions do |t| + t.string :version + t.text :description + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index d7a1b18bc..8895085f5 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 => 20150128032421) do +ActiveRecord::Schema.define(:version => 20150305081132) do create_table "activities", :force => true do |t| t.integer "act_id", :null => false @@ -802,6 +802,13 @@ ActiveRecord::Schema.define(:version => 20150128032421) do t.integer "project_id" end + create_table "phone_app_versions", :force => true do |t| + t.string "version" + t.text "description" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + create_table "poll_answers", :force => true do |t| t.integer "poll_question_id" t.text "answer_text" diff --git a/lib/redmine.rb b/lib/redmine.rb index cd855e01a..1b13e89a2 100644 --- a/lib/redmine.rb +++ b/lib/redmine.rb @@ -363,6 +363,7 @@ Redmine::MenuManager.map :admin_menu do |menu| menu.push :projects, {:controller => 'admin', :action => 'projects'}, :caption => :label_project_plural menu.push :users, {:controller => 'admin', :action => 'users'}, :caption => :label_user_plural menu.push :first_page_made, {:controller => 'admin',:action => 'first_page_made'},:caption => :label_first_page_made + menu.push :mobile_version, {:controller => 'admin',:action => 'mobile_version'},:caption => :label_mobile_version menu.push :groups, {:controller => 'groups'}, :caption => :label_group_plural menu.push :roles, {:controller => 'roles'}, :caption => :label_role_and_permissions menu.push :trackers, {:controller => 'trackers'}, :caption => :label_tracker_plural diff --git a/spec/models/phone_app_version_spec.rb b/spec/models/phone_app_version_spec.rb new file mode 100644 index 000000000..312833a42 --- /dev/null +++ b/spec/models/phone_app_version_spec.rb @@ -0,0 +1,5 @@ +require 'spec_helper' + +describe PhoneAppVersion do + pending "add some examples to (or delete) #{__FILE__}" +end From e2307366f63e00961bcc1f8942044194976f743f Mon Sep 17 00:00:00 2001 From: sw <939547590@qq.com> Date: Thu, 5 Mar 2015 17:42:31 +0800 Subject: [PATCH 49/97] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E7=BB=84=E7=BB=87?= =?UTF-8?q?=E7=9A=84=E5=A2=9E=E3=80=81=E5=88=A0=E3=80=81=E6=94=B9=E3=80=81?= =?UTF-8?q?=E6=9F=A5=E5=8A=9F=E8=83=BD=E5=8F=8A=E7=9B=B8=E5=85=B3=E7=95=8C?= =?UTF-8?q?=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/organization_controller.rb | 45 ++++++++++++++++++++++ app/views/organization/_form.html.erb | 21 ++++++++++ app/views/organization/edit.html.erb | 25 ++++++++++++ app/views/organization/new.html.erb | 18 +++++++++ config/locales/zh.yml | 2 + 5 files changed, 111 insertions(+) create mode 100644 app/views/organization/_form.html.erb create mode 100644 app/views/organization/edit.html.erb create mode 100644 app/views/organization/new.html.erb diff --git a/app/controllers/organization_controller.rb b/app/controllers/organization_controller.rb index ef0919ced..db8295e44 100644 --- a/app/controllers/organization_controller.rb +++ b/app/controllers/organization_controller.rb @@ -1,5 +1,7 @@ class OrganizationController < ApplicationController layout 'project_base' + before_filter :require_admin, :except => [:index] + def index #@projects = Project.find_by_sql("SELECT * FROM projects WHERE id IN (select MAX(id) from projects GROUP BY enterprise_name)") @organizations = Organization.all @@ -7,4 +9,47 @@ class OrganizationController < ApplicationController format.html end end + + def new + @organizations = Organization.new + respond_to do |format| + format.html + end + end + + def create + @organizations = Organization.new + @organizations.name = params[:organization][:name] + if @organizations.save + redirect_to admin_organization_url + end + end + + def edit + @organization = Organization.find params[:id] + respond_to do |format| + format.html + end + rescue Exception => e + render_404 + end + + def update + @organization = Organization.find params[:id] + @organization.name = params[:organization][:name] + if @organization.save + redirect_to admin_organization_url + end + rescue Exception => e + render_404 + end + + def destroy + @organization = Organization.find params[:id] + if @organization.destroy + redirect_to admin_organization_url + end + rescue Exception => e + render_404 + end end diff --git a/app/views/organization/_form.html.erb b/app/views/organization/_form.html.erb new file mode 100644 index 000000000..80cc76850 --- /dev/null +++ b/app/views/organization/_form.html.erb @@ -0,0 +1,21 @@ +<%= error_messages_for 'project' %> + +<% unless @organizations.new_record? %> +

      + <%= render :partial=>"avatar/avatar_form",:locals=> {source:@organizations} %> +

      +<% end %> +

      + + <%= f.text_field :name, :required => true, :size => 60, :style => "width:290px;" %> +

      + + + <%#= l(:field_description)%> + + + + diff --git a/app/views/organization/edit.html.erb b/app/views/organization/edit.html.erb new file mode 100644 index 000000000..60b7c06a0 --- /dev/null +++ b/app/views/organization/edit.html.erb @@ -0,0 +1,25 @@ +<%= form_for(@organization) do |f|%> +

      + <%=l(:label_organization_edit)%> +

      +
      + <%= error_messages_for 'project' %> +

      + <%= render :partial=>"avatar/avatar_form",:locals=> {source:@organization} %> +

      +

      + + <%= f.text_field :name, :required => true, :size => 60, :style => "width:290px;" %> +

      + + <%= submit_tag l(:button_create), :class => "enterprise"%> + +
      + <%#= submit_tag l(:button_create_and_continue), :name => 'continue' %> + <%= javascript_tag "$('#project_name').focus();" %> +<% end %> + +<% html_title(l(:label_organization_edit)) -%> \ No newline at end of file diff --git a/app/views/organization/new.html.erb b/app/views/organization/new.html.erb new file mode 100644 index 000000000..163f4a5f5 --- /dev/null +++ b/app/views/organization/new.html.erb @@ -0,0 +1,18 @@ +<%= form_for(@organizations, :method => :post, + :name => 'new_form', + :url => {:controller => 'organization', + :action => 'create'}) do |f|%> +

      + <%=l(:label_organization_new)%> +

      +
      + <%= render :partial => 'form', :locals => { :f => f } %> + + <%= submit_tag l(:button_create), :class => "enterprise"%> + +
      + <%#= submit_tag l(:button_create_and_continue), :name => 'continue' %> + <%= javascript_tag "$('#project_name').focus();" %> +<% end %> + +<% html_title(l(:label_organization_new)) -%> \ No newline at end of file diff --git a/config/locales/zh.yml b/config/locales/zh.yml index 231339a8e..72634bd2b 100644 --- a/config/locales/zh.yml +++ b/config/locales/zh.yml @@ -539,8 +539,10 @@ zh: label_activity_project: '项目: ' #added by bai label_organization: 组织 + label_organization_name: 组织名称 label_organization_list: 组织列表 label_organization_new: 新建组织 + label_organization_edit: 修改组织 label_project_plural: 项目列表 label_first_page_made: 首页定制 label_project_first_page: 项目托管平台首页 From 26081c61205d549ffadb52195bd1ddb5f7d87a2e Mon Sep 17 00:00:00 2001 From: sw <939547590@qq.com> Date: Fri, 6 Mar 2015 09:27:43 +0800 Subject: [PATCH 50/97] =?UTF-8?q?=E6=96=B0=E5=BB=BA=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E6=97=B6=E5=A2=9E=E5=8A=A0=E4=B8=8D=E9=80=89=E6=8B=A9=E6=89=80?= =?UTF-8?q?=E5=B1=9E=E7=BB=84=E7=BB=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/helpers/projects_helper.rb | 4 ++++ config/locales/zh.yml | 1 + db/schema.rb | 30 ++++++++++++++---------------- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index ccc750462..3c1663fcb 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -374,6 +374,10 @@ module ProjectsHelper def project_organizations_id_option type = [] + option1 = [] + option1 << l(:label_organization_choose) + option1 << 0 + type << option1 Organization.all.each do |org| option = [] option << org.name diff --git a/config/locales/zh.yml b/config/locales/zh.yml index 72634bd2b..edfea2cb7 100644 --- a/config/locales/zh.yml +++ b/config/locales/zh.yml @@ -539,6 +539,7 @@ zh: label_activity_project: '项目: ' #added by bai label_organization: 组织 + label_organization_choose: --请选择组织-- label_organization_name: 组织名称 label_organization_list: 组织列表 label_organization_new: 新建组织 diff --git a/db/schema.rb b/db/schema.rb index 4a3b14edc..b863dbaed 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 => 20150302091345) do +ActiveRecord::Schema.define(:version => 20150305011359) do create_table "activities", :force => true do |t| t.integer "act_id", :null => false @@ -631,16 +631,6 @@ ActiveRecord::Schema.define(:version => 20150302091345) do add_index "journal_details", ["journal_id"], :name => "journal_details_journal_id" - create_table "journal_details_copy", :force => true do |t| - t.integer "journal_id", :default => 0, :null => false - t.string "property", :limit => 30, :default => "", :null => false - t.string "prop_key", :limit => 30, :default => "", :null => false - t.text "old_value" - t.text "value" - end - - add_index "journal_details_copy", ["journal_id"], :name => "journal_details_journal_id" - create_table "journal_replies", :id => false, :force => true do |t| t.integer "journal_id" t.integer "user_id" @@ -825,6 +815,13 @@ ActiveRecord::Schema.define(:version => 20150302091345) do t.integer "project_id" end + create_table "organizations", :force => true do |t| + t.string "name" + t.string "logo_link" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + create_table "poll_answers", :force => true do |t| t.integer "poll_question_id" t.text "answer_text" @@ -949,6 +946,7 @@ ActiveRecord::Schema.define(:version => 20150302091345) do t.integer "user_id" t.integer "dts_test", :default => 0 t.string "enterprise_name" + t.integer "organization_id" end add_index "projects", ["lft"], :name => "index_projects_on_lft" @@ -1036,12 +1034,12 @@ ActiveRecord::Schema.define(:version => 20150302091345) do end create_table "roles", :force => true do |t| - t.string "name", :limit => 90 - t.integer "position" - t.boolean "assignable" - t.integer "builtin" + t.string "name", :limit => 30, :default => "", :null => false + t.integer "position", :default => 1 + t.boolean "assignable", :default => true + t.integer "builtin", :default => 0, :null => false t.text "permissions" - t.string "issues_visibility", :limit => 90 + t.string "issues_visibility", :limit => 30, :default => "default", :null => false end create_table "schools", :force => true do |t| From 3c1f1d8baddb12647d6a99ec5baa8e13ac078898 Mon Sep 17 00:00:00 2001 From: sw <939547590@qq.com> Date: Fri, 6 Mar 2015 09:45:38 +0800 Subject: [PATCH 51/97] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=83=A8=E5=88=86?= =?UTF-8?q?=E6=B5=8F=E8=A7=88=E5=99=A8=E4=B8=8B=E5=8F=91=E5=B8=83=E9=97=AE?= =?UTF-8?q?=E5=8D=B7=E3=80=81=E5=8F=96=E6=B6=88=E5=8F=91=E5=B8=83=E9=97=AE?= =?UTF-8?q?=E5=8D=B7=E6=A0=B7=E5=BC=8F=E6=98=BE=E7=A4=BA=E4=B8=8D=E6=AD=A3?= =?UTF-8?q?=E7=A1=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/poll/publish_poll.js.erb | 2 +- app/views/poll/republish_poll.js.erb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/poll/publish_poll.js.erb b/app/views/poll/publish_poll.js.erb index 6074df6c6..2e8dab181 100644 --- a/app/views/poll/publish_poll.js.erb +++ b/app/views/poll/publish_poll.js.erb @@ -1,6 +1,6 @@ $("#polls_<%= @poll.id %>").html("<%= escape_javascript(render :partial => 'poll',:locals => {:poll => @poll}) %>"); $('#ajax-modal').html("<%= escape_javascript(render :partial => 'alert', locals: { :message => l(:label_memo_create_succ)}) %>"); -showModal('ajax-modal', '180px'); +showModal('ajax-modal', '250px'); $('#ajax-modal').css('height','111px'); $('#ajax-modal').siblings().remove(); $('#ajax-modal').before("" + diff --git a/app/views/poll/republish_poll.js.erb b/app/views/poll/republish_poll.js.erb index 94369678d..f2fcee96a 100644 --- a/app/views/poll/republish_poll.js.erb +++ b/app/views/poll/republish_poll.js.erb @@ -1,6 +1,6 @@ $("#polls_<%= @poll.id %>").html("<%= escape_javascript(render :partial => 'poll',:locals => {:poll => @poll}) %>"); $('#ajax-modal').html("<%= escape_javascript(render :partial => 'alert', locals: { :message => l(:label_poll_republish_success)}) %>"); -showModal('ajax-modal', '180px'); +showModal('ajax-modal', '250px'); $('#ajax-modal').css('height','80px'); $('#ajax-modal').siblings().remove(); $('#ajax-modal').before("" + From 5692cbf2020a74ecb552028136e157dabbfcd459 Mon Sep 17 00:00:00 2001 From: sw <939547590@qq.com> Date: Fri, 6 Mar 2015 09:50:17 +0800 Subject: [PATCH 52/97] =?UTF-8?q?#1965=20=E5=85=AC=E5=85=B1=E8=B4=B4?= =?UTF-8?q?=E5=90=A7=E5=8F=96=E6=B6=88=E8=BD=AF=E4=BB=B6=E5=88=9B=E5=AE=A2?= =?UTF-8?q?=E5=85=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/helpers/application_helper.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 5579fe79b..1ac0a5bbf 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1841,7 +1841,7 @@ module ApplicationHelper # course_all_course_link = link_to l(:label_course_all), {:controller => 'courses', :action => 'index'} course_teacher_all_link = link_to l(:label_teacher_all), {:controller => 'users', :action => 'index', :role => 'teacher', :host => Setting.course_domain} # courses_link = link_to l(:label_course_practice), {:controller => 'courses', :action => 'index'} - users_link = link_to l(:label_software_user), {:controller => 'users', :action => 'index', :host => Setting.user_domain} + #users_link = link_to l(:label_software_user), {:controller => 'users', :action => 'index', :host => Setting.user_domain} # contest_link = link_to l(:label_contest_innovate), {:controller => 'contests', :action => 'index'} bids_link = link_to l(:label_requirement_enterprise), {:controller => 'bids', :action => 'index'} forum_link = link_to l(:label_forum_all), {:controller => "forums", :action => "index"} @@ -1860,7 +1860,7 @@ module ApplicationHelper nav_list.push(courses_link) if @nav_dispaly_course_label && @show_course == 1 # nav_list.push(projects_link) if @nav_dispaly_project_label - nav_list.push(users_link) if @nav_dispaly_user_label + #nav_list.push(users_link) if @nav_dispaly_user_label # nav_list.push(contest_link) if @nav_dispaly_contest_label && @show_contest == 1 nav_list.push(bids_link) if @nav_dispaly_bid_label nav_list.push(forum_link) if @nav_dispaly_forum_label From e32693402761a8ae09bd3698b346644553a5c514 Mon Sep 17 00:00:00 2001 From: sw <939547590@qq.com> Date: Fri, 6 Mar 2015 10:58:12 +0800 Subject: [PATCH 53/97] =?UTF-8?q?=E8=B0=83=E6=95=B4=E7=BB=84=E7=BB=87?= =?UTF-8?q?=E9=A6=96=E9=A1=B5=E7=BC=BA=E5=B0=91=E9=A1=B9=E7=9B=AE=E6=97=B6?= =?UTF-8?q?=E7=9A=84=E6=98=BE=E7=A4=BA=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/welcome/index.html.erb | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/app/views/welcome/index.html.erb b/app/views/welcome/index.html.erb index a2fb9657a..b1a699afa 100644 --- a/app/views/welcome/index.html.erb +++ b/app/views/welcome/index.html.erb @@ -94,9 +94,13 @@ <% @organization_projects.map do |project| %> <%= render :partial => 'hot_projects_list', :locals => {:project => project} %> <% end %> -
      - <%= l(:label_part_enterprise_tips) %> -
      +
    • +

      +
      + <%= l(:label_part_enterprise_tips) %> +
      +

      +
    • <% @part_projects.map do |project| %> <%= render :partial => 'hot_projects_list', :locals => {:project => project} %> <% end %> From 140cb81748976481e3569b581b8061e9dd463700 Mon Sep 17 00:00:00 2001 From: lizanle <491823689@qq.com> Date: Fri, 6 Mar 2015 11:38:32 +0800 Subject: [PATCH 54/97] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E7=89=88=E5=8F=91?= =?UTF-8?q?=E5=B8=83=E8=AF=BE=E7=A8=8B=E9=80=9A=E7=9F=A5=E5=92=8C=E8=AE=A8?= =?UTF-8?q?=E8=AE=BA=E5=8C=BA=E5=8F=91=E5=B8=83=E6=96=B0=E5=B8=96=E6=8A=A5?= =?UTF-8?q?500?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/message.rb | 7 +++++-- app/models/news.rb | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/app/models/message.rb b/app/models/message.rb index 413a4f91c..85a87132d 100644 --- a/app/models/message.rb +++ b/app/models/message.rb @@ -164,8 +164,11 @@ class Message < ActiveRecord::Base # Author lizanle # Description def act_as_forge_activity - self.forge_acts << ForgeActivity.new(:user_id => self.author_id, - :project_id => self.board.project.id) + # 如果project为空,那么就是课程相关的消息 + if !self.board.project.nil? + self.forge_acts << ForgeActivity.new(:user_id => self.author_id, + :project_id => self.board.project.id) + end end #更新用户分数 -by zjc diff --git a/app/models/news.rb b/app/models/news.rb index fa9f31712..d2547fc02 100644 --- a/app/models/news.rb +++ b/app/models/news.rb @@ -98,8 +98,11 @@ class News < ActiveRecord::Base # Author lizanle # Description 公用表中也要记录 def act_as_forge_activity - self.forge_acts << ForgeActivity.new(:user_id => self.author_id, - :project_id => self.project.id) + # 如果是project为空,那么是课程相关的,不需要保存 + if !self.project.nil? + self.forge_acts << ForgeActivity.new(:user_id => self.author_id, + :project_id => self.project.id) + end end end From 10faab012967ac375694fa917d6911da3326dbf9 Mon Sep 17 00:00:00 2001 From: lizanle <491823689@qq.com> Date: Fri, 6 Mar 2015 11:53:16 +0800 Subject: [PATCH 55/97] =?UTF-8?q?=E6=96=B0=E5=BB=BA=E7=9A=84=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E5=8F=91=E5=B8=83=E6=96=B0=E9=97=AE=E9=A2=98=E6=8A=A5?= =?UTF-8?q?500?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/issues_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb index 5dc945cc7..d429f9d3e 100644 --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -154,7 +154,7 @@ class IssuesController < ApplicationController call_hook(:controller_issues_new_before_save, { :params => params, :issue => @issue }) @issue.save_attachments(params[:attachments] || (params[:issue] && params[:issue][:uploads])) # 给该issue在它所在的项目中所有的issues中所在的位置给一个序号 - @issue.project_issues_index = @issue.project.issues.last.project_issues_index + 1 + @issue.project_issues_index = @issue.project.issues.last.nil? ? 1 : @issue.project.issues.last.project_issues_index + 1 if @issue.save call_hook(:controller_issues_new_after_save, { :params => params, :issue => @issue}) respond_to do |format| From beac15475dd9fdbd6441083fcab379c75dd7e1f6 Mon Sep 17 00:00:00 2001 From: huang Date: Fri, 6 Mar 2015 14:55:21 +0800 Subject: [PATCH 56/97] =?UTF-8?q?=E6=96=B0=E9=A1=B9=E7=9B=AE=E5=8F=8A?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E5=8F=8D=E9=A6=88=E6=A1=86=E7=9A=84=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=EF=BC=81=EF=BC=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/boards_controller.rb | 1 + app/controllers/documents_controller.rb | 4 + app/controllers/files_controller.rb | 6 +- app/controllers/issues_controller.rb | 2 + app/controllers/projects_controller.rb | 22 +- app/helpers/application_helper.rb | 2 +- app/helpers/watchers_helper.rb | 2 +- app/views/boards/_project_show.html.erb | 8 +- app/views/calendars/show.html.erb | 4 +- app/views/documents/index.html.erb | 27 +- app/views/documents/show.html.erb | 4 +- app/views/files/_newfile_index.html.erb | 250 +++++++++++++++ app/views/files/_project_file.html.erb | 9 +- app/views/files/index.html.erb | 251 +-------------- app/views/files/index.js.erb | 2 + app/views/files/new.html.erb | 4 +- app/views/gantts/show.html.erb | 6 +- app/views/issues/_newissue_index.html.erb | 137 ++++++++ app/views/issues/index.html.erb | 136 +------- app/views/issues/index.js.erb | 1 + app/views/issues/new.html.erb | 3 + app/views/issues/show.html.erb | 5 +- app/views/layouts/_base_feedback.html.erb | 63 ++-- app/views/layouts/_join_exit_project.html.erb | 24 +- app/views/layouts/base_projects.html.erb | 296 +++++++++--------- app/views/projects/_form.html.erb | 2 +- app/views/projects/_newproject_show.html.erb | 107 +++++++ app/views/projects/_tools_expand.html.erb | 62 ++-- app/views/projects/feedback.html.erb | 3 + app/views/projects/member.html.erb | 7 +- app/views/projects/new.html.erb | 4 +- app/views/projects/settings.html.erb | 4 +- app/views/projects/share.html.erb | 4 +- app/views/projects/show.html.erb | 105 +------ app/views/projects/show.js.erb | 1 + app/views/projects/watcherlist.html.erb | 4 +- app/views/repositories/new.html.erb | 4 +- app/views/repositories/show.html.erb | 4 +- app/views/wiki/show.html.erb | 99 +++--- app/views/words/_new.html.erb | 5 +- config/locales/zh.yml | 3 +- .../app/views/code_review/index.html.erb | 6 +- public/images/sidebar_bg.png | Bin 9419 -> 9739 bytes public/stylesheets/application.css | 129 +++++++- .../stylesheets/application.css | 108 +++---- 45 files changed, 1034 insertions(+), 896 deletions(-) create mode 100644 app/views/files/_newfile_index.html.erb create mode 100644 app/views/files/index.js.erb create mode 100644 app/views/issues/_newissue_index.html.erb create mode 100644 app/views/issues/index.js.erb create mode 100644 app/views/projects/_newproject_show.html.erb create mode 100644 app/views/projects/show.js.erb diff --git a/app/controllers/boards_controller.rb b/app/controllers/boards_controller.rb index 383da0bbe..67355fdfa 100644 --- a/app/controllers/boards_controller.rb +++ b/app/controllers/boards_controller.rb @@ -57,6 +57,7 @@ class BoardsController < ApplicationController def show respond_to do |format| + format.js format.html { sort_init 'updated_on', 'desc' sort_update 'created_on' => "#{Message.table_name}.created_on", diff --git a/app/controllers/documents_controller.rb b/app/controllers/documents_controller.rb index 932ffaa7a..545d61155 100644 --- a/app/controllers/documents_controller.rb +++ b/app/controllers/documents_controller.rb @@ -61,6 +61,10 @@ class DocumentsController < ApplicationController if @project.project_type ==1 render :action => 'show', :layout => 'base_courses' end + respond_to do |format| + format.html + format.api + end end def new diff --git a/app/controllers/files_controller.rb b/app/controllers/files_controller.rb index 56f760e13..8421e9be1 100644 --- a/app/controllers/files_controller.rb +++ b/app/controllers/files_controller.rb @@ -148,7 +148,11 @@ class FilesController < ApplicationController show_attachments @containers - render :layout => !request.xhr? + + respond_to do |format| + format.html + format.js + end elsif params[:course_id] @isproject = false diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb index c0d83fdcd..4e3c28468 100644 --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -90,6 +90,7 @@ class IssuesController < ApplicationController respond_to do |format| + format.js format.html { render :template => 'issues/index', :layout => @project_base_tag }#by young format.api { Issue.load_visible_relations(@issues) if include_in_api_response?('relations') @@ -103,6 +104,7 @@ class IssuesController < ApplicationController format.html { render(:template => 'issues/index', :layout => @project_base_tag) }#by young format.any(:atom, :csv, :pdf) { render(:nothing => true) } format.api { render_validation_errors(@query) } + format.js end end rescue ActiveRecord::RecordNotFound diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 02bfc9e19..c67b5197b 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -278,7 +278,7 @@ class ProjectsController < ApplicationController :with_subprojects => @with_subprojects, :author => @author) @activity.scope_select {|t| !has["show_#{t}"].nil?} - + # 根据私密性,取出符合条件的所有数据 if User.current.member_of?(@project) || User.current.admin? events = @activity.events(@date_from, @date_to) @@ -286,7 +286,6 @@ class ProjectsController < ApplicationController events = @activity.events(@date_from, @date_to, :is_public => 1) end - @offset, @limit = api_offset_and_limit({:limit => 10}) @events_count = events.count @events_pages = Paginator.new @events_count, @limit, params['page'] @@ -295,11 +294,14 @@ class ProjectsController < ApplicationController events = events.slice(@offset,@limit) # 按天分组 @events_by_day = events.group_by {|event| User.current.time_to_date(event.event_datetime)} - + # 获取讨论区总数 + boards = @project.boards.includes(:last_message => :author).all + @topic_count = @project.boards.count # 根据对应的请求,返回对应的数据 respond_to do |format| format.html format.api + format.js end end @@ -311,6 +313,20 @@ class ProjectsController < ApplicationController @wiki ||= @project.wiki end + + #发送邮件邀请新用户 + def invite_members_by_mail + + end + + # 邀请Trustie注册用户 + def invite_members_had_loged + @member ||= @project.members.new + respond_to do |format| + format.js + end + end + def edit end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 5579fe79b..dbe292f76 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -48,7 +48,7 @@ module ApplicationHelper def authorize_for(controller, action) User.current.allowed_to?({:controller => controller, :action => action}, @project) end - + # add by nwb def authorize_for_course(controller, action) User.current.allowed_to?({:controller => controller, :action => action}, @course) diff --git a/app/helpers/watchers_helper.rb b/app/helpers/watchers_helper.rb index 842e1f1b7..f47ced545 100644 --- a/app/helpers/watchers_helper.rb +++ b/app/helpers/watchers_helper.rb @@ -283,6 +283,6 @@ module WatchersHelper def exit_project_link(project) link_to(l(:label_exit_project),exit_cur_project_path(project.id), - :remote => true, :confirm => l(:lable_sure_exit_project) ) + :remote => true, :confirm => l(:lable_sure_exit_project), :style => "color: #fff; display:block; padding: 0px 5px;margin-right:10px;height:20px;text-aligh:center;" ) end end diff --git a/app/views/boards/_project_show.html.erb b/app/views/boards/_project_show.html.erb index 1a5cbd2fa..97ed903d9 100644 --- a/app/views/boards/_project_show.html.erb +++ b/app/views/boards/_project_show.html.erb @@ -9,9 +9,7 @@ -
      - <%= h @board.name %> +
      +

      <%= h @board.name %>

      <% if !User.current.logged? %> diff --git a/app/views/calendars/show.html.erb b/app/views/calendars/show.html.erb index dae061251..39cab4a53 100644 --- a/app/views/calendars/show.html.erb +++ b/app/views/calendars/show.html.erb @@ -1,4 +1,6 @@ -

      <%= @query.new_record? ? l(:label_calendar) : h(@query.name) %>

      +
      +

      <%= @query.new_record? ? l(:label_calendar) : h(@query.name) %>

      +
      <%= form_tag({:controller => 'calendars', :action => 'show', :project_id => @project}, :method => :get, :id => 'query_form') do %> diff --git a/app/views/documents/index.html.erb b/app/views/documents/index.html.erb index f7f76a812..e0c39eb33 100644 --- a/app/views/documents/index.html.erb +++ b/app/views/documents/index.html.erb @@ -1,3 +1,6 @@ +
      +

      <%=l(:label_document_plural)%>

      +
      <%= l(:label_documents_sort) %> @@ -8,24 +11,22 @@ | <%= link_to l(:label_document_new), new_project_document_path(@project), :class => 'icon icon-add', - :onclick => 'showAndScrollTo("add-document", "document_title"); return false;' if User.current.allowed_to?(:add_documents, @project) %> + :onclick => 'showAndScrollTo("add-document", "document_title"); return false;' if User.current.allowed_to?(:add_documents, @project) %>
      -

      <%=l(:label_document_plural)%>

      - <% if @grouped.empty? %>

      <%= l(:label_no_data) %> diff --git a/app/views/documents/show.html.erb b/app/views/documents/show.html.erb index 45f54ad9b..5632c9d63 100644 --- a/app/views/documents/show.html.erb +++ b/app/views/documents/show.html.erb @@ -1,3 +1,6 @@ +

      +

      <%=h @document.title %>

      +
      @@ -9,7 +12,6 @@ <% end %>
      -

      <%=h @document.title %>

      <%#=h @document.category.name %>
      <%= format_date @document.created_on %>

      diff --git a/app/views/files/_newfile_index.html.erb b/app/views/files/_newfile_index.html.erb new file mode 100644 index 000000000..5ffaacae4 --- /dev/null +++ b/app/views/files/_newfile_index.html.erb @@ -0,0 +1,250 @@ + +
      + <% if @isproject %> + <%= render :partial => 'project_file', locals: {project: @project} %> + <% else %> + <%= render :partial => 'course_file', locals: {course: @course} %> + <% end %> +
      + + + + + diff --git a/app/views/files/_project_file.html.erb b/app/views/files/_project_file.html.erb index e2f928332..e204030f1 100644 --- a/app/views/files/_project_file.html.erb +++ b/app/views/files/_project_file.html.erb @@ -1,11 +1,8 @@ - <% attachmenttypes = @project.attachmenttypes %> <% sufixtypes = @project.contenttypes %> - - - <%= (@project.project_type == 1) ? t(:label_user_course) : t(:label_project) %> - 资源共享区 - +
      +

      资源共享区

      +
      <%#= link_to(l(:label_attachment_new), 'javascript:void(0);', :onclick=>"$('#file_buttons').slideToggle();", :class => 'icon icon-add') if User.current.allowed_to?(:manage_files, @project) %> diff --git a/app/views/files/index.html.erb b/app/views/files/index.html.erb index fe04c4e3f..39bc8b52e 100644 --- a/app/views/files/index.html.erb +++ b/app/views/files/index.html.erb @@ -1,250 +1 @@ - -
      -<% if @isproject %> - <%= render :partial => 'project_file', locals: {project: @project} %> -<% else %> - <%= render :partial => 'course_file', locals: {course: @course} %> -<% end %> -
      - - - - - +<%= render :partial => 'files/newfile_index' %> \ No newline at end of file diff --git a/app/views/files/index.js.erb b/app/views/files/index.js.erb new file mode 100644 index 000000000..59bc2407f --- /dev/null +++ b/app/views/files/index.js.erb @@ -0,0 +1,2 @@ +alert("eeee"); +$('#content').html('<%= escape_javascript(render :partial => 'issues/newissue_index') %>'); diff --git a/app/views/files/new.html.erb b/app/views/files/new.html.erb index 8fd99b195..be9bcd722 100644 --- a/app/views/files/new.html.erb +++ b/app/views/files/new.html.erb @@ -1,4 +1,6 @@ -

      <%=l(:label_attachment_new)%>

      +
      +

      <%=l(:label_attachment_new)%>

      +
      <%= error_messages_for 'attachment' %> <%= form_tag(project_files_path(@project), :multipart => true, :class => "tabular") do %> diff --git a/app/views/gantts/show.html.erb b/app/views/gantts/show.html.erb index 6ec189256..2808a99cc 100644 --- a/app/views/gantts/show.html.erb +++ b/app/views/gantts/show.html.erb @@ -1,5 +1,7 @@ -<% @gantt.view = self %> -

      <%= @query.new_record? ? l(:label_gantt) : h(@query.name) %>

      +
      +

      <% @gantt.view = self %> + <%= @query.new_record? ? l(:label_gantt) : h(@query.name) %>

      +
      <%= form_tag({:controller => 'gantts', :action => 'show', :project_id => @project, :month => params[:month], diff --git a/app/views/issues/_newissue_index.html.erb b/app/views/issues/_newissue_index.html.erb new file mode 100644 index 000000000..f0b7c0108 --- /dev/null +++ b/app/views/issues/_newissue_index.html.erb @@ -0,0 +1,137 @@ +
      +

      问题跟踪

      +
      +
      + <% if @project.enabled_modules.where("name = 'issue_tracking'").count > 0 %> + + <%= link_to l(:label_issue_new), {:controller => 'issues', :action => 'new', :copy_from => nil}, :param => :project_id, :caption => :label_issue_new, + :html => {:accesskey => Redmine::AccessKeys.key_for(:new_issue)}, :class => 'icon icon-add' %> + <%= link_to l(:label_query), '#', :class => 'icon icon-help', + :onclick => '$("#custom_query").slideToggle(400); ' if true || User.current.logged? %> + + <% end %> + 问题总数:100 未解决:20 +
      +
      + <% if !@query.new_record? && @query.editable_by?(User.current) %> + <%= link_to l(:button_edit), edit_query_path(@query), :class => 'icon icon-edit' %> + <%= delete_link query_path(@query) %> + <% end %> +
      + +<% html_title(@query.new_record? ? l(:label_issue_plural) : @query.name) %> +
      + <%= form_tag({:controller => 'issues', :action => 'index', :project_id => @project}, :method => :get, :id => 'query_form', :class => 'query_form') do %> + <%= hidden_field_tag 'set_filter', '1' %> + +
      + ---<%= l :label_query_new %>--- + +
      +
      "> + + <%= l(:label_issue_query_condition) %> + +
      "> + <%= render :partial => 'queries/filters', :locals => {:query => @query} %> +
      +
      + +
      + <%= link_to_function l(:label_issue_query), 'submit_query_form("query_form")', :class => 'icon icon-checked' %> + <%= link_to l(:label_issue_cancel_query), {:set_filter => 1, :project_id => @project}, :class => 'icon icon-reload' %> +
      +
      +
      + <% end %> +
      + +<%= error_messages_for 'query' %> + +<% if @query.valid? %> + <% if @issues.empty? %> +

      + <%= l(:label_no_data) %> +

      + <% else %> + <%= render :partial => 'issues/list', :locals => {:issues => @issues, :query => @query} %> + + <% end %> +
      + <% other_formats_links do |f| %> + <%= f.link_to 'Atom', :url => params.merge(:key => User.current.rss_key) %> + <%= f.link_to 'CSV', :url => params, :onclick => "showModal('csv-export-options', '330px'); return false;" %> + <%= f.link_to 'PDF', :url => params %> + <% end %> +
      + + + + +<% end %> + +<%= call_hook(:view_issues_index_bottom, {:issues => @issues, :project => @project, :query => @query}) %> + +<% content_for :sidebar do %> + <%= render :partial => 'issues/sidebar' %> +<% end %> + +<% content_for :header_tags do %> + <%= auto_discovery_link_tag(:atom, + {:query_id => @query, :format => 'atom', + :page => nil, :key => User.current.rss_key}, + :title => l(:label_issue_plural)) %> + <%= auto_discovery_link_tag(:atom, + {:controller => 'journals', :action => 'index', + :query_id => @query, :format => 'atom', + :page => nil, :key => User.current.rss_key}, + :title => l(:label_changes_details)) %> +<% end %> + +<%= context_menu issues_context_menu_path %> diff --git a/app/views/issues/index.html.erb b/app/views/issues/index.html.erb index 219a0f641..b3750a770 100644 --- a/app/views/issues/index.html.erb +++ b/app/views/issues/index.html.erb @@ -1,135 +1 @@ -
      - <% if @project.enabled_modules.where("name = 'issue_tracking'").count > 0 %> -
      - <%= link_to l(:label_issue_new), {:controller => 'issues', :action => 'new', :copy_from => nil}, :param => :project_id, :caption => :label_issue_new, - :html => {:accesskey => Redmine::AccessKeys.key_for(:new_issue)}, :class => 'icon icon-add' %> - - <%= link_to l(:label_query), '#', :class => 'icon icon-help', - :onclick => '$("#custom_query").slideToggle(400); ' if true || User.current.logged? %> -
      - <% end %> -
      - -
      - <% if !@query.new_record? && @query.editable_by?(User.current) %> - <%= link_to l(:button_edit), edit_query_path(@query), :class => 'icon icon-edit' %> - <%= delete_link query_path(@query) %> - <% end %> -
      - -<% html_title(@query.new_record? ? l(:label_issue_plural) : @query.name) %> -
      - <%= form_tag({:controller => 'issues', :action => 'index', :project_id => @project}, :method => :get, :id => 'query_form', :class => 'query_form') do %> - <%= hidden_field_tag 'set_filter', '1' %> - -
      - ---<%= l :label_query_new %>--- - -
      -
      "> - - <%= l(:label_issue_query_condition) %> - -
      "> - <%= render :partial => 'queries/filters', :locals => {:query => @query} %> -
      -
      - -
      - <%= link_to_function l(:label_issue_query), 'submit_query_form("query_form")', :class => 'icon icon-checked' %> - <%= link_to l(:label_issue_cancel_query), {:set_filter => 1, :project_id => @project}, :class => 'icon icon-reload' %> -
      -
      -
      - <% end %> -
      - -<%= error_messages_for 'query' %> - -<% if @query.valid? %> - <% if @issues.empty? %> -

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

      - <% else %> - <%= render :partial => 'issues/list', :locals => {:issues => @issues, :query => @query} %> - - <% end %> -
      - <% other_formats_links do |f| %> - <%= f.link_to 'Atom', :url => params.merge(:key => User.current.rss_key) %> - <%= f.link_to 'CSV', :url => params, :onclick => "showModal('csv-export-options', '330px'); return false;" %> - <%= f.link_to 'PDF', :url => params %> - <% end %> -
      - - - - -<% end %> - -<%= call_hook(:view_issues_index_bottom, {:issues => @issues, :project => @project, :query => @query}) %> - -<% content_for :sidebar do %> - <%= render :partial => 'issues/sidebar' %> -<% end %> - -<% content_for :header_tags do %> - <%= auto_discovery_link_tag(:atom, - {:query_id => @query, :format => 'atom', - :page => nil, :key => User.current.rss_key}, - :title => l(:label_issue_plural)) %> - <%= auto_discovery_link_tag(:atom, - {:controller => 'journals', :action => 'index', - :query_id => @query, :format => 'atom', - :page => nil, :key => User.current.rss_key}, - :title => l(:label_changes_details)) %> -<% end %> - -<%= context_menu issues_context_menu_path %> +<%= render :partial => 'issues/newissue_index' %> \ No newline at end of file diff --git a/app/views/issues/index.js.erb b/app/views/issues/index.js.erb new file mode 100644 index 000000000..866882053 --- /dev/null +++ b/app/views/issues/index.js.erb @@ -0,0 +1 @@ +$('#content').html('<%= escape_javascript(render :partial => 'issues/newissue_index') %>'); diff --git a/app/views/issues/new.html.erb b/app/views/issues/new.html.erb index 05ec50c11..51ebd139e 100644 --- a/app/views/issues/new.html.erb +++ b/app/views/issues/new.html.erb @@ -1,3 +1,6 @@ +
      +

      问题跟踪

      +
      <%= call_hook(:view_issues_new_top, {:issue => @issue}) %> <%= labelled_form_for @issue, :url => project_issues_path(@project), diff --git a/app/views/issues/show.html.erb b/app/views/issues/show.html.erb index 204dd519a..47ba63ebf 100644 --- a/app/views/issues/show.html.erb +++ b/app/views/issues/show.html.erb @@ -1,5 +1,6 @@ -<%# html_title "#{@issue.tracker.name} ##{@issue.id}: #{@issue.subject}" %> - +
      +

      问题跟踪

      +
      <% html_title "#{@issue.tracker.name} #{@issue.source_from}: #{@issue.subject}" %> <%= render :partial => 'action_menu' %> diff --git a/app/views/layouts/_base_feedback.html.erb b/app/views/layouts/_base_feedback.html.erb index c4479b43a..2444af68c 100644 --- a/app/views/layouts/_base_feedback.html.erb +++ b/app/views/layouts/_base_feedback.html.erb @@ -1,32 +1,30 @@