diff --git a/.gitignore b/.gitignore index 944ad4ef2..af337a4e7 100644 --- a/.gitignore +++ b/.gitignore @@ -7,8 +7,11 @@ /config/configuration.yml /files/* /log/* +/public/tmp/* /tmp/* +/public/cache/* .gitignore +/config/newrelic.yml /public/images/avatars/* /Gemfile /Gemfile.lock @@ -16,3 +19,5 @@ /Gemfile.lock /lib/plugins/acts_as_versioned/test/debug.log .rbenv-gemsets +.DS_Store +public/api_doc/ diff --git a/.metadata/.log b/.metadata/.log index 0cb16378c..ea77ea8b9 100644 --- a/.metadata/.log +++ b/.metadata/.log @@ -209,3 +209,60 @@ java.lang.UnsupportedOperationException: Not supported yet. at com.aptana.index.core.IndexRequestJob.indexFileStores(IndexRequestJob.java:205) at com.aptana.index.core.IndexContainerJob.run(IndexContainerJob.java:114) at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54) +!SESSION 2015-01-17 11:30:30.655 ----------------------------------------------- +eclipse.buildId=unknown +java.version=1.6.0_24 +java.vendor=Sun Microsystems Inc. +BootLoader constants: OS=win32, ARCH=x86, WS=win32, NL=zh_CN +Command-line arguments: -os win32 -ws win32 -arch x86 + +!ENTRY org.eclipse.core.resources 4 567 2015-01-17 11:30:37.624 +!MESSAGE Workspace restored, but some problems occurred. +!SUBENTRY 1 org.eclipse.core.resources 4 567 2015-01-17 11:30:37.624 +!MESSAGE Could not read metadata for 'demo'. +!STACK 1 +org.eclipse.core.internal.resources.ResourceException: The project description file (.project) for 'demo' is missing. This file contains important information about the project. The project will not function properly until this file is restored. + at org.eclipse.core.internal.localstore.FileSystemResourceManager.read(FileSystemResourceManager.java:851) + at org.eclipse.core.internal.resources.SaveManager.restoreMetaInfo(SaveManager.java:874) + at org.eclipse.core.internal.resources.SaveManager.restoreMetaInfo(SaveManager.java:854) + at org.eclipse.core.internal.resources.SaveManager.restore(SaveManager.java:703) + at org.eclipse.core.internal.resources.SaveManager.startup(SaveManager.java:1528) + at org.eclipse.core.internal.resources.Workspace.startup(Workspace.java:2503) + at org.eclipse.core.internal.resources.Workspace.open(Workspace.java:2251) + at org.eclipse.core.resources.ResourcesPlugin.start(ResourcesPlugin.java:439) + at org.eclipse.osgi.framework.internal.core.BundleContextImpl$1.run(BundleContextImpl.java:711) + at java.security.AccessController.doPrivileged(Native Method) + at org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:702) + at org.eclipse.osgi.framework.internal.core.BundleContextImpl.start(BundleContextImpl.java:683) + at org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(BundleHost.java:381) + at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:299) + at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:440) + at org.eclipse.osgi.internal.loader.BundleLoader.setLazyTrigger(BundleLoader.java:268) + at org.eclipse.core.runtime.internal.adaptor.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107) + at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findLocalClass(ClasspathManager.java:463) + at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.findLocalClass(DefaultClassLoader.java:216) + at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:400) + at org.eclipse.osgi.internal.loader.SingleSourcePackage.loadClass(SingleSourcePackage.java:35) + at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:473) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:429) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:417) + at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107) + at java.lang.ClassLoader.loadClass(Unknown Source) + at com.aptana.rcp.IDEApplication.start(IDEApplication.java:125) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) + at java.lang.reflect.Method.invoke(Unknown Source) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:577) + at org.eclipse.equinox.launcher.Main.run(Main.java:1410) +!SUBENTRY 2 org.eclipse.core.resources 4 567 2015-01-17 11:30:37.626 +!MESSAGE The project description file (.project) for 'demo' is missing. This file contains important information about the project. The project will not function properly until this file is restored. + +!ENTRY org.eclipse.core.jobs 2 2 2015-01-17 11:33:58.913 +!MESSAGE Job found still running after platform shutdown. Jobs should be canceled by the plugin that scheduled them during shutdown: com.aptana.usage.internal.DefaultAnalyticsEventHandler$1 diff --git a/.metadata/.plugins/com.aptana.core.io/connections.9 b/.metadata/.plugins/com.aptana.core.io/connections.9 deleted file mode 100644 index 4371c4759..000000000 --- a/.metadata/.plugins/com.aptana.core.io/connections.9 +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/.metadata/.plugins/com.aptana.syncing.core/defaultConnection.9 b/.metadata/.plugins/com.aptana.syncing.core/defaultConnection.9 deleted file mode 100644 index 375897785..000000000 --- a/.metadata/.plugins/com.aptana.syncing.core/defaultConnection.9 +++ /dev/null @@ -1,7 +0,0 @@ - - - -Default -file:/C:/Users/nudt - - \ No newline at end of file diff --git a/.metadata/.plugins/com.aptana.syncing.core/sites.9 b/.metadata/.plugins/com.aptana.syncing.core/sites.9 deleted file mode 100644 index d9b475695..000000000 --- a/.metadata/.plugins/com.aptana.syncing.core/sites.9 +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/.metadata/.plugins/com.aptana.webserver.core/webservers.8 b/.metadata/.plugins/com.aptana.webserver.core/webservers.8 deleted file mode 100644 index 5c07542b1..000000000 --- a/.metadata/.plugins/com.aptana.webserver.core/webservers.8 +++ /dev/null @@ -1,6 +0,0 @@ - - - -demo - - \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.index b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.index index fddafcbcd..83f5328be 100644 Binary files a/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.index and b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.index differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.root/2.tree b/.metadata/.plugins/org.eclipse.core.resources/.root/2.tree deleted file mode 100644 index 5b2529389..000000000 Binary files a/.metadata/.plugins/org.eclipse.core.resources/.root/2.tree and /dev/null differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.root/4.tree b/.metadata/.plugins/org.eclipse.core.resources/.root/4.tree new file mode 100644 index 000000000..942a97c51 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.root/4.tree differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.safetable/com.aptana.core.io.15 b/.metadata/.plugins/org.eclipse.core.resources/.safetable/com.aptana.core.io.15 new file mode 100644 index 000000000..971c3ef7e --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.safetable/com.aptana.core.io.15 @@ -0,0 +1,3 @@ +#safe table +#Mon Jan 05 10:27:54 CST 2015 +connections=connections.15 diff --git a/.metadata/.plugins/org.eclipse.core.resources/.safetable/com.aptana.core.io.9 b/.metadata/.plugins/org.eclipse.core.resources/.safetable/com.aptana.core.io.9 deleted file mode 100644 index 0b4ef3b47..000000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.safetable/com.aptana.core.io.9 +++ /dev/null @@ -1,3 +0,0 @@ -#safe table -#Tue Mar 11 17:27:27 CST 2014 -connections=connections.9 diff --git a/.metadata/.plugins/org.eclipse.core.resources/.safetable/com.aptana.syncing.core.15 b/.metadata/.plugins/org.eclipse.core.resources/.safetable/com.aptana.syncing.core.15 new file mode 100644 index 000000000..01bf076fe --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.safetable/com.aptana.syncing.core.15 @@ -0,0 +1,4 @@ +#safe table +#Mon Jan 05 10:27:54 CST 2015 +defaultConnection=defaultConnection.15 +sites=sites.15 diff --git a/.metadata/.plugins/org.eclipse.core.resources/.safetable/com.aptana.syncing.core.9 b/.metadata/.plugins/org.eclipse.core.resources/.safetable/com.aptana.syncing.core.9 deleted file mode 100644 index 371e94161..000000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.safetable/com.aptana.syncing.core.9 +++ /dev/null @@ -1,4 +0,0 @@ -#safe table -#Tue Mar 11 17:27:27 CST 2014 -defaultConnection=defaultConnection.9 -sites=sites.9 diff --git a/.metadata/.plugins/org.eclipse.core.resources/.safetable/com.aptana.webserver.core.12 b/.metadata/.plugins/org.eclipse.core.resources/.safetable/com.aptana.webserver.core.12 new file mode 100644 index 000000000..26cede301 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.safetable/com.aptana.webserver.core.12 @@ -0,0 +1,3 @@ +#safe table +#Mon Jan 05 10:27:28 CST 2015 +webservers=webservers.12 diff --git a/.metadata/.plugins/org.eclipse.core.resources/.safetable/com.aptana.webserver.core.8 b/.metadata/.plugins/org.eclipse.core.resources/.safetable/com.aptana.webserver.core.8 deleted file mode 100644 index 1af4b85d6..000000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.safetable/com.aptana.webserver.core.8 +++ /dev/null @@ -1,3 +0,0 @@ -#safe table -#Tue Mar 11 17:27:27 CST 2014 -webservers=webservers.8 diff --git a/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources b/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources index b3b591e28..b756a6952 100644 Binary files a/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources and b/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources differ diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.aptana.explorer.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.aptana.explorer.prefs index 752d73cf4..992cdf2bf 100644 --- a/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.aptana.explorer.prefs +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.aptana.explorer.prefs @@ -1,2 +1,2 @@ -activeProject=demo +activeProject=trustie eclipse.preferences.version=1 diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.aptana.portal.ui.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.aptana.portal.ui.prefs index a710d7ff4..e78c19c52 100644 --- a/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.aptana.portal.ui.prefs +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.aptana.portal.ui.prefs @@ -1,2 +1,2 @@ eclipse.preferences.version=1 -last_known_studio_version=3.4.0.1358388620 +last_known_studio_version=3.4.2.1368863613 diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.aptana.theme.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.aptana.theme.prefs index 590c84632..bc6c0d7c7 100644 --- a/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.aptana.theme.prefs +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.aptana.theme.prefs @@ -1,7 +1,7 @@ ACTIVE_HYPERLINK_COLOR=84,143,160 ACTIVE_THEME=Aptana Studio HYPERLINK_COLOR=84,143,160 -THEME_CHANGED=1394527579080 +THEME_CHANGED=1421465443240 eclipse.preferences.version=1 hyperlinkColor=84,143,160 hyperlinkColor.SystemDefault=false diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs index 71a846af6..310adab05 100644 --- a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs @@ -2,6 +2,6 @@ PROBLEMS_FILTERS_MIGRATE=true SHOW_COOLBAR=true SHOW_PERSPECTIVEBAR=true eclipse.preferences.version=1 -platformState=1394526372425 +platformState=1420528131671 quickStart=false tipsAndTricks=true diff --git a/.metadata/.plugins/org.eclipse.debug.core/.launches/Firefox - Internal Server.launch b/.metadata/.plugins/org.eclipse.debug.core/.launches/Firefox - Internal Server.launch index 678ced8a0..08a9581b9 100644 --- a/.metadata/.plugins/org.eclipse.debug.core/.launches/Firefox - Internal Server.launch +++ b/.metadata/.plugins/org.eclipse.debug.core/.launches/Firefox - Internal Server.launch @@ -3,7 +3,7 @@ - + diff --git a/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/.workspace/2015/1/2/refactorings.history b/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/.workspace/2015/1/2/refactorings.history new file mode 100644 index 000000000..664784aa9 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/.workspace/2015/1/2/refactorings.history @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/.workspace/2015/1/2/refactorings.index b/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/.workspace/2015/1/2/refactorings.index new file mode 100644 index 000000000..d5428a792 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/.workspace/2015/1/2/refactorings.index @@ -0,0 +1,2 @@ +1420424676858 Delete resource 'trustie2' +1420424775104 Delete resource 'trustie2' diff --git a/.metadata/.plugins/org.eclipse.ltk.ui.refactoring/dialog_settings.xml b/.metadata/.plugins/org.eclipse.ltk.ui.refactoring/dialog_settings.xml new file mode 100644 index 000000000..27eb4040f --- /dev/null +++ b/.metadata/.plugins/org.eclipse.ltk.ui.refactoring/dialog_settings.xml @@ -0,0 +1,7 @@ + +
+
+ + +
+
diff --git a/.metadata/.plugins/org.eclipse.ui.ide/dialog_settings.xml b/.metadata/.plugins/org.eclipse.ui.ide/dialog_settings.xml index 4868ecd96..09856e2e7 100644 --- a/.metadata/.plugins/org.eclipse.ui.ide/dialog_settings.xml +++ b/.metadata/.plugins/org.eclipse.ui.ide/dialog_settings.xml @@ -1,14 +1,26 @@
- - - - + + + + - + +
+ + +
+
+ + +
+
+ + +
diff --git a/.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml b/.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml index f7e4d66f0..c8c1e4f77 100644 --- a/.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml +++ b/.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml @@ -1,7 +1,9 @@
+
+
- + diff --git a/.metadata/.plugins/org.eclipse.ui.workbench/workbench.xml b/.metadata/.plugins/org.eclipse.ui.workbench/workbench.xml index 88eaacee1..cd47216f4 100644 --- a/.metadata/.plugins/org.eclipse.ui.workbench/workbench.xml +++ b/.metadata/.plugins/org.eclipse.ui.workbench/workbench.xml @@ -1,5 +1,5 @@ - + @@ -8,14 +8,14 @@ - + - - - + + + - + @@ -37,7 +37,7 @@ demo -E:\code\demo +C:\Users\zh @@ -66,10 +66,10 @@ - - + + - + @@ -78,7 +78,7 @@ - + @@ -124,14 +124,19 @@ - - - - + + + + + + + + + - + @@ -166,15 +171,11 @@ - - - - - - - - - + + + + + @@ -188,6 +189,9 @@ + + + diff --git a/Gemfile b/Gemfile index dc834e68d..037c606c8 100644 --- a/Gemfile +++ b/Gemfile @@ -8,6 +8,8 @@ unless RUBY_PLATFORM =~ /w32/ 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" @@ -18,9 +20,12 @@ gem "builder", "3.0.0" gem 'acts-as-taggable-on', '2.4.1' gem 'spreadsheet' gem 'ruby-ole' -#gem 'email_verifier' +#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 @@ -33,7 +38,7 @@ group :test do 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 @@ -44,19 +49,8 @@ group :test do #end end -group :development, :test do - # gem "guard-rails", '~> 0.5.3' - gem 'spork-testunit', '~> 0.0.8' - # gem 'guard-spork', '~> 1.5.1' - # gem 'guard-test', '~> 1.0.0' - gem 'ruby-prof', '~> 0.15.1' unless RUBY_PLATFORM =~ /w32/ - gem 'pry' - gem 'pry-nav' gem 'rspec-rails' , '2.13.1' gem 'guard-rspec','2.5.0' -end - - # Gems used only for assets and not required # in production environments by default. group :assets do diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 000000000..355ca422d --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,348 @@ +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) diff --git a/app/api/mobile/api.rb b/app/api/mobile/api.rb new file mode 100644 index 000000000..bee78a20e --- /dev/null +++ b/app/api/mobile/api.rb @@ -0,0 +1,47 @@ +module Mobile + require_relative 'middleware/error_handler' + require_relative 'apis/auth' + require_relative 'apis/users' + require_relative 'apis/courses' + require_relative 'apis/watches' + require_relative 'apis/upgrade' + require_relative 'apis/homeworks' + class API < Grape::API + version 'v1', using: :path + format :json + content_type :json, "application/json;charset=UTF-8" + use Mobile::Middleware::ErrorHandler + + helpers do + def logger + API.logger + end + + def authenticate! + raise('Unauthorized. Invalid or expired token.') unless current_user + end + + def current_user + token = ApiKey.where(access_token: params[:token]).first + if token && !token.expired? + @current_user = User.find(token.user_id) + else + nil + end + end + end + + mount Apis::Auth + mount Apis::Users + mount Apis::Courses + mount Apis::Watches + mount Apis::Upgrade + mount Apis::Homeworks + + #add_swagger_documentation ({api_version: 'v1', base_path: 'http://u06.shellinfo.cn/trustie/api'}) + #add_swagger_documentation ({api_version: 'v1', base_path: '/api'}) if Rails.env.development? + + end +end + + diff --git a/app/api/mobile/apis/auth.rb b/app/api/mobile/apis/auth.rb new file mode 100644 index 000000000..320497e50 --- /dev/null +++ b/app/api/mobile/apis/auth.rb @@ -0,0 +1,48 @@ +#coding=utf-8 + +module Mobile + + module Entities + class Auth < Grape::Entity + expose :token + expose :user, using: User + end + end + + module Apis + class Auth < Grape::API + resource :auth do + desc "用户登录" + params do + requires :login, type: String, desc: 'Username or email' + requires :password, type: String, desc: 'Password' + end + post do + user,last_logon = ::User.try_to_login(params[:login], params[:password]) + if user + ::ApiKey.delete_all(user_id: user.id) + key = ::ApiKey.create!(user_id: user.id) + api_user = ::UsersService.new.show_user({id:user.id}) + present :data, {token: key.access_token, user: api_user}, using: Entities::Auth + present :status, 0 + else + raise 'Unauthorized.' + end + end + + desc "用户登出" + params do + requires :token, type: String + end + delete do + authenticate! + ::ApiKey.delete_all(user_id: current_user.id) + {status: 0} + end + + end + end + end +end + + diff --git a/app/api/mobile/apis/courses.rb b/app/api/mobile/apis/courses.rb new file mode 100644 index 000000000..7c1aa5e7e --- /dev/null +++ b/app/api/mobile/apis/courses.rb @@ -0,0 +1,216 @@ +#coding=utf-8 +module Mobile + module Apis + class Courses < Grape::API + resource :courses do + desc "获取所有课程" + params do + optional :school_id, type: Integer, desc: '传入学校id,返回该学校课程列表' + requires :per_page_count, type: Integer, desc: '每页总数' + requires :page, type: Integer, desc: '当前页码' + end + get do + cs = CoursesService.new + courses = cs.course_list(params) + present :data, courses, with: Mobile::Entities::Course + present :status, 0 + end + + desc "新建课程" + #current_user当前用户对象(不是id) + # params[:course][:name]:课程名称 + #params[:course][:password]:密码 + #params[:course][:description]:描述 + #params[:course][:is_public]:是否公开1公开,0私有 + #params[:course][:open_student]:是否公开学生列表1公开,0不公开,不公开时非课程成员无法看到学生列表 + #params[:course][:course_type]:暂时默认给1值。 + #params[:term]:学期(秋季学期或春季学期) + #params[:time]: 年份(例:2014) + #params[:setup_time]:暂不传(貌似已经没用了) + #params[:endup_time]: 暂不传(貌似已经没用了) + #params[:class_period]:学时总数 + params do + requires :token, type: String + requires :name, type: String, desc: '课程名称' + requires :password, type: String, desc: '密码' + requires :description, type: String, desc: '描述' + requires :is_public, type: Integer, desc: '是否公开 1公开 0私有' + requires :open_student, type: Integer, desc: '是否公开学生列表1公开,0不公开,不公开时非课程成员无法看到学生列表' + requires :course_type, type:Integer, desc: '暂时传1' + requires :term, type: String, desc: '学期(秋季学期或春季学期)' + requires :time, type: String, desc: '年份' + requires :class_period, type: String, desc: '学时总数' + end + post do + authenticate! + cs = CoursesService.new + cs_params = { + course: params.reject{|k,v| [:term,:time,:class_period].include?(k)}, + term: params[:term], + time: params[:time], + class_period: params[:class_period] + } + courses = cs.create_course(cs_params, current_user) + present :data, courses, with: Mobile::Entities::Course + present :status, 0 + end + + desc "编辑课程" + params do + requires :token, type: String + requires :course_id, type: Integer, desc: '课程id' + requires :name, type: String, desc: '课程名称' + requires :password, type: String, desc: '密码' + requires :description, type: String, desc: '描述' + requires :is_public, type: Integer, desc: '是否公开 1公开 0私有' + requires :open_student, type: Integer, desc: '是否公开学生列表1公开,0不公开,不公开时非课程成员无法看到学生列表' + requires :course_type, type:Integer, desc: '暂时传1' + requires :term, type: String, desc: '学期(秋季学期或春季学期)' + requires :time, type: String, desc: '年份' + requires :class_period, type: String, desc: '学时总数' + end + put do + authenticate! + cs = CoursesService.new + cs_params = { + course: params.reject{|k,v| [:term,:time,:class_period].include?(k)}, + term: params[:term], + time: params[:time], + class_period: params[:class_period] + } + course = ::Course.find(params[:course_id]) + cs.edit_course_authorize(current_user,course) + course = cs.edit_course(cs_params, course,current_user) + present :data, course, with: Mobile::Entities::Course + present :status, 0 + end + post do + end + + desc "加入课程" + params do + requires :token, type: String + requires :course_password, type: String + end + post ":id" do + authenticate! + cs = CoursesService.new + status = cs.join_course({:object_id => params[:id],:course_password => params[:course_password]},current_user) + out = {status: status[:state]} + message = case status[:state] + when 0; "加入成功" + when 1; "密码错误" + when 2; "课程已过期 请联系课程管理员重启课程。(在配置课程处)" + when 3; "您已经加入了课程" + when 4; "您加入的课程不存在" + when 5; "您还未登录" + else; "未知错误,请稍后再试" + end + out.merge(message: message) + end + + desc "退出课程" + params do + requires :token, type: String + end + delete ":id" do + authenticate! + cs = CoursesService.new + status = cs.exit_course({:object_id => params[:id]}, current_user) + out = {status: status} + message = case status + when 0; "退出成功" + when 1; "您不在课程中" + when 2; "您还未登录" + else; "未知错误,请稍后再试" + end + out.merge(message: message) + end + + desc "搜索课程" + params do + requires :name, type: String, desc: "课程名" + end + get 'search' do + cs = CoursesService.new + courses = cs.search_course(params) + present :data, courses, with: Mobile::Entities::Course + present :status, 0 + end + + desc "课程老师列表" + params do + requires :token, type: String + requires :course_id, type: Integer, desc: "课程id" + end + get 'teachers' do + cs = CoursesService.new + teachers = cs.course_teacher_or_student_list({role: '1'}, params[:course_id],current_user) + present :data, teachers, with: Mobile::Entities::User + present :status, 0 + end + + desc "课程学生列表" + params do + requires :token, type: String + requires :course_id, type: Integer, desc: "课程id" + end + get 'students' do + cs = CoursesService.new + students = cs.course_teacher_or_student_list({role: '2'}, params[:course_id],current_user) + present :data, students, with: Mobile::Entities::User + present :status, 0 + end + + desc "返回单个课程" + params do + requires :id, type: Integer + end + route_param :id do + get do + cs = CoursesService.new + course = cs.show_course(params,(current_user.nil? ? User.find(2):current_user)) + #course = Course.find(params[:id]) + {status: 0, data: course} + end + end + + desc "课程作业列表" + params do + requires :token, type: String + end + get "homeworks/:id" do + cs = CoursesService.new + homeworks = cs.homework_list params,current_user + present :data, homeworks, with: Mobile::Entities::Homework + present :status, 0 + end + + desc "课程通知列表" + params do + end + get ":course_id/news" do + cs = CoursesService.new + news = cs.course_news_list params + present :data, news, with: Mobile::Entities::News + present :status, 0 + end + + desc "显示课程通知" + params do + + end + get "news/:id" do + cs = CoursesService.new + cs.show_course_news_authorize(current_user.nil? ? User.find(2):current_user) + news = cs.show_course_news params,current_user.nil? ? User.find(2):current_user + present :data, news, with: Mobile::Entities::News + present :status, 0 + end + + + end + end + end +end + diff --git a/app/api/mobile/apis/homeworks.rb b/app/api/mobile/apis/homeworks.rb new file mode 100644 index 000000000..cba295064 --- /dev/null +++ b/app/api/mobile/apis/homeworks.rb @@ -0,0 +1,77 @@ +#coding=utf-8 + +module Mobile + module Apis + class Homeworks < Grape::API + + def self.get_service + HomeworkService.new + end + + resources :homeworks do + desc "作业详情" + params do + requires :id, type: Integer, desc: "作业ID" + end + route_param :id do + get do + homework = Homeworks.get_service.show_homework params + present :data, homework, with: Mobile::Entities::Homework + present :status, 0 + end + end + + desc "我的作品列表" + params do + requires :token, type: String + end + get ':user_id/homework_attachs' do + ue = Homeworks.get_service.my_homework_list params,current_user.nil? ? User.find(2):current_user + present :data, ue,with: Mobile::Entities::Course + present :status, 0 + end + + desc "启动匿评" + params do + requires :token, type: String + end + post ':id/start_anonymous_comment' do + statue = Homeworks.get_service.start_anonymous_comment params,current_user.nil? ? User.find(2):current_user + messages = "" + case statue + when 1 + messages = "启动成功" + when 2 + messages = "启动失败,作业总数大于等于2份时才能启动匿评" + when 3 + messages = "已开启匿评,请务重复开启" + end + present :data,messages + present :status, statue + end + + desc "关闭匿评" + params do + requires :token, type: String + end + post ':id/stop_anonymous_comment' do + Homeworks.get_service.stop_anonymous_comment params,current_user.nil? ? User.find(2):current_user + present :status, 0 + end + + desc "匿评作品详情" + params do + requires :token, type: String + end + get ':homework_id/anonymous_works_show' do + works,par = Homeworks.get_service.anonymous_works_show params.merge(:id => params[:homework_id]),current_user.nil? ? User.find(2):current_user + present :data, works ,with: Mobile::Entities::HomeworkAttach + present :otherdata,par,with: Mobile::Entities::AnonymousWorksParams + present :status, 0 + end + + + end + end + end +end diff --git a/app/api/mobile/apis/upgrade.rb b/app/api/mobile/apis/upgrade.rb new file mode 100644 index 000000000..02ff97185 --- /dev/null +++ b/app/api/mobile/apis/upgrade.rb @@ -0,0 +1,22 @@ +#coding=utf-8 + +module Mobile + module Apis + class Upgrade < Grape::API + resource :upgrade do + desc "get update info" + params do + requires :platform, type: String, desc: '平台名,android, ios' + end + get do + { + version: '2', + url: 'http://u06.shellinfo.cn/trustie/Trustie_Beta1.0.0_201412310917.apk', + desc: '更新了什么功能' + } + end + end + + end + end +end diff --git a/app/api/mobile/apis/users.rb b/app/api/mobile/apis/users.rb new file mode 100644 index 000000000..69260716e --- /dev/null +++ b/app/api/mobile/apis/users.rb @@ -0,0 +1,96 @@ +#coding=utf-8 +module Mobile + module Apis + class Users < Grape::API + resource :users do + + desc "注册用户" + params do + requires :login, type: String, desc: 'username' + requires :mail, type: String, desc: 'mail' + requires :password, type: String, desc: 'password' + end + post do + us = UsersService.new + user = us.register params.merge(:password_confirmation => params[:password], + :should_confirmation_password => true) + raise "register failed #{user.errors.full_messages}" if user.new_record? + + present :data, user, with: Mobile::Entities::User + present :status, 0 + end + + desc "显示用户" + params do + + end + get ':id' do + us = UsersService.new + ue = us.show_user params + present :data, ue,with: Mobile::Entities::User + present :status, 0 + end + + desc "修改用户" + params do + requires :token, type: String + #optional :file, type: File, desc: 'avatar' + optional :occupation, type: String + optional :brief_introduction, type: String + optional :province, type: String + optional :city, type: String + optional :gender, type: Integer + end + put ':id' do + authenticate! + us = UsersService.new + ue = us.edit_user params.merge(id: current_user.id) + present :data, ue,with: Mobile::Entities::User + present :status, 0 + end + + desc '获取用户课程' + params do + optional :token, type: String + end + + get ':id/courses' do + us = UsersService.new + ue = us.user_courses_list params,current_user.nil? ? User.find(2):current_user + present :data, ue,with: Mobile::Entities::Course + present :status, 0 + end + + + desc '修改密码' + params do + requires :token, type: String + requires :password, type:String , desc: '原密码' + requires :new_password, type: String, desc: '新密码' + end + post 'password' do + authenticate! + us = UsersService.new + user = us.change_password params.merge(current_user_id: current_user.id, + new_password_confirmation: params[:new_password]) + present :data, user, with: Mobile::Entities::User + present :status, 0 + end + + desc "用户搜索" + params do + requires :name, type: String, desc: '用户名关键字' + end + get 'search' do + us = UsersService.new + user = us.search_user params + present :data, user, with: Mobile::Entities::User + present :status, 0 + end + + end + end + end +end + + diff --git a/app/api/mobile/apis/watches.rb b/app/api/mobile/apis/watches.rb new file mode 100644 index 000000000..1603b311a --- /dev/null +++ b/app/api/mobile/apis/watches.rb @@ -0,0 +1,49 @@ +#coding=utf-8 +module Mobile + module Apis + class Watches < Grape::API + resource :watches do + + desc "获取所有关注" + params do + requires :token, type: String + end + get do + authenticate! + us = UsersService.new + ws = us.user_watcher(id: current_user.id) + present :data, ws, with: Mobile::Entities::User + present :status, 0 + end + + + desc "关注某人" + params do + requires :token, type: String + requires :object_id, type: Integer, desc: '关注的用户的id' + end + post do + authenticate! + ws = WatchesService.new + o = ws.watch(params.merge({current_user_id:current_user.id, object_type:'user' }) ) + present :data, o, with: Mobile::Entities::User + present :status, 0 + end + + + desc "取消关注" + params do + requires :token, type: String + requires :object_id, type: Integer, desc: '取消关注的用户的id' + end + delete do + authenticate! + ws = WatchesService.new + ws.unwatch(params.merge({current_user_id:current_user.id, object_type:'user' }) ) + {status: 0} + end + + end + end + end +end diff --git a/app/api/mobile/entities/anonymous_works_params.rb b/app/api/mobile/entities/anonymous_works_params.rb new file mode 100644 index 000000000..95cf9215d --- /dev/null +++ b/app/api/mobile/entities/anonymous_works_params.rb @@ -0,0 +1,35 @@ +module Mobile + module Entities + #匿评作品页面相关参数 + class AnonymousWorksParams < Grape::Entity + def self.anonymous_works_params_expose(field) + expose field do |f,opt| + if f.is_a?(Hash) && f.key?(field) + f[field] + elsif f.is_a?(Hash) && !f.key?(field) + + end + end + end + anonymous_works_params_expose :is_teacher + anonymous_works_params_expose :m_score + anonymous_works_params_expose :is_anonymous_comments + anonymous_works_params_expose :cur_type + expose :jours ,using: Mobile::Entities::Jours do |f, opt| + if f.is_a?(Hash) && f.key?(:jours) + f[:jours] + end + end + expose :teacher_stars,using: Mobile::Entities::HomeworkJours do |f, opt| + if f.is_a?(Hash) && f.key?(:teacher_stars) + f[:teacher_stars] + end + end + expose :student_stars , using: Mobile::Entities::HomeworkJours do |f, opt| + if f.is_a?(Hash) && f.key?(:student_stars) + f[:student_stars] + end + end + end + end +end \ No newline at end of file diff --git a/app/api/mobile/entities/attachment.rb b/app/api/mobile/entities/attachment.rb new file mode 100644 index 000000000..510db89be --- /dev/null +++ b/app/api/mobile/entities/attachment.rb @@ -0,0 +1,23 @@ +module Mobile + module Entities + class Attachment < Grape::Entity + def self.attachment_expose(field) + expose field do |f,opt| + if f.is_a?(Hash) && f.key?(field) + f[field] + elsif f.is_a?(::Attachment) + if f.respond_to?(field) + f.send(field) + else + #case field + # when "" + #end + end + end + end + end + attachment_expose :filename + attachment_expose :description + end + end +end \ No newline at end of file diff --git a/app/api/mobile/entities/course.rb b/app/api/mobile/entities/course.rb new file mode 100644 index 000000000..ec00579ce --- /dev/null +++ b/app/api/mobile/entities/course.rb @@ -0,0 +1,58 @@ +module Mobile + module Entities + class Course < Grape::Entity + def self.course_expose(field) + expose field do |f,opt| + c = nil + if f.is_a? ::Course + c = f + else + c = f[:course] + end + if field == :img_url + f[field] if f.is_a?(Hash) && f.key?(field) + #f.img_url if f.respond_to?(:img_url) + else + (c[field] if (c.is_a?(Hash) && c.key?(field))) || (c.send(field) if c.respond_to?(field)) + end + end + end + course_expose :img_url + course_expose :attachmenttype + course_expose :class_period + course_expose :code + course_expose :created_at + course_expose :description + course_expose :endup_time + course_expose :extra + course_expose :id + course_expose :inherit_members + course_expose :is_public + course_expose :lft + course_expose :location + course_expose :name + course_expose :open_student + # course_expose :password + course_expose :rgt + course_expose :school_id + course_expose :setup_time + course_expose :state + course_expose :status + course_expose :string + course_expose :tea_id + course_expose :term + course_expose :time + course_expose :updated_at + expose :teacher, using: Mobile::Entities::User do |c, opt| + if c.is_a? ::Course + c.teacher + else + c[:course].teacher + end + end + expose :my_homework,using: Mobile::Entities::HomeworkAttach do |f, opt| + f[:my_homework] if f.is_a?(Hash) && f.key?(:my_homework) + end + end + end +end diff --git a/app/api/mobile/entities/homework.rb b/app/api/mobile/entities/homework.rb new file mode 100644 index 000000000..9be9bc53e --- /dev/null +++ b/app/api/mobile/entities/homework.rb @@ -0,0 +1,45 @@ +module Mobile + module Entities + class Homework < Grape::Entity + def self.homework_expose(field) + expose field do |f,opt| + if f.is_a?(Hash) && f.key?(field) + f[field] + elsif f.is_a?(::Bid) + if f.respond_to?(field) + f.send(field) + else + + end + end + end + end + #作业id + homework_expose :id + #课程名称 + homework_expose :course_name + #课程老师 + homework_expose :course_teacher + #作业次数 + homework_expose :homework_times + #作业名称 + homework_expose :homework_name + #已提交的作业数量 + homework_expose :homework_count + #学生提问数量 + homework_expose :student_questions_count + #作业描述 + homework_expose :description + #作业是否启用匿评功能 0:不启用,1启用 + homework_expose :open_anonymous_evaluation + #作业状态 0:新建,1:已开启匿评,2:已关闭匿评 + #只有作业启用了匿评功能且当前用户是课程老师且已提交的作品数量大于或等于2才能开启匿评 + homework_expose :homework_state + + 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 + + end + end +end \ No newline at end of file diff --git a/app/api/mobile/entities/homework_attach.rb b/app/api/mobile/entities/homework_attach.rb new file mode 100644 index 000000000..256dcdf61 --- /dev/null +++ b/app/api/mobile/entities/homework_attach.rb @@ -0,0 +1,39 @@ +module Mobile + module Entities + class HomeworkAttach < Grape::Entity + include Redmine::I18n + def self.homework_attach_expose(field) + expose field do |f,opt| + if f.is_a?(Hash) && f.key?(field) + f[field] + elsif f.is_a?(::HomeworkAttach) + if f.respond_to?(field) + if field == :created_at + format_time(f.send(:created_at)) + else + f.send(field) + end + else + case field + when :homework_times + f.bid.courses.first.homeworks.index(f.bid) + 1 unless (f.bid.nil? || f.bid.courses.nil? || f.bid.courses.first.nil?) + end + end + end + end + end + + homework_attach_expose :id + homework_attach_expose :name + homework_attach_expose :homework_times + homework_attach_expose :description + homework_attach_expose :created_at + expose :attachments,using: Mobile::Entities::Attachment do |f, opt| + if f.respond_to?(:attachments) + f.send(:attachments) + end + end + #homework_attach_expose :user + end + end +end \ No newline at end of file diff --git a/app/api/mobile/entities/homework_jours.rb b/app/api/mobile/entities/homework_jours.rb new file mode 100644 index 000000000..63c6997fd --- /dev/null +++ b/app/api/mobile/entities/homework_jours.rb @@ -0,0 +1,25 @@ +module Mobile + module Entities + #带评分的留言(教师评论、学生匿名评分都属于此类) + class HomeworkJours < Grape::Entity + include Redmine::I18n + def self.homework_jours_expose(field) + expose field do |f,opt| + if f.is_a?(Hash) && f.key?(field) + f[field] + elsif f.is_a?(::SeemsRateableRates) + + end + end + end + homework_jours_expose :rater_id + homework_jours_expose :rater_name + homework_jours_expose :created_at + homework_jours_expose :stars + expose :comment,using: Mobile::Entities::Jours do |f,opt| + f[:comment] + end + + end + end +end \ No newline at end of file diff --git a/app/api/mobile/entities/jours.rb b/app/api/mobile/entities/jours.rb new file mode 100644 index 000000000..5a9f48cbc --- /dev/null +++ b/app/api/mobile/entities/jours.rb @@ -0,0 +1,37 @@ +module Mobile + module Entities + #普通留言 + class Jours < Grape::Entity + include Redmine::I18n + include WordsHelper + def self.jours_expose(field) + expose field do |f,opt| + if f.is_a?(Hash) && f.key?(field) + f[field] + elsif f.is_a?(::JournalsForMessage) && f.respond_to?(field) + if field == :created_on + format_time(f.send(field)) + else + f.send(field) + end + end + end + end + jours_expose :id + expose :user,using: Mobile::Entities::User do |f, opt| + f.user + end + jours_expose :created_on + jours_expose :notes + jours_expose :m_reply_id + expose :reply_user,using: Mobile::Entities::User do |f, opt| + f.at_user + end + expose :child_reply,using: Mobile::Entities::Jours do |f, opt| + if f.is_a?(::JournalsForMessage) + fetch_user_leaveWord_reply(f) + end + end + end + end +end diff --git a/app/api/mobile/entities/news.rb b/app/api/mobile/entities/news.rb new file mode 100644 index 000000000..7c77f8c82 --- /dev/null +++ b/app/api/mobile/entities/news.rb @@ -0,0 +1,42 @@ +module Mobile + module Entities + class News < Grape::Entity + def self.news_expose(field) + expose field do |f,opt| + if f.is_a?(Hash) && f.key?(field) + f[field] + elsif f.is_a?(Hash) && !f.key?(field) + n = f[:news] + comments = f[:comments] + if n.is_a?(::News) + n.send(field) if n.respond_to?(field) + end + + end + end + end + + #新闻标题 + news_expose :title + + expose :author,using: Mobile::Entities::User do |f, opt| + n = f[:news] + n.author if n.respond_to?(:author) + end + #作者id + news_expose :author_id + #作者名 + news_expose :author_name + #新闻内容 + news_expose :description + #发布时间 + news_expose :created_on + #评论数量 + news_expose :comments_count + #评论 + news_expose :comments + + + end + end +end \ No newline at end of file diff --git a/app/api/mobile/entities/user.rb b/app/api/mobile/entities/user.rb new file mode 100644 index 000000000..1f52ae841 --- /dev/null +++ b/app/api/mobile/entities/user.rb @@ -0,0 +1,51 @@ +module Mobile + module Entities + class User < Grape::Entity + include ApplicationHelper + include ApiHelper + def self.user_expose(f) + expose f do |u,opt| + if u.is_a?(Hash) && u.key?(f) + u[f] + elsif u.is_a?(::User) + if u.respond_to?(f) + u.send(f) + else + case f + when :img_url + url_to_avatar(u) + when :gender + u.user_extensions.gender.nil? ? 0 : u.user_extensions.gender + when :work_unit + get_user_work_unit u + when :location + get_user_location u + when :brief_introduction + u.user_extensions.brief_introduction + end + end + end + + end + end + + expose :id + #头像 + user_expose :img_url + #昵称 + expose :nickname + #性别 + user_expose :gender + #我的二维码 + #工作单位 + user_expose :work_unit + #邮箱地址 + user_expose :mail + #地区 + user_expose :location + #签名 + user_expose :brief_introduction + end + end + +end diff --git a/app/api/mobile/middleware/error_handler.rb b/app/api/mobile/middleware/error_handler.rb new file mode 100644 index 000000000..018191d8d --- /dev/null +++ b/app/api/mobile/middleware/error_handler.rb @@ -0,0 +1,19 @@ +module Mobile + module Middleware + class ErrorHandler < Grape::Middleware::Base + def call!(env) + @env = env + begin + @app.call(@env) + rescue =>e + message = {status: 1, message: e.message }.to_json + puts(e.backtrace.join("\n")) if Rails.env.development? + status = 200 + headers = { 'Content-Type' => content_type } + Rack::Response.new([message], status, headers).finish + # throw :error, :message => e.message || options[:default_message], :status => 500 + end + end + end + end +end diff --git a/app/assets/javascripts/enterprises.js.coffee b/app/assets/javascripts/enterprises.js.coffee new file mode 100644 index 000000000..761567942 --- /dev/null +++ b/app/assets/javascripts/enterprises.js.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/ diff --git a/app/assets/javascripts/system_log.js.coffee b/app/assets/javascripts/system_log.js.coffee new file mode 100644 index 000000000..761567942 --- /dev/null +++ b/app/assets/javascripts/system_log.js.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/ diff --git a/app/assets/stylesheets/enterprises.css.scss b/app/assets/stylesheets/enterprises.css.scss new file mode 100644 index 000000000..174f3a2ec --- /dev/null +++ b/app/assets/stylesheets/enterprises.css.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the Enterprises controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/system_log.css.scss b/app/assets/stylesheets/system_log.css.scss new file mode 100644 index 000000000..aa1f18587 --- /dev/null +++ b/app/assets/stylesheets/system_log.css.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the system_log controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/controllers/account_controller.rb b/app/controllers/account_controller.rb index 69c2d3002..ff66b8d46 100644 --- a/app/controllers/account_controller.rb +++ b/app/controllers/account_controller.rb @@ -118,13 +118,30 @@ class AccountController < ApplicationController redirect_to my_account_path end else - create_and_save_user params[:user][:login],user_params[:password],user_params[:mail],user_params[:password_confirmation],true + us = UsersService.new + @user = us.register user_params.merge(:should_confirmation_password => true) + case Setting.self_registration + when '1' + #register_by_email_activation(@user) + unless @user.new_record? + flash[:notice] = l(:notice_account_register_done) + render action: 'email_valid', locals: {:mail => user.mail} + end + when '3' + #register_automatically(@user) + unless @user.new_record? + self.logged_user = @user + flash[:notice] = l(:notice_account_activated) + redirect_to my_account_url + end + else + #register_manually_by_administrator(@user) + unless @user.new_record? + account_pending + end + end end end - if params[:identity] == "2" - @user.firstname = firstname_code - @user.lastname = lastname_code - end end #should_confirmation_password是否验证密码 @@ -172,6 +189,11 @@ class AccountController < ApplicationController redirect_to signin_url end + def api_register login,password,email + users_service = UsersService.new + users_service.register({login: login, password: password, email: eamil}) + end + def valid_ajax req = Hash.new(false) req[:message] = '' diff --git a/app/controllers/applied_project_controller.rb b/app/controllers/applied_project_controller.rb index 3d061ef74..f2c0eb056 100644 --- a/app/controllers/applied_project_controller.rb +++ b/app/controllers/applied_project_controller.rb @@ -3,7 +3,31 @@ class AppliedProjectController < ApplicationController #申请加入项目 def applied_join_project @user_id = params[:user_id] - @project = Project.find(params[:project_id]) + @project = Project.find_by_id(params[:project_id]) + if params[:project_join] + if @project + user = User.find @user_id + if user.member_of?(@project) + @status = 3 + else + @applieds = AppliedProject.where("user_id = ? and project_id = ?", params[:user_id],params[:project_id]) + if @applieds.count == 0 + appliedproject = AppliedProject.create(:user_id => params[:user_id], :project_id => params[:project_id]) + Mailer.applied_project(appliedproject).deliver + @status = 2 + else + @status = 1 + end + end + else + @status = 0 + end + respond_to do |format| + format.js + end + return + end + @applieds = AppliedProject.where("user_id = ? and project_id = ?", params[:user_id],params[:project_id]) if @applieds.count == 0 appliedproject = AppliedProject.create(:user_id => params[:user_id], :project_id => params[:project_id]) diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb index b5e0362b3..7653be94d 100644 --- a/app/controllers/courses_controller.rb +++ b/app/controllers/courses_controller.rb @@ -8,6 +8,7 @@ class CoursesController < ApplicationController menu_item :overview menu_item :feedback, :only => :feedback menu_item :homework, :only => :homework + menu_item :new_homework, :only => :new_homework menu_item l(:label_sort_by_time), :only => :index @@ -26,36 +27,40 @@ class CoursesController < ApplicationController def join if User.current.logged? - course = Course.find_by_id params[:object_id] - if course - if course_endTime_timeout? course - @state = 2 - else - if User.current.member_of_course?(course) - @state = 3 - else - if params[:course_password] == course.password - members = [] - members << Member.new(:role_ids => [10], :user_id => User.current.id) - course.members << members - StudentsForCourse.create(:student_id => User.current.id, :course_id => params[:object_id]) - @state = 0 - else - @state = 1 - end - end - end - else - @state = 4 - end + cs = CoursesService.new + join = cs.join_course params,User.current + @state = join[:state] + course = join[:course] + #course = Course.find_by_id params[:object_id] + #if course + # if course_endTime_timeout? course + # @state = 2 + # else + # if User.current.member_of_course?(course) + # @state = 3 + # else + # if params[:course_password] == course.password + # members = [] + # members << Member.new(:role_ids => [10], :user_id => User.current.id) + # course.members << members + # StudentsForCourse.create(:student_id => User.current.id, :course_id => params[:object_id]) + # @state = 0 + # else + # @state = 1 + # end + # end + # end + #else + # @state = 4 + #end else - @state = 5 + @state = 5 #未登录 end respond_to do |format| format.js { render :partial => 'set_join', :locals => {:user => User.current, :course => course, :object_id => params[:object_id]} } end rescue Exception => e - @state = 4 + @state = 4 #已经加入了课程 respond_to do |format| # format.html { redirect_to_referer_or {render :text => (watching ? 'Watcher added.' : 'Watcher removed.'), :layout => true}} format.js { render :partial => 'set_join', :locals => {:user => User.current, :course => nil, :object_id => nil} } @@ -64,15 +69,18 @@ class CoursesController < ApplicationController def unjoin if User.current.logged? - - @member = Member.where('course_id = ? and user_id = ?', params[:object_id], User.current.id) - @member.first.destroy - - joined = StudentsForCourse.where('student_id = ? and course_id = ?', User.current.id, params[:object_id]) - joined.each do |join| - join.delete - end + # + # @member = Member.where('course_id = ? and user_id = ?', params[:object_id], User.current.id) + # @member.first.destroy + # + # joined = StudentsForCourse.where('student_id = ? and course_id = ?', User.current.id, params[:object_id]) + # joined.each do |join| + # join.delete + # end + cs = CoursesService.new + cs.exit_course params,User.current end + respond_to do |format| # format.html { redirect_to_referer_or {render :text => (watching ? 'Watcher added.' : 'Watcher removed.'), :layout => true}} format.js { render :partial => 'set_join', :locals => {:user => User.current, :course => Course.find(params[:object_id]), :object_id => params[:object_id]} } @@ -89,27 +97,16 @@ class CoursesController < ApplicationController #更新课程信息 def update - @course.safe_attributes = params[:course] - @course.time = params[:time] - @course.term = params[:term] - @course.class_period = params[:class_period] - if @course.save - if params[:course][:is_public] == '0' - course_status = CourseStatus.find_by_course_id(@course.id) - course_status.destroy if course_status - elsif params[:course][:is_public] == '1' - course_status = CourseStatus.find_by_course_id(@course.id) - course_status.destroy if course_status - course_status = CourseStatus.create(:course_id => @course.id, :grade => 0) - end - - respond_to do |format| - format.html { - flash[:notice] = l(:notice_successful_update) - redirect_to settings_course_url(@course) - } - format.api { render_api_ok } - end + cs = CoursesService.new + @course = cs.edit_course params,@course,User.current + if @course.errors.full_messages.count <= 0 + respond_to do |format| + format.html { + flash[:notice] = l(:notice_successful_update) + redirect_to settings_course_url(@course) + } + format.api { render_api_ok } + end else respond_to do |format| format.html { @@ -119,6 +116,36 @@ class CoursesController < ApplicationController format.api { render_validation_errors(@course) } end end + #@course.safe_attributes = params[:course] + #@course.time = params[:time] + #@course.term = params[:term] + #@course.class_period = params[:class_period] + #if @course.save + # if params[:course][:is_public] == '0' + # course_status = CourseStatus.find_by_course_id(@course.id) + # course_status.destroy if course_status + # elsif params[:course][:is_public] == '1' + # course_status = CourseStatus.find_by_course_id(@course.id) + # course_status.destroy if course_status + # course_status = CourseStatus.create(:course_id => @course.id, :grade => 0) + # end + # + # respond_to do |format| + # format.html { + # flash[:notice] = l(:notice_successful_update) + # redirect_to settings_course_url(@course) + # } + # format.api { render_api_ok } + # end + #else + # respond_to do |format| + # format.html { + # settings + # render :action => 'settings' + # } + # format.api { render_validation_errors(@course) } + # end + #end end def new_join @@ -203,6 +230,11 @@ class CoursesController < ApplicationController render_feed(courses, :title => "#{Setting.app_title}: #{l(:label_course_latest)}") } end + + rescue Exception => e + if e.message == 'sumbit empty' + (redirect_to courses_url, :notice => l(:label_sumbit_empty);return) + end end def searchmembers @@ -212,7 +244,7 @@ class CoursesController < ApplicationController @is_remote = true @score_sort_by = "desc" q = "#{params[:name].strip}" - #(redirect_to stores_url, :notice => l(:label_sumbit_empty);return) if params[:name].blank? + #(redirect_to stores_url, :notice => l(:label_sumbit_empty);return) if params[:name].blank? if params[:incourse] @results = searchmember_by_name(student_homework_score(0,0,0,"desc"), q) @@ -448,57 +480,79 @@ class CoursesController < ApplicationController end def create - if User.current.user_extensions.identity - @course = Course.new - @course.extra='course' + DateTime.parse(Time.now.to_s).strftime('%Y-%m-%d_%H-%M-%S').to_s - @course.safe_attributes = params[:course] - @course.tea_id = User.current.id - # added by bai - @course.term = params[:term] - @course.time = params[:time] - #@course.school_id = params[:occupation] - @course.school_id = User.current.user_extensions.school_id - @course.setup_time = params[:setup_time] - @course.endup_time = params[:endup_time] - @course.class_period = params[:class_period] - end - - @issue_custom_fields = IssueCustomField.sorted.all - @trackers = Tracker.sorted.all - - if @course.save - #unless User.current.admin? - 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 => @course.id) - #user_grades = UserGrade.create(:user_id => User.current.id, :course_id => @course.id) - if params[:course][:is_public] == '1' - course_status = CourseStatus.create(:course_id => @course.id, :watchers_count => 0, :changesets_count => 0, :grade => 0, :course_type => @course_tag) - end - @course.members << m - @course.course_infos << course - #end - respond_to do |format| - format.html { - flash[:notice] = l(:notice_successful_create) - if params[:continue] - redirect_to new_course_url(attrs, :course => '0') - elsif params[:course_continue] - redirect_to new_course_url(:course => '1') - else - redirect_to settings_course_url(@course, :course_type => 1) + cs = CoursesService.new + @course = cs.create_course params,User.current + if @course.new_record? + respond_to do |format| + format.html { render :action => 'new', :layout => 'base' } #Added by young + format.api { render_validation_errors(@course) } + end + else + respond_to do |format| + format.html { + flash[:notice] = l(:notice_successful_create) + if params[:continue] + redirect_to new_course_url(attrs, :course => '0') + elsif params[:course_continue] + redirect_to new_course_url(:course => '1') + else + redirect_to settings_course_url(@course, :course_type => 1) + end + } + format.api { render :action => 'show', :status => :created, :location => url_for(:controller => 'courses', :action => 'show', :id => @course.id) } end - } - format.api { render :action => 'show', :status => :created, :location => url_for(:controller => 'courses', :action => 'show', :id => @course.id) } - end - else - #@course.destroy - respond_to do |format| - format.html { render :action => 'new', :layout => 'base' } #Added by young - format.api { render_validation_errors(@course) } - end - end + end + #if User.current.user_extensions.identity + # @course = Course.new + # @course.extra='course' + DateTime.parse(Time.now.to_s).strftime('%Y-%m-%d_%H-%M-%S').to_s + # @course.safe_attributes = params[:course] + # @course.tea_id = User.current.id + # # added by bai + # @course.term = params[:term] + # @course.time = params[:time] + # #@course.school_id = params[:occupation] + # @course.school_id = User.current.user_extensions.school_id + # @course.setup_time = params[:setup_time] + # @course.endup_time = params[:endup_time] + # @course.class_period = params[:class_period] + #end + # + #@issue_custom_fields = IssueCustomField.sorted.all + #@trackers = Tracker.sorted.all + # + #if @course.save + # #unless User.current.admin? + # 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 => @course.id) + # #user_grades = UserGrade.create(:user_id => User.current.id, :course_id => @course.id) + # if params[:course][:is_public] == '1' + # course_status = CourseStatus.create(:course_id => @course.id, :watchers_count => 0, :changesets_count => 0, :grade => 0, :course_type => @course_tag) + # end + # @course.members << m + # @course.course_infos << course + # #end + # respond_to do |format| + # format.html { + # flash[:notice] = l(:notice_successful_create) + # if params[:continue] + # redirect_to new_course_url(attrs, :course => '0') + # elsif params[:course_continue] + # redirect_to new_course_url(:course => '1') + # else + # redirect_to settings_course_url(@course, :course_type => 1) + # end + # } + # format.api { render :action => 'show', :status => :created, :location => url_for(:controller => 'courses', :action => 'show', :id => @course.id) } + # end + # else + # #@course.destroy + # respond_to do |format| + # format.html { render :action => 'new', :layout => 'base' } #Added by young + # format.api { render_validation_errors(@course) } + # end + # end end def course @@ -622,7 +676,10 @@ class CoursesController < ApplicationController end def index - render_404 + if !User.current.admin? + render_404 + return + end @course_type = params[:course_type] @school_id = params[:school_id] per_page_option = 10 @@ -670,7 +727,7 @@ class CoursesController < ApplicationController respond_to do |format| format.html { - # render :layout => 'base' + render :layout => 'base' } format.atom { courses = Course.visible.order('created_on DESC').limit(Setting.feeds_limit.to_i).all @@ -771,6 +828,7 @@ class CoursesController < ApplicationController end def show + # try to redirect to the requested menu item if params[:jump] && redirect_to_course_menu_item(@course, params[:jump]) return @@ -809,6 +867,7 @@ class CoursesController < ApplicationController @activity.scope_select {|t| has["show_#{t}"]} # modify by nwb # 添加私密性判断 + if User.current.member_of_course?(@course)|| User.current.admin? events = @activity.events(@days, @course.created_at) else @@ -833,14 +892,13 @@ class CoursesController < ApplicationController @events_by_day = events.group_by {|event| User.current.time_to_date(event.event_datetime)} # documents @sort_by = %w(category date title author).include?(params[:sort_by]) ? params[:sort_by] : 'category' - # - @teachers= searchTeacherAndAssistant(@course) - @canShowRealName = isCourseTeacher(User.current.id,@course) + # 这写变量发现没有用而且拖慢速度 + #@teachers= searchTeacherAndAssistant(@course) + #@canShowRealName = isCourseTeacher(User.current.id,@course) if(User.find_by_id(CourseInfos.find_by_course_id(@course.id).try(:user_id))) @user = User.find_by_id(CourseInfos.find_by_course_id(@course.id).user_id) end - respond_to do |format| format.html{render :layout => 'base_courses'} format.api diff --git a/app/controllers/homework_attach_controller.rb b/app/controllers/homework_attach_controller.rb index 8e69d1d72..2c943e778 100644 --- a/app/controllers/homework_attach_controller.rb +++ b/app/controllers/homework_attach_controller.rb @@ -101,13 +101,7 @@ class HomeworkAttachController < ApplicationController #获取学生匿评列表 def get_student_batch_homework @is_student_batch_homework = true - all_homework_list = HomeworkAttach.eager_load(:attachments,:user,:rate_averages).find_by_sql("SELECT homework_attaches.*, - (SELECT stars FROM seems_rateable_rates WHERE rateable_type = 'HomeworkAttach' AND rateable_id = homework_attaches.id AND is_teacher_score = 1 AND stars IS NOT NULL ORDER BY updated_at DESC limit 0,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.current.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 - WHERE homework_attaches.bid_id = #{@bid.id} AND homework_evaluations.user_id = #{User.current.id} ORDER BY m_score DESC") + all_homework_list = get_student_batch_homework_list @bid,User.current @cur_page = params[:page] || 1 @cur_type = 4 @homework_list = paginateHelper all_homework_list,10 diff --git a/app/controllers/my_controller.rb b/app/controllers/my_controller.rb index 8f00c49cd..7ff015fbc 100644 --- a/app/controllers/my_controller.rb +++ b/app/controllers/my_controller.rb @@ -183,17 +183,35 @@ class MyController < ApplicationController return end if request.post? - if @user.check_password?(params[:password]) - @user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation] - - if @user.save - flash.now[:notice] = l(:notice_account_password_updated) - redirect_to my_account_url - end - else - flash.now[:error] = l(:notice_account_wrong_password) + us = UsersService.new + @user = us.change_password params.merge(:current_user_id => @user.id) + if @user.errors.full_messages.count <= 0 + flash.now[:notice] = l(:notice_account_password_updated) + redirect_to my_account_url end end + rescue Exception => e + if e.message == 'wrong password' + flash.now[:error] = l(:notice_account_wrong_password) + end + # @user = User.current + # unless @user.change_password_allowed? + # flash.now[:error] = l(:notice_can_t_change_password) + # redirect_to my_account_url + # return + # end + # if request.post? + # if @user.check_password?(params[:password]) + # @user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation] + # + # if @user.save + # flash.now[:notice] = l(:notice_account_password_updated) + # redirect_to my_account_url + # end + # else + # flash.now[:error] = l(:notice_account_wrong_password) + # end + # end end # Create a new feeds key diff --git a/app/controllers/news_controller.rb b/app/controllers/news_controller.rb index 23f8c18e9..2df17d73f 100644 --- a/app/controllers/news_controller.rb +++ b/app/controllers/news_controller.rb @@ -91,8 +91,12 @@ class NewsController < ApplicationController end def show - @comments = @news.comments - @comments.reverse! if User.current.wants_comments_in_reverse_order? + cs = CoursesService.new + result = cs.show_course_news params,User.current + @news = result[:news] + @comments = result[:comments] + #@comments = @news.comments + #@comments.reverse! if User.current.wants_comments_in_reverse_order? #modify by nwb if @news.course_id @course = Course.find(@news.course_id) diff --git a/app/controllers/originizations_controller.rb b/app/controllers/originizations_controller.rb new file mode 100644 index 000000000..033f9d8ec --- /dev/null +++ b/app/controllers/originizations_controller.rb @@ -0,0 +1,6 @@ +class OriginizationsController < ApplicationController + layout 'project_base' + def index + @enterprises = Project.find_by_sql("select distinct(enterprise_name) from projects") + end +end diff --git a/app/controllers/poll_controller.rb b/app/controllers/poll_controller.rb index 8926c0be6..1b2794034 100644 --- a/app/controllers/poll_controller.rb +++ b/app/controllers/poll_controller.rb @@ -1,8 +1,8 @@ class PollController < ApplicationController - before_filter :find_poll_and_course, :only => [:edit,:update,:destroy,:show,:statistics_result,:create_poll_question,:commit_poll,:commit_answer,:publish_poll,:republish_poll,:poll_result] + before_filter :find_poll_and_course, :only => [:edit,:update,:destroy,:show,:statistics_result,:create_poll_question,:commit_poll,:commit_answer,:publish_poll,:republish_poll,:poll_result,:close_poll] before_filter :find_container, :only => [:new,:create, :index] before_filter :is_member_of_course, :only => [:index,:show,:poll_result] - before_filter :is_course_teacher, :only => [:new,:create,:edit,:update,:destroy,:publish_poll,:republish_poll] + before_filter :is_course_teacher, :only => [:new,:create,:edit,:update,:destroy,:publish_poll,:republish_poll,:close_poll] include PollHelper def index if @course @@ -83,6 +83,12 @@ class PollController < ApplicationController def destroy if @poll && @poll.destroy + if @is_teacher + polls = Poll.where("polls_type = 'Course' and polls_group_id = #{@course.id}") + else + polls = Poll.where("polls_type = 'Course' and polls_group_id = #{@course.id} and polls_status = 2") + end + @polls = paginateHelper polls,20 #分页 respond_to do |format| format.js end @@ -339,6 +345,17 @@ class PollController < ApplicationController end end + #关闭问卷 + def close_poll + @poll.polls_status = 3 + @poll.closed_at = Time.now + if @poll.save + respond_to do |format| + format.js + end + end + end + private def find_poll_and_course @poll = Poll.find params[:id] diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index a2e793a10..64706887b 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -14,41 +14,35 @@ # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# Time 2015-01-28 16:34:21 +# Author lizanle +# Description 封装代码,简化代码,格式化代码, class ProjectsController < ApplicationController layout :select_project_layout menu_item :overview menu_item :roadmap, :only => :roadmap menu_item :settings, :only => :settings - - menu_item l(:label_sort_by_time), :only => :index - menu_item l(:label_sort_by_active), :only => :index - menu_item l(:label_sort_by_influence), :only => :index - - # menu_item l(:label_homework), :only => :homework - # menu_item l(:label_course_feedback), :only => :feedback menu_item :homework, :only => [:homework, :new_homework] menu_item :feedback, :only => :feedback - menu_item l(:label_course_file), :only => :index - menu_item l(:label_course_news), :only => :index -# edit - before_filter :authorize1, :only => [:show] -# + before_filter :find_project, :except => [ :index, :search,:list, :new, :create, :copy, :statistics, :new_join, + :course, :enterprise_course, :course_enterprise,:view_homework_attaches] + before_filter :authorize, :only => [:show, :settings, :edit, :sort_project_members, :update, :modules, :close, + :reopen,:view_homework_attaches,:course] before_filter :find_project, :except => [ :index, :search,:list, :new, :create, :copy, :statistics, :new_join, :course, :enterprise_course, :course_enterprise,:view_homework_attaches,:join_project] # before_filter :authorize, :except => [:new_join, :new_homework, :homework, :statistics, :search, :watcherlist, :index, :list, :new, :create, :copy, :archive, :unarchive, :destroy, :member, :focus, :file, # :statistics, :feedback, :course, :enterprise_course, :course_enterprise, :project_respond, :share, # :show_projects_score, :issue_score_index, :news_score_index, :file_score_index, :code_submit_score_index, :projects_topic_score_index] #此条勿删 课程相关权限 ,:new_homework,:homework,:feedback,,:member - before_filter :authorize, :only => [:settings, :edit, :sort_project_members, :update, :modules, :close, :reopen,:view_homework_attaches,:course] + before_filter :authorize, :only => [:show, :settings, :edit, :sort_project_members, :update, :modules, :close, :reopen,:view_homework_attaches,:course] before_filter :authorize_global, :only => [:new, :create,:view_homework_attaches] before_filter :require_admin, :only => [ :copy, :archive, :unarchive, :destroy, :calendar] before_filter :file, :statistics, :watcherlist - #before_filter :find_project_repository, :only => [:show] # 除非项目内人员,不可查看成员, TODO: 完了写报表里去 before_filter :memberAccess, only: :member - accept_rss_auth :index + # accept_rss_auth :index accept_api_auth :index, :show, :create, :update, :destroy after_filter :only => [:create, :edit, :update, :archive, :unarchive, :destroy] do |controller| @@ -82,369 +76,66 @@ class ProjectsController < ApplicationController ### added by william include ActsAsTaggableOn::TagsHelper - def find_project_repository - unless @project.repositories.nil? - @project.repositories.each do |repository| - repository.fetch_changesets if Setting.autofetch_changesets? - end - end - end - - def enterprise_course - session[:enterprise_college] = 2 - respond_to do |format| - format.html { redirect_to :back } - #format.api { render_api_ok } - end - end - - def course_enterprise - session[:enterprise_college] = 1 - respond_to do |format| - format.html { redirect_to :back } - #format.api { render_api_ok } - end - end - def index render_404 - #调用存储过程更新提交次数 - #ActiveRecord::Base.connection.execute("CALL sp_project_status_cursor();") - #Modified by nie - @project_type = params[:project_type].to_i - per_page_option = 10 - - @projects_all = Project.active.visible. - joins("LEFT JOIN #{ProjectStatus.table_name} ON #{Project.table_name}.id = #{ProjectStatus.table_name}.project_id").joins("LEFT JOIN #{ProjectScore.table_name} ON #{Project.table_name}.id = #{ProjectScore.table_name}.project_id"). - where("#{Project.table_name}.project_type = ? ", Project::ProjectType_project) - - @poll_questions_count = @projects_all.count - @poll_questions_pages = Paginator.new @project_count, per_page_option, params['page'] - -#gcm activity count - - @project_activity_count=Hash.new - - @projects_all.each do |project| - @project_activity_count[project.id]=0 - end - - @project_activity_count=get_project_activity @projects_all,@project_activity_count - -#gcm end - - case params[:project_sort_type] - when '0' - @projects = @projects_all.order("created_on desc") - @s_type = 0 - when '1' - @projects = @projects_all.order("score desc") - @s_type = 1 - when '2' - @projects = @projects_all.order("watchers_count desc") - @s_type = 2 - - #gcm - when '3' - #@projects=desc_sort_course_by_avtivity(@project_activity_count_array,@project_all_array) - @projects=handle_project @projects_all,@project_activity_count - @s_type = 3 - @projects = @projects[@project_pages.offset, @project_pages.per_page] - - else - @projects = @projects = @projects_all.order("score desc") - @s_type = 1 - end - @projects = @projects.offset(@project_pages.offset).limit(@project_pages.per_page) - - - respond_to do |format| - format.html { - # render :layout => 'base' - # scope = Project - # unless params[:closed] - # scope = scope.active - # end - } - format.api { - # @offset, @limit = api_offset_and_limit - # @project_count = Project.visible.count - # @projects = Project.visible.offset(@offset).limit(@limit).order('lft').all - } - format.atom { - projects = Project.visible.order('created_on DESC').limit(Setting.feeds_limit.to_i).all - render_feed(projects, :title => "#{Setting.app_title}: #{l(:label_project_latest)}") - } - end end def course - @project_type = params[:project_type] - @school_id = params[:school_id] - per_page_option = 10 - if @school_id == "0" or @school_id.nil? - @projects_all = Project.active.visible. - joins("LEFT JOIN #{ProjectStatus.table_name} ON #{Project.table_name}.id = #{ProjectStatus.table_name}.project_id"). - where("#{Project.table_name}.project_type = ? ", Project::ProjectType_course) - else - @projects_all = Project.active.visible. - joins("LEFT JOIN #{ProjectStatus.table_name} ON #{Project.table_name}.id = #{ProjectStatus.table_name}.project_id"). - joins(:course_extra). - where("#{Project.table_name}.project_type = ? AND #{Course.table_name}.school_id = ?", Project::ProjectType_course, @school_id) - end - - @project_count = @projects_all.count - @project_pages = Paginator.new @project_count, per_page_option, params['page'] - - #gcm activity count - - @project_activity_count=Hash.new - #count initialize - @projects_all.each do |project| - @project_activity_count[project.id]=0 - end - - #@project_activity_count=get_project_activity @projects_all,@project_activity_count - #gcm end - - - case params[:project_sort_type] - when '0' - @projects = @projects_all.order("created_on desc") - @s_type = 0 - @projects = @projects.offset(@project_pages.offset).limit(@project_pages.per_page) - - #gcm - @project_activity_count=get_project_activity @projects,@project_activity_count - #gcmend - - when '1' - @projects = @projects_all.order("course_ac_para desc") - @s_type = 1 - @projects = @projects.offset(@project_pages.offset).limit(@project_pages.per_page) - - #gcm - @project_activity_count=get_project_activity @projects,@project_activity_count - #gcmend - - when '2' - @projects = @projects_all.order("watchers_count desc") - @s_type = 2 - @projects = @projects.offset(@project_pages.offset).limit(@project_pages.per_page) - - #gcm - @project_activity_count=get_project_activity @projects,@project_activity_count - #gcmend - - #gcm - when '3' - - #gcm - @project_activity_count=get_project_activity @projects_all,@project_activity_count - #gcmend - - @projects=handle_project @projects_all,@project_activity_count - @s_type = 3 - @projects = @projects[@project_pages.offset, @project_pages.per_page] - else - @s_type = 0 - @projects = @projects_all.order("created_on desc") - @projects = @projects.offset(@project_pages.offset).limit(@project_pages.per_page) - - #gcm - @project_activity_count=get_project_activity @projects,@project_activity_count - #gcmend - - end - - respond_to do |format| - format.html { - render :layout => 'base' - } - format.api { - # @offset, @limit = api_offset_and_limit - # @project_count = Project.visible.count - # @projects = Project.visible.offset(@offset).limit(@limit).order('lft').all - } - format.atom { - projects = Project.visible.order('created_on DESC').limit(Setting.feeds_limit.to_i).all - render_feed(projects, :title => "#{Setting.app_title}: #{l(:label_project_latest)}") - } - end + render_404 end -#gcm + # Time 2015-01-29 11:19:11 + # Author lizanle + # Description 项目搜索方法 def search - #modified by nie - project_type = params[:project_type].to_i - projects_all = (project_type.eql? Project::ProjectType_course) ? Project.course_entities : Project.project_entities - @projects = projects_all.visible - #@projects_all = @projects.visible.like(params[:name]) if params[:name].present? + # 如果有名字,就按名字搜索,如果没有,就展示所有,用Karminari分页 if params[:name].present? - @projects_all = @projects.visible.like(params[:name]) + @project_pages = Project.project_entities.visible.like(params[:name]).page(params[:page]).per(10) else - @projects_all = @projects; + @project_pages = Project.project_entities.visible.page(params[:page] ).per(10) end - @project_count = @projects_all.count - @project_pages = Paginator.new @project_count, per_page_option, params['page'] - - #gcm activity count - - @project_activity_count=Hash.new - # count initialize - @projects_all.each do |project| - @project_activity_count[project.id]=0 - end - - #@project_activity_count=get_project_activity @projects_all,@project_activity_count - - #gcm end - - - case params[:project_sort_type] - when '0' - @projects = @projects_all.order("created_on desc") - @s_type = 0 - @projects = @projects.offset(@project_pages.offset).limit(@project_pages.per_page) - - #gcm - @project_activity_count=get_project_activity @projects,@project_activity_count - #gcmend - - when '1' - @projects = @projects_all.order("course_ac_para desc") - @s_type = 1 - @projects = @projects.offset(@project_pages.offset).limit(@project_pages.per_page) - - #gcm - @project_activity_count=get_project_activity @projects,@project_activity_count - #gcmend - - when '2' - @projects = @projects_all.order("watchers_count desc") - @s_type = 2 - @projects = @projects.offset(@project_pages.offset).limit(@project_pages.per_page) - - #gcm - @project_activity_count=get_project_activity @projects,@project_activity_count - #gcmend - - when '3' - #@projects=desc_sort_course_by_avtivity(@project_activity_count_array,@project_all_array) - @project_activity_count=get_project_activity @projects_all,@project_activity_count_array #gcm - @projects=handle_project @projects_all,@project_activity_count - @s_type = 3 - @projects = @projects[@project_pages.offset, @project_pages.per_page] - - else - @s_type = 0 - @projects = @projects_all.order("created_on desc") - @projects = @projects.offset(@project_pages.offset).limit(@project_pages.per_page) - - #gcm - @project_activity_count=get_project_activity @projects,@project_activity_count - #gcmend - - end - + @projects = @project_pages.order("created_on desc") respond_to do |format| format.html { render :layout => 'base' scope = Project unless params[:closed] - scope = scope.active + scope = scope.active end } - format.api { - # @offset, @limit = api_offset_and_limit - # @project_count = Project.visible.count - # @projects = Project.visible.offset(@offset).limit(@limit).order('lft').all - } + # 需要到处atom使用的格式 (redmine自带) format.atom { projects = Project.visible.order('created_on DESC').limit(Setting.feeds_limit.to_i).all render_feed(projects, :title => "#{Setting.app_title}: #{l(:label_project_latest)}") } end end -#gcmend - - - #Added by young - def homework - @offset, @limit = api_offset_and_limit({:limit => 10}) - @bids = @project.homeworks.order('deadline') - @bids = @bids.like(params[:name]) if params[:name].present? - - @bids = paginateHelper @bids - render :layout => 'base_courses' - - end - - def new_homework - # Dear maintainer: - # once you are done trying to 'optimize' this Magic routine, - # well, it's on you, I'll leave it to you. - if (User.current.logged? && - (User.current.admin? || - ( - !Member.where('user_id = ? and project_id = ?', User.current.id, @project.id).first.nil? && - ( - Member.where('user_id = ? and project_id = ?', User.current.id, @project.id).first.roles && - ( Role.where(id: [3, 4, 7, 9]).size > 0 ) - ) - ) - ) - ) - @homework = Bid.new - @homework.safe_attributes = params[:bid] - render :layout => 'base_courses' - else - render_404 - end - - end - #Ended by young + # Time 2015-01-29 16:13:20 + # Author lizanle + # Description 项目首页中用户反馈 方法 def feedback - @page = params[:page] - @page = @page.to_i + @page = params[:page].to_i # Find the page of the requested reply @jours = @project.journals_for_messages.where('m_parent_id IS NULL').order('created_on DESC') - @limit = 10 + limit = 10 offset = @jours.count(:conditions => ["#{JournalsForMessage.table_name}.id > ?", params[:r].to_i]) - page = 1 + offset / @limit + page = 1 + offset / limit if params[:r] && @page.nil? - @page = page - end - - puts @page - if @page < 0 - @page = 1 - end - if @page > page - @page = page + @page = @page < 0 ? 1 : @page end - - - #@feedback_count = @jours.count - #@feedback_pages = Paginator.new @feedback_count, @limit, @page - #@offset ||= @feedback_pages.offset + @page = @page > page ? page : @page @jour = paginateHelper @jours,10 @state = false - @base_courses_tag = @project.project_type - - respond_to do |format| - format.html{render :layout => 'base_courses' if @base_courses_tag==1} + format.html format.api end end def project_respond - # will_reply = JournalsForMessage.find(params[:reference_id]) if params[:reference_id] project_id = request.headers["Referer"].match((%r|/([0-9]{1,})/|))[1] - # @project = Project.find_by_id(project_id) parent_id = params[:reference_id] author_id = User.current.id reply_user_id = params[:reference_user_id] @@ -460,12 +151,8 @@ class ProjectsController < ApplicationController @jfm = Project.add_new_jour(nil, nil, project_id, options) @save_succ = @jfm.errors.empty? - # flash[:notice]=l(:label_projects_feedback_respond_success) - respond_to do |format| - # format.html { redirect_to :back } format.js - #format.api { render_api_ok } end end @@ -556,45 +243,18 @@ class ProjectsController < ApplicationController render_404 end - # Show @project + # Time 2015-01-29 10:42:00 + # Author lizanle + # Description 项目动态展示方法,删除了不必要的代码 def show - if(@project && !@project.is_public && !User.current.member_of?(@project)) - render_403 - return - end - - @project_type = params[:project_type] - - # try to redirect to the requested menu item + # 试图跳转到请求的按钮 if params[:jump] && redirect_to_project_menu_item(@project, params[:jump]) - return + return end - @users_by_role = @project.users_by_role - @subprojects = @project.children.visible.all - @news = @project.news.limit(5).includes(:author, :project).reorder("#{News.table_name}.created_on DESC").all - @trackers = @project.rolled_up_trackers - if(User.find_by_id(ProjectInfo.find_by_project_id(@project.id).try(:user_id))) - @user = User.find_by_id(ProjectInfo.find_by_project_id(@project.id).user_id) - end cond = @project.project_condition(Setting.display_subprojects_issues?) - @open_issues_by_tracker = Issue.visible.open.where(cond).count(:group => :tracker) - @total_issues_by_tracker = Issue.visible.where(cond).count(:group => :tracker) - - if User.current.allowed_to?(:view_time_entries, @project) - @total_hours = TimeEntry.visible.sum(:hours, :include => :project, :conditions => cond).to_f - end - - @key = User.current.rss_key - #新增内容 - @days = Setting.activity_days_default.to_i - - if params[:from] - begin; @date_to = params[:from].to_date + 1; rescue; end - end - has = { - "show_issues" => true, + "show_issues" => true , "show_files" => true, "show_documents" => true, "show_messages" => true, @@ -604,59 +264,40 @@ class ProjectsController < ApplicationController "show_wiki_edits"=>true, "show_journals_for_messages" => true } - - + # 读取项目默认展示的动态时间天数 + @days = Setting.activity_days_default.to_i + @date_to ||= Date.today + 1 + # 时间跨度不能太大,不然很慢,所以删掉了-1.years + @date_from = @date_to - @days @with_subprojects = params[:with_subprojects].nil? ? Setting.display_subprojects_issues? : (params[:with_subprojects] == '1') - @author = (params[:user_id].blank? ? nil : User.active.find(params[:user_id])) + @author = params[:user_id].blank? ? nil : User.active.find(params[:user_id]) # 决定显示所用用户或单个用户活动 - @activity = Redmine::Activity::Fetcher.new(User.current, :project => @project, - :with_subprojects => @with_subprojects, - :author => @author) + @activity = Redmine::Activity::Fetcher.new(User.current, + :project => @project, + :with_subprojects => @with_subprojects, + :author => @author) @activity.scope_select {|t| !has["show_#{t}"].nil?} - # logger.debug "=========================================#{@activity.scope}" - # @activity.scope = (@author.nil? ? :default : :all) if @activity.scope.empty? - # modify by nwb - # 添加私密性判断 - if User.current.member_of?(@project)|| User.current.admin? - events = @activity.events(@days) + # 根据私密性,取出符合条件的所有数据 + if User.current.member_of?(@project) || User.current.admin? + events = @activity.events(@date_from, @date_to) else - events = @activity.events(@days,nil, :is_public => 1) + 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'] @offset ||= @events_pages.offset + # 总的数据中取出某一页 events = events.slice(@offset,@limit) - #Ended by young + # 按天分组 @events_by_day = events.group_by {|event| User.current.time_to_date(event.event_datetime)} - # documents - @sort_by = %w(category date title author).include?(params[:sort_by]) ? params[:sort_by] : 'category' - documents = @project.documents.includes(:attachments, :category).all - case @sort_by - when 'date' - @grouped = documents.group_by {|d| d.updated_on.to_date } - when 'title' - @grouped = documents.group_by {|d| d.title.first.upcase} - when 'author' - @grouped = documents.select{|d| d.attachments.any?}.group_by {|d| d.attachments.last.author} - else - @grouped = documents.group_by(&:category) - end - @document = @project.documents.build - # - @base_courses_tag = @project.project_type - #判断能否显示真名(当前用户为课程的教师时显示真名) - if @project.project_type == Project::ProjectType_course - @teachers= searchTeacherAndAssistant(@project) - @canShowRealName = isCourseTeacher(User.current.id) - end - # real_name action为虚拟的该方法并不存在,用来辅助判断真名权限 - # @canShowRealName = User.current.allowed_to?({:controller => "projects", :action => "real_name"}, @project || @projects, :global => false) + # 根据对应的请求,返回对应的数据 respond_to do |format| - format.html{render :layout => 'base_courses' if @base_courses_tag==1} + format.html format.api end end @@ -667,23 +308,13 @@ class ProjectsController < ApplicationController @member ||= @project.members.new @trackers = Tracker.sorted.all @wiki ||= @project.wiki - #Added by young - # @course_tag = params[:course] - # if @course_tag == '1' - #@course = Course.find_by_extra(@project.identifier) - # if @project.project_type == 1 - # render :layout => 'base_courses' - # else - # render :layout => 'base_projects' - # end - #Ended by young end def edit end - #by young - include CoursesHelper + # by young + # include CoursesHelper def member ## 有角色参数的才是课程,没有的就是项目 @render_file = 'member_list' @@ -702,11 +333,10 @@ class ProjectsController < ApplicationController @subPage_title = '' @members = @project.member_principals.includes(:roles, :principal).all.sort end - else # @project.project_type == Project::ProjectType_project + else roles = Role.find_all_givable @subPage_title = l :label_member_list @members = @project.member_principals.includes(:roles, :principal).joins("LEFT JOIN #{OptionNumber.table_name} ON #{OptionNumber.table_name}.user_id = #{Member.table_name}.user_id and #{OptionNumber.table_name}.score_type = 2 AND #{Member.table_name}.project_id = #{OptionNumber.table_name}.project_id").order("#{OptionNumber.table_name}.total_score DESC").all - #@members = sort_project_members(@project, @members) @applied_members = appied_project_members(@project, @members) end @members = paginateHelper @members @@ -971,91 +601,6 @@ class ProjectsController < ApplicationController end end - - - #gcm - def get_project_activity projects,activities - @project_ids=activities.keys() - - days = Setting.activity_days_default.to_i - date_to ||= Date.today + 1 - date_from = date_to - days-1.years - - #issue_count - Issue.where(project_id: @project_ids).where("updated_on>?",date_from).each do |issue| -# activities[issue.project_id.to_s]+=1 - activities[issue.project_id]+=issue.journals.where("created_on>?",date_from).count - end - - #repository_count - Repository.where(project_id: @project_ids).each do |repository| -# activities[repository.project_id.to_s]+=1 - activities[repository.project_id]+=repository.changesets.where("committed_on>?",date_from).count - end - - - #news_count - News.where(project_id: @project_ids).where("created_on>?",date_from).each do |news| - activities[news.project_id]+=1 - end - - #document_count - Document.where(project_id: @project_ids).where("created_on>?",date_from).each do |document| - activities[document.project_id]+=1 - end - - #file_count - Attachment.where(container_id: @project_ids, container_type: Project).where("created_on>?",date_from).each do |attachment| - activities[attachment.container_id]+=1 - end - - #message_count - Board.where(project_id: @project_ids).each do |board| -# activities[board.project_id]+=1 - activities[board.project_id]+=board.messages.where("updated_on>?",date_from).count - end - - #time_entry_count - TimeEntry.where(project_id: @project_ids).where("updated_on>?",date_from).each do |timeentry| - activities[timeentry.project_id]+=1 - end - - #feedbackc_count - JournalsForMessage.where(jour_id: @project_ids, jour_type: Project).each do |jourformess| - activities[jourformess.jour_id]+=1 - end - - #activities!=0 - i=0; - projects.each do |project| - id=project.id - if activities[id]==0 - activities[id]=1 - end - end - - return activities - end - #gcmend - - #gcm - def handle_project projects,activities - project_activity_count_array=activities.values() - - project_array=[] - i=0; - projects.each do |project| - project_array[i]=project - i=i+1 - end - - projects=desc_sort_course_by_avtivity(project_activity_count_array,project_array) - - return projects - end - #gcmend - - #gcm def desc_sort_course_by_avtivity(activity_count,projects) return projects if activity_count.size<2 diff --git a/app/controllers/system_log_controller.rb b/app/controllers/system_log_controller.rb new file mode 100644 index 000000000..274cb18a9 --- /dev/null +++ b/app/controllers/system_log_controller.rb @@ -0,0 +1,59 @@ +# Time 2015-01-26 17:12:23 +# Author lizanle +# Description 显示和清理系统日志 +class SystemLogController < ApplicationController + + before_filter :require_admin + # 默认每页显示20条记录 + PER_PAGE = 20 + layout "base" + include SystemLogHelper + + # Time 2015-01-26 17:12:46 + # Author lizanle + # Description 查看所有日志 + def index + @logs = SystemLog.logo_data(params[:page]||1, params[:per]||PER_PAGE, params[:search], params[:day]) + end + + # Time 2015-01-26 14:42:38 + # Author lizanle + # Description 清除日志 + def clear + SystemLog.clear params[:day] + redirect_to :action => :index + end + + # Time 2015-01-26 17:24:25 + # Author lizanle + # Description 访问分析 + def access_analysis + #解析日志,然后逆序 + @log_result = SystemLog.analysis(params[:day]).reverse[1...-1] + @access_module = Hash.new + #日誌可能為空 + if @log_result && !@log_result.empty? + #将数组中的模块访问统计出来放到hash中 每条记录的第四个值是Controller#action的形式 + @log_result.collect! { |r| @access_module[r[3]].nil? ? + @access_module[r[3]] = 1 : @access_module[r[3]] +=1 } + # 去掉key可能为空记录 排序,然后取逆序 + @access_module = @access_module.delete_if { |k, v| k.nil? }.sort_by { |key, val| val }.reverse + else + @access_module + end + end + + # Time 2015-01-26 17:24:36 + # Author lizanle + # Description 耗时分析 + def time_analysis + #解析日志 + @log_result = SystemLog.analysis(params[:day]).reverse[1...-1] + if @log_result && !@log_result.empty? + #分页 + @log_result = Kaminari.paginate_array(@log_result).page(params[:page]||1).per(params[:per]||PER_PAGE) + else + @log_result = [] + end + end +end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 58af43da3..a2933c577 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -358,8 +358,7 @@ class UsersController < ApplicationController respond_to do |format| format.html { @groups = Group.all.sort - # render :layout => @user_base_tag - render_404 + User.current.admin? ? (render :layout => @user_base_tag) : (render_404) } format.api end @@ -369,34 +368,35 @@ class UsersController < ApplicationController sort_init 'login', 'asc' sort_update %w(login firstname lastname mail admin created_on last_login_on) (redirect_to user_url, :notice => l(:label_sumbit_empty);return) if params[:name].blank? - case params[:format] - when 'xml', 'json' - @offset, @limit = api_offset_and_limit({:limit => 15}) + case params[:format] + when 'xml', 'json' + @offset, @limit = api_offset_and_limit({:limit => 15}) + else + @limit = 15#per_page_option + end + # + #@status = params[:status] || 1 + #has = { + # "show_changesets" => true + #} + # scope = User.logged.status(@status) + # @search_by = params[:search_by] ? params[:search_by][:id] : 0 + # scope = scope.like(params[:name],@search_by) if params[:name].present? + us = UsersService.new + scope = us.search_user params + @user_count = scope.count + @user_pages = Paginator.new @user_count, @limit, params['page'] + @user_base_tag = params[:id] ? 'base_users':'users_base' + @offset ||= @user_pages.reverse_offset + unless @offset == 0 + @users = scope.offset(@offset).limit(@limit).all.reverse else - @limit = 15#per_page_option + limit = @user_count % @limit + if limit == 0 + limit = @limit + end + @users = scope.offset(@offset).limit(limit).all.reverse end - - @status = params[:status] || 1 - has = { - "show_changesets" => true - } - scope = User.logged.status(@status) - @search_by = params[:search_by] ? params[:search_by] :"0" - scope = scope.like(params[:name], @search_by) if params[:name].present? - @user_count = scope.count - @user_pages = Paginator.new @user_count, @limit, params['page'] - @user_base_tag = params[:id] ? 'base_users':'users_base' - @offset ||= @user_pages.reverse_offset - unless @offset == 0 - @users = scope.offset(@offset).limit(@limit).all.reverse - else - limit = @user_count % @limit - if limit == 0 - limit = @limit - end - @users = scope.offset(@offset).limit(limit).all.reverse - end - respond_to do |format| format.html { @groups = Group.all.sort diff --git a/app/controllers/watchers_controller.rb b/app/controllers/watchers_controller.rb index 50bb2ccd8..f6d01a03d 100644 --- a/app/controllers/watchers_controller.rb +++ b/app/controllers/watchers_controller.rb @@ -15,13 +15,37 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. class WatchersController < ApplicationController - before_filter :require_login, :find_watchables, :only => [:watch, :unwatch] + before_filter :require_login#, :find_watchables, :only => [:watch, :unwatch] def watch - set_watcher(@watchables, User.current, true) + s = WatchesService.new + watchables = s.watch params.merge(:current_user_id => User.current.id) + respond_to do |format| + format.html { redirect_to_referer_or {render :text => (true ? 'Watcher added.' : 'Watcher removed.'), :layout => true}} + format.js { render :partial => 'set_watcher', :locals => {:user => User.current, :watched => watchables} } + end + rescue Exception => e + if e.message == "404" + render_404 + else + raise e + end + #set_watcher(@watchables, User.current, true) end def unwatch - set_watcher(@watchables, User.current, false) + s = WatchesService.new + watchables = s.unwatch params.merge(:current_user_id => User.current.id) + respond_to do |format| + format.html { redirect_to_referer_or {render :text => (false ? 'Watcher added.' : 'Watcher removed.'), :layout => true}} + format.js { render :partial => 'set_watcher', :locals => {:user => User.current, :watched => watchables} } + end + rescue Exception => e + if e.message == "404" + render_404 + else + raise e + end + #set_watcher(@watchables, User.current, false) end def join @@ -162,4 +186,5 @@ class WatchersController < ApplicationController format.js { render :partial => 'set_watcher', :locals => {:user => user, :watched => watchables} } end end + end diff --git a/app/controllers/welcome_controller.rb b/app/controllers/welcome_controller.rb index 8e11bceb5..b1138f964 100644 --- a/app/controllers/welcome_controller.rb +++ b/app/controllers/welcome_controller.rb @@ -25,6 +25,17 @@ class WelcomeController < ApplicationController before_filter :entry_select, :only => [:index] def index + unless params[:originization].nil? + @originization = params[:originization] + @originization_projects = Project.find_by_sql(["select * from projects where enterprise_name =? ", @originization]) + @e_count = @originization_projects.count + if @e_count < 10 + part_count = 10 -@e_count + # @part_projects = find_all_hot_project part_count, order + @part_projects = find_miracle_project(part_count, 3,"score desc") + limit = 10 - @e_count + end + end if @first_page.nil? || @first_page.sort_type.nil? @projects = find_miracle_project(10, 3,"score desc") else diff --git a/app/helpers/account_helper.rb b/app/helpers/account_helper.rb index 8beeac363..8ef2d6095 100644 --- a/app/helpers/account_helper.rb +++ b/app/helpers/account_helper.rb @@ -18,4 +18,45 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. module AccountHelper + + def email_activation_register(user, &block) + token = Token.new(:user => user, :action => "register") + if user.save and token.save + UserStatus.create(:user_id => user.id, :changsets_count => 0, :watchers_count => 0) + Mailer.register(token).deliver + #flash[:notice] = l(:notice_account_register_done) + #render action: 'email_valid', locals: {:mail => user.mail} + else + yield if block_given? + end + user + end + + def automatically_register(user, &block) + # Automatic activation + user.activate + user.last_login_on = Time.now + if user.save + UserStatus.create(:user_id => user.id, :changsets_count => 0, :watchers_count => 0) + #self.logged_user = user + #flash[:notice] = l(:notice_account_activated) + #redirect_to my_account_url + else + yield if block_given? + end + user + end + + def administrator_manually__register(user, &block) + if user.save + UserStatus.create(:user_id => user.id ,:changsets_count => 0, :watchers_count => 0) + # Sends an email to the administrators + Mailer.account_activation_request(user).deliver + #account_pending + else + yield if block_given? + end + user + end + end diff --git a/app/helpers/api_helper.rb b/app/helpers/api_helper.rb new file mode 100644 index 000000000..8ff6f725c --- /dev/null +++ b/app/helpers/api_helper.rb @@ -0,0 +1,40 @@ +module ApiHelper + #获取用户的工作单位 + def get_user_work_unit user + work_unit = "" + if user.user_extensions.identity == 0 || user.user_extensions.identity == 1 + work_unit = user.user_extensions.school.name unless user.user_extensions.school.nil? + elsif user.user_extensions.identity == 3 + work_unit = user.user_extensions.occupation + elsif user.user_extensions.identity == 2 + work_unit = user.firstname + end + work_unit + end + + #获取用户地区 + def get_user_location user + location = "" + location << (user.user_extensions.location || '') + location << (user.user_extensions.location_city || '') + location + end + + + def get_assigned_homeworks(homeworks, n, index) + homeworks += homeworks + homeworks[index + 1 .. index + n] + end + + + def stars_to_json_like starts,show_jour,homework,show_name + result = [] + starts.each do |s| + comment = get_homework_review homework,show_jour,s.rater + rater_name = show_name ? s.rater.login : l(:label_anonymous) + rater_id = show_name ? s.rater.id : '' + result << {:rater_id =>rater_id ,:rater_name => rater_name,:created_at => format_time(s.created_at),:stars => s.stars,:comment => comment} + end + result + end +end \ No newline at end of file diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index caf29ba90..5579fe79b 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1844,7 +1844,7 @@ module ApplicationHelper 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_project_module_forums), {:controller => "forums", :action => "index"} + forum_link = link_to l(:label_forum_all), {:controller => "forums", :action => "index"} stores_link = link_to l(:label_stores_index), {:controller => 'stores', :action=> 'index'} school_all_school_link = link_to l(:label_school_all), {:controller => 'school', :action => 'index'} @@ -1961,4 +1961,17 @@ module ApplicationHelper end confirm_info end + + def get_technical_title user + if user.user_extensions.technical_title == "Professor" || user.user_extensions.technical_title == "教授" + technical_title = l(:label_technicl_title_professor) + elsif user.user_extensions.technical_title == "Associate professor" || user.user_extensions.technical_title == "副教授" + technical_title = l(:label_technicl_title_associate_professor) + elsif user.user_extensions.technical_title == "Lecturer" || user.user_extensions.technical_title == "讲师" + technical_title = l(:label_technicl_title_lecturer) + elsif user.user_extensions.technical_title == "Teaching assistant" || user.user_extensions.technical_title == "助教" + technical_title = l(:label_technicl_title_teaching_assistant) + end + technical_title + end end diff --git a/app/helpers/expire_helper.rb b/app/helpers/expire_helper.rb new file mode 100644 index 000000000..0a9cab69c --- /dev/null +++ b/app/helpers/expire_helper.rb @@ -0,0 +1,16 @@ +module ExpireHelper + #index.html 中 “projects”塊 緩存過期 + def expire_project_cache + ActionController::Base.new.expire_fragment('projects') + end + + #index.html 中 “activities”塊 緩存過期 + def expire_activitie_cache + ActionController::Base.new.expire_fragment('activities') + end + + #welcome/index.html 中 “forums”塊 緩存過期 + def expire_forum_cache + ActionController::Base.new.expire_fragment('forums') + end +end diff --git a/app/helpers/homework_attach_helper.rb b/app/helpers/homework_attach_helper.rb index 4744df624..c41ba54ee 100644 --- a/app/helpers/homework_attach_helper.rb +++ b/app/helpers/homework_attach_helper.rb @@ -119,4 +119,15 @@ module HomeworkAttachHelper #end ary end + + def get_student_batch_homework_list bid,user + student_batch_homework_list = HomeworkAttach.eager_load(:attachments,:user,:rate_averages).find_by_sql("SELECT homework_attaches.*, + (SELECT stars FROM seems_rateable_rates WHERE rateable_type = 'HomeworkAttach' AND rateable_id = homework_attaches.id AND is_teacher_score = 1 AND stars IS NOT NULL ORDER BY updated_at DESC limit 0,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.current.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 + WHERE homework_attaches.bid_id = #{bid.id} AND homework_evaluations.user_id = #{user.id} ORDER BY m_score DESC") + student_batch_homework_list + end end \ No newline at end of file diff --git a/app/helpers/originizations_helper.rb b/app/helpers/originizations_helper.rb new file mode 100644 index 000000000..10321ba16 --- /dev/null +++ b/app/helpers/originizations_helper.rb @@ -0,0 +1,2 @@ +module EnterprisesHelper +end diff --git a/app/helpers/poll_helper.rb b/app/helpers/poll_helper.rb index 60d82c096..3156f1b3a 100644 --- a/app/helpers/poll_helper.rb +++ b/app/helpers/poll_helper.rb @@ -64,13 +64,13 @@ module PollHelper def options_show pq case pq when 1 - "单选题" + l(:label_MC) when 2 - "多选题" + l(:label_MCQ) when 3 - "单行主观题" + l(:label_single) else - "多行主观题" + l(:label_mulit) end end diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 5df3644ad..fe6714186 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -36,67 +36,8 @@ module ProjectsHelper {:name => 'activities', :action => :manage_project_activities, :partial => 'projects/settings/activities', :label => :enumeration_activities} ] tabs.select {|tab| User.current.allowed_to?(tab[:action], @project)} - end - # added bu huang - def sort_project_enterprise(state, project_type) - content = ''.html_safe - case state - when 0 - - content << content_tag('li', link_to(l(:label_sort_by_active), projects_path(:project_sort_type => '1', :project_type => project_type))) - content << content_tag('li', link_to(l(:label_sort_by_influence), projects_path(:project_sort_type => '2', :project_type => project_type))) - content << content_tag('li', link_to(l(:label_sort_by_time), projects_path(:project_sort_type => '0', :project_type => project_type), :class=>"selected"), :class=>"selected") - when 1 - - content << content_tag('li', link_to(l(:label_sort_by_active), projects_path(:project_sort_type => '1', :project_type => project_type), :class=>"selected"), :class=>"selected") - content << content_tag('li', link_to(l(:label_sort_by_influence), projects_path(:project_sort_type => '2', :project_type => project_type))) - content << content_tag('li', link_to(l(:label_sort_by_time), projects_path(:project_sort_type => '0', :project_type => project_type))) - when 2 - content << content_tag('li', link_to(l(:label_sort_by_active), projects_path(:project_sort_type => '1', :project_type => project_type))) - content << content_tag('li', link_to(l(:label_sort_by_influence), projects_path(:project_sort_type => '2', :project_type => project_type), :class=>"selected"), :class=>"selected") - content << content_tag('li', link_to(l(:label_sort_by_time), projects_path(:project_sort_type => '0', :project_type => project_type))) - end - content = content_tag('ul', content) - content_tag('div', content, :class => "tabs_enterprise") - end - - def sort_course(state, project_type, school_id) - content = ''.html_safe - case state - when 0 - content << content_tag('li', link_to(l(:label_sort_by_time), course_path(:project_sort_type => '0', :project_type => project_type), :school_id => school_id, :class=>"selected"), :class=>"selected") - content << content_tag('li', link_to(l(:label_sort_by_active), course_path(:project_sort_type => '1', :project_type => project_type, :school_id => school_id))) - # content << content_tag('li', link_to(l(:label_sort_by_influence), course_path(:project_sort_type => '2', :project_type => project_type))) - content << content_tag('li', link_to(l(:label_sort_by_activity), course_path(:project_sort_type => '3', :project_type => project_type, :school_id => school_id))) - - when 1 - content << content_tag('li', link_to(l(:label_sort_by_time), course_path(:project_sort_type => '0', :project_type => project_type, :school_id => school_id))) - content << content_tag('li', link_to(l(:label_sort_by_active), course_path(:project_sort_type => '1', :project_type => project_type, :school_id => school_id), :class=>"selected"), :class=>"selected") - # content << content_tag('li', link_to(l(:label_sort_by_influence), course_path(:project_sort_type => '2', :project_type => project_type))) - content << content_tag('li', link_to(l(:label_sort_by_activity), course_path(:project_sort_type => '3', :project_type => project_type, :school_id => school_id))) - - when 2 - content << content_tag('li', link_to(l(:label_sort_by_time), course_path(:project_sort_type => '0', :project_type => project_type, :school_id => school_id))) - content << content_tag('li', link_to(l(:label_sort_by_active), course_path(:project_sort_type => '1', :project_type => project_type, :school_id => school_id))) - # content << content_tag('li', link_to(l(:label_sort_by_influence), course_path(:project_sort_type => '2', :project_type => project_type), :class=>"selected"), :class=>"selected") - content << content_tag('li', link_to(l(:label_sort_by_activity), course_path(:project_sort_type => '3', :project_type => project_type, :school_id => school_id))) - - #gcm - when 3 - content << content_tag('li', link_to(l(:label_sort_by_time), course_path(:project_sort_type => '0', :project_type => project_type, :school_id => school_id))) - content << content_tag('li', link_to(l(:label_sort_by_active), course_path(:project_sort_type => '1', :project_type => project_type, :school_id => school_id))) - # content << content_tag('li', link_to(l(:label_sort_by_influence), course_path(:project_sort_type => '2', :project_type => project_type))) - content << content_tag('li', link_to(l(:label_sort_by_activity), course_path(:project_sort_type => '3', :project_type => project_type, :school_id => school_id), :class=>"selected"), :class=>"selected") - end - #gcmend - - content = content_tag('ul', content) - content_tag('div', content, :class => "tabs") - end - # end - def sort_project(state, project_type) content = ''.html_safe case state @@ -118,30 +59,7 @@ module ProjectsHelper content = content_tag('ul', content) content_tag('div', content, :class => "tabs") end - - # def sort_course(state, project_type) - # content = ''.html_safe - # case state - # when 0 -# - # content << content_tag('li', link_to(l(:label_sort_by_active), course_path(:project_sort_type => '1', :project_type => project_type))) - # content << content_tag('li', link_to(l(:label_sort_by_influence), course_path(:project_sort_type => '2', :project_type => project_type))) - # content << content_tag('li', link_to(l(:label_sort_by_time), course_path(:project_sort_type => '0', :project_type => project_type), :class=>"selected"), :class=>"selected") - # when 1 -# - # content << content_tag('li', link_to(l(:label_sort_by_active), course_path(:project_sort_type => '1', :project_type => project_type), :class=>"selected"), :class=>"selected") - # content << content_tag('li', link_to(l(:label_sort_by_influence), course_path(:project_sort_type => '2', :project_type => project_type))) - # content << content_tag('li', link_to(l(:label_sort_by_time), course_path(:project_sort_type => '0', :project_type => project_type))) - # when 2 - # content << content_tag('li', link_to(l(:label_sort_by_active), course_path(:project_sort_type => '1', :project_type => project_type))) - # content << content_tag('li', link_to(l(:label_sort_by_influence), course_path(:project_sort_type => '2', :project_type => project_type), :class=>"selected"), :class=>"selected") - # content << content_tag('li', link_to(l(:label_sort_by_time), course_path(:project_sort_type => '0', :project_type => project_type))) - # end - # content = content_tag('ul', content) - # content_tag('div', content, :class => "tabs") - # end - # Added by young def course_settings_tabs tabs = [{:name => 'info', :action => :edit_project, :partial => 'projects/edit', :label => :label_information_plural, :course=>'1'}, @@ -153,9 +71,6 @@ module ProjectsHelper end # Ended by young - - - def parent_project_select_tag(project) selected = project.parent # retrieve the requested parent project @@ -375,4 +290,85 @@ module ProjectsHelper end end end + + # Time 2015-01-29 11:39:02 + # Author lizanle + # Description 计算projects + def get_project_activity projects,activities + @project_ids=activities.keys() + + days = Setting.activity_days_default.to_i + date_to ||= Date.today + 1 + date_from = date_to - days-1.years + + #issue_count + Issue.where(project_id: @project_ids).where("updated_on>?",date_from).each do |issue| +# activities[issue.project_id.to_s]+=1 + activities[issue.project_id]+=issue.journals.where("created_on>?",date_from).count + end + + #repository_count + Repository.where(project_id: @project_ids).each do |repository| +# activities[repository.project_id.to_s]+=1 + activities[repository.project_id]+=repository.changesets.where("committed_on>?",date_from).count + end + + + #news_count + News.where(project_id: @project_ids).where("created_on>?",date_from).each do |news| + activities[news.project_id]+=1 + end + + #document_count + Document.where(project_id: @project_ids).where("created_on>?",date_from).each do |document| + activities[document.project_id]+=1 + end + + #file_count + Attachment.where(container_id: @project_ids, container_type: Project).where("created_on>?",date_from).each do |attachment| + activities[attachment.container_id]+=1 + end + + #message_count + Board.where(project_id: @project_ids).each do |board| +# activities[board.project_id]+=1 + activities[board.project_id]+=board.messages.where("updated_on>?",date_from).count + end + + #time_entry_count + TimeEntry.where(project_id: @project_ids).where("updated_on>?",date_from).each do |timeentry| + activities[timeentry.project_id]+=1 + end + + #feedbackc_count + JournalsForMessage.where(jour_id: @project_ids, jour_type: Project).each do |jourformess| + activities[jourformess.jour_id]+=1 + end + + #activities!=0 + i=0; + projects.each do |project| + id=project.id + if activities[id]==0 + activities[id]=1 + end + end + + return activities + end + + def handle_project projects,activities + project_activity_count_array=activities.values() + + project_array=[] + i=0; + projects.each do |project| + project_array[i]=project + i=i+1 + end + + projects=desc_sort_course_by_avtivity(project_activity_count_array,project_array) + + return projects + end end diff --git a/app/helpers/system_log_helper.rb b/app/helpers/system_log_helper.rb new file mode 100644 index 000000000..2ca5baaed --- /dev/null +++ b/app/helpers/system_log_helper.rb @@ -0,0 +1,186 @@ +# Time 2015-01-26 17:30:16 +# Author lizanle +# Description 日志帮助类 +module SystemLogHelper + class SystemLog + class << self + # Time 2015-01-26 17:29:17 + # Author lizanle + # Description 分页(支持多关键字查询) + def logo_data(page, per, search, day) + logs = find_all_logs day + if logs.empty? #如果返回的是空數組,就說明日誌文件不存在 + return logs + end + # 根据search参数来决定是否需要查询 + keywords = search + if keywords && !keywords.strip.blank? + # 把keywords转化成正则表达式数组 + keywords = keywords.strip.split(/\s+/).collect! { |w| Regexp.new(w, 'i') } + # 一条记录应该匹配每个关键字 log =~ r 是对log记录进行判断是否符合r的正则表达式 + logs = logs.find_all do |log| + keywords.all? { |r| log =~ r && !(log =~ Regexp.new("SystemLogController#",'i')) } + end + #用Kaminari分页 + logs = Kaminari.paginate_array(logs).page(page).per(per).collect! { |log| parse(log) } + #将分页后的记录的搜索结果添加样式,样式中的\0是给给r占位置的。 + logs.collect! do |log| + keywords.each { |r| log.gsub!(r, '\0') } + log + end + + else + logs = Kaminari.paginate_array(logs).page(page).per(per).collect! { |log| parse(log) } + # 过滤掉日志中日志分析请求 + logs.collect! do |log| + log = "" if log =~ Regexp.new("SystemLogController",'i') + log + end + end + logs + end + + # Time 2015-01-26 17:28:57 + # Author lizanle + # Description 清除日誌 + def clear day + if File::exists?(logfile_path day) + File.open(logfile_path(day), 'w') do |f| + f.print '' + end + else + end + end + + # Time 2015-01-26 17:28:49 + # Author lizanle + # Description 讀取日誌 + private + def find_all_logs day + if File::exists?(logfile_path day) + File.open(logfile_path day) do |f| + #打开文件,并按照正则表达式切分,逆序,最新一个记录可以扔掉(因为最新的记录永远都是访问System_log) + f.read.split("Processing").reverse[1..-1] + end + else + [] + end + end + + # Time 2015-01-26 17:28:34 + # Author lizanle + # Description 日志文件的路径,一般在Rails.root/log下,根据环境配置 + # 依次记录到product.log development.log test.log中 + def logfile_path day + #将日期处理成2015-01-01的形式 + unless day.nil? + dayArr = day.split('-') + if dayArr[1].length == 1 + dayArr[1] = "0" + dayArr[1] + end + if dayArr[2].length == 1 + dayArr[2] = "0" + dayArr[2] + end + day = dayArr.join('-') + end + #如果不是當天,則需要加後綴 + if !day.nil? && !day.strip.blank? && day != Time.now.strftime("%Y-%m-%d") + File.join(Rails.root, "log", "#{Rails.env}.log.#{day.gsub('-', '')}") + else + File.join(Rails.root, "log", "#{Rails.env}.log") + end + end + + # Time 2015-01-26 17:28:22 + # Author lizanle + # Description 替換換行符 + def parse(log) + ERB::Util.html_escape(log.gsub(/\e\[[\d;m]+/, '')).gsub("\n", "
") + end + + # Time 2015-01-26 17:28:07 + # Author lizanle + # Description 定义响应正则表达式 2015-01-20 11:31:13 INFO -- Completed 200 OK in 125ms (Views: 81.0ms | ActiveRecord: 2.0ms) + def response_regex + 'Completed \d+ \w+ in (\d+)ms \(Views: (\d+\.\d+)?ms \| ActiveRecord: (\d+\.\d+)?ms\)' + end + + # Time 2015-01-26 17:27:51 + # Author lizanle + # Description 将一条记录中的地址主机等都分析出来 + def get_status(paragraph) + request_regex = 'Started GET \"(\/.*)\" for ([\d]+\.[\d]+\.[\d]+\.[\d]+) at [\d]*-([\d]*-[\d]* [\d]*:[\d]*:[\d]*)' + controller_regex = 'Processing by ([\w]+#[\w]+)' + page_time_regex = 'Views: \d+(\.\d+)?ms' + activeRecord_time_regex = 'ActiveRecord: \d+(\.\d+)?ms' + + #解析请求中的正则,主机,时间 + if paragraph.match(request_regex) != nil + request_url = paragraph.match(request_regex)[1] #正则表达式中的括号能够截取成数组 + request_host = paragraph.match(request_regex)[2] + request_at = paragraph.match(request_regex)[3] + end + + #解析控制器 + if paragraph.match(controller_regex) != nil + controller_name = paragraph.match(controller_regex)[1] + end + + #解析响应时间以及计算百分比 + if paragraph.match(response_regex) != nil + #print(paragraph.match(response_regex)) + total_time = paragraph.match(response_regex)[1] + page_time = paragraph.match(response_regex)[2] + activeRecord_time = paragraph.match(response_regex)[3] + page_time_percent = page_time.to_f/(total_time.to_f) + activeRecord_time_percent = activeRecord_time.to_f/(total_time.to_f) + else + end + #将解析结果当做一条记录数组返回 + request_status = [request_url, request_host, request_at, + controller_name, total_time, page_time, page_time_percent, activeRecord_time, activeRecord_time_percent] + request_status + end + + # Time 2015-01-26 16:41:51 + # Author lizanle + # Description 分析日志 + public + def analysis day + csv = Array.new + #如果文件不存在,则直接返回空数组 + if File::exists?(logfile_path day) + File.open(logfile_path(day), "r:utf-8") do |file| + paragraph = "" + begin_flag = false + # 对每一行进行判断 + file.each do |line| + # 以"Started GET "开头为一个paragraph + #print(line.match('[\d]*-([\d]*-[\d]* [\d]*:[\d]*:[\d]*) INFO -- Started GET ') == nil) + if (line.match('[\d]*-([\d]*-[\d]* [\d]*:[\d]*:[\d]*) \w+ -- Started GET ') != nil) + if !begin_flag + begin_flag = true + paragraph.concat(line) + else + # 另一个paragraph的开头 + if (paragraph.match(response_regex) != nil) + csv << get_status(paragraph) + end + begin_flag = true + paragraph = line + end + else + if begin_flag + paragraph.concat(line) + else + end + end + end + end + end + csv + end + end + end +end + diff --git a/app/helpers/welcome_helper.rb b/app/helpers/welcome_helper.rb index 27caa8306..d101fd36c 100644 --- a/app/helpers/welcome_helper.rb +++ b/app/helpers/welcome_helper.rb @@ -314,38 +314,38 @@ module WelcomeHelper str = ' '.html_safe case event.event_type when 'news' - str << content_tag("span", "发表了") << + str << content_tag("span", l(:field_user_active_published)) << content_tag("span", find_all_event_type(event)) << ': '.html_safe << link_to(strip_tags(event.event_description).gsub(/ /,''), event.event_url, {:title => event.event_description}) when 'issue', 'message' , 'bid' , 'wiki-page' , 'document' - str << content_tag("span", "发表了") << + str << content_tag("span", l(:field_user_active_published)) << content_tag("span", find_all_event_type(event)) << ': '.html_safe << link_to(event.event_title, event.event_url, {:title => event.event_title}) when 'reply' ,'Reply', 'Memo' - str << content_tag("span", "发表了") << - content_tag("span", find_all_event_type(event)) << + str << content_tag("span", l(:field_user_active_published)) << + content_tag("span", find_all_event_type(event)) << ': '.html_safe << link_to(strip_tags(event.event_description).gsub(/ /,''), event.event_url, {:title => event.event_description}) when 'attachment' - str << content_tag('span', '上传了') << + str << content_tag('span', l(:field_user_active_uploaded)) << content_tag('span', find_all_event_type(event)) << ': '.html_safe << link_to(event.event_title, event.event_url, {:title => event.event_title}) << link_to((' ['.html_safe+l(:label_downloads_list).to_s << ']'), project_files_path(event.container.project), :class => "attachments_list_color") else - str << content_tag("span", "更新了") << + str << content_tag("span", l(:field_user_active_updated)) << content_tag("span", find_all_event_type(event)) << ': '.html_safe << link_to(event.event_title, event.event_url, {:title => event.event_title}) end str rescue Exception => e - str << content_tag("span", '未知内容') + str << content_tag("span", l(:field_user_active_unknow)) end def show_event_reply event - str = "回复(" + str = l(:field_active_reply) case event.event_type when 'news' str << link_to( event.comments.count, news_path(event)) << ")" @@ -463,25 +463,25 @@ module WelcomeHelper def find_all_event_type event case event.event_type when 'news' - '新闻' + l(:field_user_active_news) when 'issue' - '缺陷' + l(:field_user_active_issue) when 'attachment' - '附件' + l(:field_user_active_attachment) when 'message' - '主题' + l(:field_user_active_message) when 'Reply','reply' - '回复' + l(:field_user_active_reply) when 'bid' - '作业' + l(:field_user_active_bid) when 'Memo' - '主题' + l(:field_user_active_memo) when 'document' - '文件' + l(:field_user_active_document) when 'changeset' - '版本库' + l(:field_user_active_changeset) when 'issue-note' - '问题说明' + l(:field_user_active_issue_note) else event.event_type end diff --git a/app/models/api_key.rb b/app/models/api_key.rb new file mode 100644 index 000000000..e71896bc0 --- /dev/null +++ b/app/models/api_key.rb @@ -0,0 +1,21 @@ +class ApiKey < ActiveRecord::Base + attr_accessible :access_token, :active, :expires_at, :user_id + before_create :generate_access_token + before_create :set_experation + + # validates_presence_of :user_id, :access_token + + def expired? + DateTime.now >= self.expires_at + end + + private + def generate_access_token + self.access_token = SecureRandom.hex + end + + def set_experation + self.expires_at = DateTime.now + 30 + end + +end diff --git a/app/models/bid.rb b/app/models/bid.rb index 88014477b..f423266b8 100644 --- a/app/models/bid.rb +++ b/app/models/bid.rb @@ -17,6 +17,7 @@ class Bid < ActiveRecord::Base HomeworkProject = 2 attr_accessible :author_id, :budget, :deadline, :name, :description, :homework_type, :password include Redmine::SafeAttributes + include ExpireHelper belongs_to :author, :class_name => 'User', :foreign_key => :author_id belongs_to :course @@ -32,7 +33,11 @@ class Bid < ActiveRecord::Base has_many :join_in_contests, :dependent => :destroy has_many :praise_tread, as: :praise_tread_object, dependent: :destroy # has_many :fork_homework, :class_name => 'Bid', :conditions => "#{Bid.table_name}.parent_id = #{id}" - + + + after_create :expire_activitie_cache + after_update :expire_activitie_cache + before_destroy :expire_activitie_cache acts_as_attachable @@ -149,4 +154,6 @@ class Bid < ActiveRecord::Base end end end + + end diff --git a/app/models/changeset.rb b/app/models/changeset.rb index e05a7d2da..101647824 100644 --- a/app/models/changeset.rb +++ b/app/models/changeset.rb @@ -16,6 +16,7 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. class Changeset < ActiveRecord::Base + include ExpireHelper belongs_to :repository belongs_to :user include UserScoreHelper @@ -64,8 +65,9 @@ class Changeset < ActiveRecord::Base includes(:repository => :project).where(Project.allowed_to_condition(args.shift || User.current, :view_changesets, *args)) } - after_create :scan_for_issues,:refresh_changests#:be_user_score # user_score - after_update :be_user_score + after_create :scan_for_issues,:refresh_changests,:expire_activitie_cache#:be_user_score # user_score + after_update :be_user_score,:expire_activitie_cache + before_destroy :expire_activitie_cache after_destroy :down_user_score before_create :before_create_cs diff --git a/app/models/contest_notification.rb b/app/models/contest_notification.rb index 1613f1378..0ccd0d5a7 100644 --- a/app/models/contest_notification.rb +++ b/app/models/contest_notification.rb @@ -1,4 +1,10 @@ class ContestNotification < ActiveRecord::Base + include ExpireHelper attr_accessible :content, :title validates :title, length: {maximum: 30} + after_create :expire_forum_cache + after_update :expire_forum_cache + before_destroy :expire_forum_cache + + end diff --git a/app/models/course.rb b/app/models/course.rb index d30e46e48..610f52f71 100644 --- a/app/models/course.rb +++ b/app/models/course.rb @@ -6,7 +6,7 @@ class Course < ActiveRecord::Base STATUS_CLOSED = 5 STATUS_ARCHIVED = 9 - attr_accessible :code, :extra, :name, :state, :tea_id, :time , :location, :state, :term, :password,:is_public,:description,:class_period, :open_student + attr_accessible :code, :extra, :name, :state, :tea_id, :time , :location, :state, :term, :password,:is_public,:description,:class_period, :open_student, :enterprise_name #belongs_to :project, :class_name => 'Course', :foreign_key => :extra, primary_key: :identifier belongs_to :teacher, :class_name => 'User', :foreign_key => :tea_id # 定义一个方法teacher,该方法通过tea_id来调用User表 belongs_to :school, :class_name => 'School', :foreign_key => :school_id #定义一个方法school,该方法通过school_id来调用School表 @@ -207,8 +207,8 @@ class Course < ActiveRecord::Base # 创建课程讨论区 def create_board_sync @board = self.boards.build - self.name=" #{l(:label_borad_course) }" - @board.name = self.name + #self.name=" #{l(:label_borad_course) }" + @board.name = " #{l(:label_borad_course) }"#self.name @board.description = self.name.to_s @board.project_id = -1 if @board.save diff --git a/app/models/course_group.rb b/app/models/course_group.rb index c7fc81df4..c6aa1299d 100644 --- a/app/models/course_group.rb +++ b/app/models/course_group.rb @@ -12,8 +12,7 @@ class CourseGroup < ActiveRecord::Base before_destroy :set_member_nil attr_accessible :name - validates :name, :presence => true, :length => {:maximum => 20} - validate :unique_name_and_course + validates :name, :presence => true, :length => {:maximum => 20}, :uniqueness => { :scope => :course_id} @@ -22,10 +21,5 @@ class CourseGroup < ActiveRecord::Base self.members.update_all("course_group_id = 0") end end - private - def unique_name_and_course - if CourseGroup.where("name=? and course_id=?", name, course_id).first - errors.add(:name, :groupname_repeat) - end - end + end diff --git a/app/models/document.rb b/app/models/document.rb index 7c2fa5a6d..48a0151eb 100644 --- a/app/models/document.rb +++ b/app/models/document.rb @@ -17,18 +17,22 @@ class Document < ActiveRecord::Base include Redmine::SafeAttributes + include ExpireHelper belongs_to :project belongs_to :user belongs_to :category, :class_name => "DocumentCategory", :foreign_key => "category_id" include UserScoreHelper after_save :be_user_score # user_score after_destroy :down_user_score - + after_create :expire_activitie_cache + after_update :expire_activitie_cache + before_destroy :expire_activitie_cache acts_as_attachable :delete_permission => :delete_documents acts_as_searchable :columns => ['title', "#{table_name}.description"], :include => :project acts_as_event :title => Proc.new {|o| "#{l(:label_document)}: #{o.title}"}, - :author => Proc.new {|o| o.attachments.reorder("#{Attachment.table_name}.created_on ASC").first.try(:author) }, + #:author => Proc.new {|o| o.attachments.reorder("#{Attachment.table_name}.created_on ASC").first.try(:author) }, + :author => Proc.new {|o| User.find(o.user_id)}, :url => Proc.new {|o| {:controller => 'documents', :action => 'show', :id => o.id}} acts_as_activity_provider :find_options => {:include => :project}, :is_public => 'documents.is_public' @@ -76,4 +80,6 @@ class Document < ActiveRecord::Base update_document(self.user,1) update_document(self.user,2,self.project) end + + end diff --git a/app/models/forum.rb b/app/models/forum.rb index eb8bb19d2..e47d18b02 100644 --- a/app/models/forum.rb +++ b/app/models/forum.rb @@ -1,8 +1,13 @@ class Forum < ActiveRecord::Base include Redmine::SafeAttributes + include ExpireHelper has_many :topics, :class_name => 'Memo', :conditions => "#{Memo.table_name}.parent_id IS NULL", :order => "#{Memo.table_name}.created_at DESC", :dependent => :destroy has_many :memos, :dependent => :destroy, conditions: "parent_id IS NULL" - belongs_to :creator, :class_name => "User", :foreign_key => 'creator_id' + belongs_to :creator, :class_name => "User", :foreign_key => 'creator_id' + + after_create :expire_forum_cache + after_update :expire_forum_cache + before_destroy :expire_forum_cache safe_attributes 'name', 'description', 'topic_count', @@ -45,5 +50,7 @@ class Forum < ActiveRecord::Base " memo_count = (SELECT COUNT(*) FROM #{Memo.table_name} WHERE forum_id=#{forum_id} AND parent_id IS NOT NULL)," + " last_memo_id = (SELECT MAX(id) FROM #{Memo.table_name} WHERE forum_id=#{forum_id})", ["id = ?", forum_id]) - end + end + + end diff --git a/app/models/issue.rb b/app/models/issue.rb index 4dc685b3b..a7b1a5943 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -19,7 +19,7 @@ class Issue < ActiveRecord::Base include Redmine::SafeAttributes include Redmine::Utils::DateCalculation include UserScoreHelper - + include ExpireHelper belongs_to :project belongs_to :tracker belongs_to :status, :class_name => 'IssueStatus', :foreign_key => 'status_id' @@ -80,6 +80,9 @@ class Issue < ActiveRecord::Base after_create :act_as_activity,:be_user_score_new_issue after_update :be_user_score after_destroy :down_user_score + after_create :expire_activitie_cache + after_update :expire_activitie_cache + before_destroy :expire_activitie_cache # after_create :be_user_score # end @@ -1553,4 +1556,5 @@ class Issue < ActiveRecord::Base end + end diff --git a/app/models/journals_for_message.rb b/app/models/journals_for_message.rb index 4819cd253..c71fbaf47 100644 --- a/app/models/journals_for_message.rb +++ b/app/models/journals_for_message.rb @@ -4,6 +4,7 @@ class JournalsForMessage < ActiveRecord::Base include Redmine::SafeAttributes include UserScoreHelper + include ExpireHelper safe_attributes "jour_type", # 留言所属类型 "jour_id", # 留言所属类型的id "notes", # 留言内容 @@ -54,7 +55,9 @@ class JournalsForMessage < ActiveRecord::Base has_many :acts, :class_name => 'Activity', :as => :act, :dependent => :destroy validates :notes, presence: true - after_create :act_as_activity #huang + after_create :act_as_activity ,:expire_activitie_cache#huang + after_update :expire_activitie_cache + before_destroy :expire_activitie_cache after_create :reset_counters! after_destroy :reset_counters! after_save :be_user_score @@ -162,4 +165,6 @@ class JournalsForMessage < ActiveRecord::Base end end end + + end diff --git a/app/models/memo.rb b/app/models/memo.rb index f9482911a..165f8e144 100644 --- a/app/models/memo.rb +++ b/app/models/memo.rb @@ -1,9 +1,13 @@ class Memo < ActiveRecord::Base include Redmine::SafeAttributes include UserScoreHelper + include ExpireHelper belongs_to :forum - belongs_to :author, :class_name => "User", :foreign_key => 'author_id' + belongs_to :author, :class_name => "User", :foreign_key => 'author_id' + after_create :expire_cache + after_update :expire_cache + before_destroy :expire_cache validates_presence_of :author_id, :forum_id, :subject,:content # 若是主题帖,则内容可以是空 #validates :content, presence: true, if: Proc.new{|o| !o.parent_id.nil? } @@ -170,5 +174,8 @@ class Memo < ActiveRecord::Base update_memo_number(User.current,1) update_replay_for_memo(User.current,1) end - + def expire_cache + expire_forum_cache + expire_activitie_cache + end end diff --git a/app/models/message.rb b/app/models/message.rb index 8af3265cc..9ce4d583a 100644 --- a/app/models/message.rb +++ b/app/models/message.rb @@ -18,7 +18,7 @@ class Message < ActiveRecord::Base include Redmine::SafeAttributes include UserScoreHelper - + include ExpireHelper belongs_to :board belongs_to :author, :class_name => 'User', :foreign_key => 'author_id' has_many :praise_tread, as: :praise_tread_object, dependent: :destroy @@ -59,8 +59,9 @@ class Message < ActiveRecord::Base validates_length_of :subject, :maximum => 255 validate :cannot_reply_to_locked_topic, :on => :create - after_create :add_author_as_watcher, :reset_counters! - after_update :update_messages_board + after_create :add_author_as_watcher, :reset_counters!,:expire_activitie_cache + after_update :update_messages_board,:expire_activitie_cache + before_destroy :expire_activitie_cache after_destroy :reset_counters!,:down_user_score # fq @@ -195,4 +196,6 @@ class Message < ActiveRecord::Base end end end + + end diff --git a/app/models/news.rb b/app/models/news.rb index 4d153e81f..9c37719f3 100644 --- a/app/models/news.rb +++ b/app/models/news.rb @@ -17,6 +17,7 @@ class News < ActiveRecord::Base include Redmine::SafeAttributes + include ExpireHelper belongs_to :project #added by nwb belongs_to :course @@ -47,6 +48,9 @@ class News < ActiveRecord::Base # fq after_create :act_as_activity # end + after_create :expire_activitie_cache + after_update :expire_activitie_cache + before_destroy :expire_activitie_cache scope :visible, lambda {|*args| includes(:project).where(Project.allowed_to_condition(args.shift || User.current, :view_news, *args)) @@ -91,4 +95,6 @@ class News < ActiveRecord::Base def act_as_activity self.acts << Activity.new(:user_id => self.author_id) end + + end diff --git a/app/models/project.rb b/app/models/project.rb index 14763347f..df403bb5c 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -17,6 +17,7 @@ class Project < ActiveRecord::Base include Redmine::SafeAttributes + include ExpireHelper ProjectType_project = 0 ProjectType_course = 1 @@ -113,9 +114,10 @@ class Project < ActiveRecord::Base validates_presence_of :name, :identifier validates_uniqueness_of :identifier validates_uniqueness_of :name - validates_associated :repository, :wiki - # validates_length_of :description, :maximum => 255 + validates_associated :wiki#, :repository + # validates_length_of :description, :maximum => 255 validates_length_of :name, :maximum => 255 + validates_length_of :enterprise_name, :maximum => 255 validates_length_of :homepage, :maximum => 255 validates_length_of :identifier, :in => 1..IDENTIFIER_MAX_LENGTH # donwcase letters, digits, dashes but not digits only @@ -125,10 +127,12 @@ class Project < ActiveRecord::Base #此代码功能:为原redmine中项目的树形结构按名称首字母排序,本系统项目非树形结构,且项目排序方式无按首字母排序,另该代码执行会使空数据库时创建项目时出异常故注释掉 #after_save :update_position_under_parent, :if => Proc.new {|project| project.name_changed?} + #ActiveModel::Dirty 这里有一个changed方法。对任何对象都可以用 after_save :update_inherited_members, :if => Proc.new {|project| project.inherit_members_changed?} # 创建project之后默认创建一个board,之后的board去掉了board的概念 - after_create :create_board_sync - before_destroy :delete_all_members + after_create :create_board_sync,:expire_project_cache + after_update :expire_project_cache + before_destroy :delete_all_members,:expire_project_cache def remove_references_before_destroy return if self.id.nil? Watcher.delete_all ['watchable_id = ?', id] @@ -760,7 +764,8 @@ class Project < ActiveRecord::Base 'issue_custom_field_ids', 'project_type', 'dts_test', - 'attachmenttype' + 'attachmenttype', + 'enterprise_name' @@ -1148,7 +1153,7 @@ class Project < ActiveRecord::Base logger.error "[Project Model] ===> Auto create board when Project saved, because #{@board.full_messages}" end end - - + + end diff --git a/app/services/courses_service.rb b/app/services/courses_service.rb new file mode 100644 index 000000000..41b6f2c68 --- /dev/null +++ b/app/services/courses_service.rb @@ -0,0 +1,354 @@ +class CoursesService + include ApplicationHelper + include CoursesHelper + include HomeworkAttachHelper + #TODO:尚未整合权限系统 + #参数school_id为0或不传时返回所有课程,否则返回对应学校的课程 + #参数per_page_count分页功能,每页显示的课程数 + #参数page分页功能,当前页码 + def course_list params + @school_id = params[:school_id] + per_page_option = params[:per_page_count] || 10 + page_no = params[:page] || 1 + if @school_id == "0" || @school_id.nil? + @courses_all = Course.active.visible. + joins("LEFT JOIN #{CourseStatus.table_name} ON #{Course.table_name}.id = #{CourseStatus.table_name}.course_id") + else + @courses_all = Course.active.visible. + joins("LEFT JOIN #{CourseStatus.table_name} ON #{Course.table_name}.id = #{CourseStatus.table_name}.course_id"). + where("#{Course.table_name}.school_id = ?", @school_id) + end + @course_count = @courses_all.count + @course_pages = Redmine::Pagination::Paginator.new @course_count, per_page_option,page_no + @courses = @courses_all.order("created_at desc") + @courses = @courses.offset(@course_pages.offset).limit(@course_pages.per_page) + course_list = [] + @courses.each do |course| + course_list << {:course => course,:img_url => url_to_avatar(course)} + end + course_list + end + + #搜索课程 + def search_course params + courses_all = Course.all_course + name = params[:name] + if name.blank? + raise 'sumbit empty' + end + @courses = courses_all.visible + if params[:name].present? + @courses_all = @courses.like(params[:name]) + else + @courses_all = @courses; + end + @courses_all + end + + #获取头像 + def get_img obj + url_to_avatar(obj) + end + + #课程老师或课程学生列表 + def course_teacher_or_student_list params,course,current_user + if course.is_a?(Course) + c = course + else + c = Course.find(course) + end + if current_user.nil? || !(current_user.admin? || c.is_public == 1 || (c.is_public == 0 && current_user.member_of_course?(c))) + raise '403' + end + @teachers= searchTeacherAndAssistant(c) + #@canShowCode = isCourseTeacher(User.current.id,course) && params[:role] != '1' + case params[:role] + when '1' + #@subPage_title = l :label_teacher_list + @members = searchTeacherAndAssistant(c) + when '2' + #@subPage_title = l :label_student_list + @members = searchStudent(c) + else + #@subPage_title = '' + @members = c.member_principals.includes(:roles, :principal).all.sort + end + users = [] + @members.each do |m| + img_url = url_to_avatar(m.user) + gender = m.user.user_extensions.gender.nil? ? 0 : m.user.user_extensions.gender + work_unit = get_user_work_unit m.user + location = get_user_location m.user + users << {:id => m.user.id, :img_url => img_url, :nickname => m.user.login, :gender => gender, :work_unit => work_unit, :mail => m.user.mail, :location => location, :brief_introduction => m.user.user_extensions.brief_introduction} + end + users + end + + #获取用户的工作单位 + def get_user_work_unit user + work_unit = "" + if user.user_extensions.identity == 0 || user.user_extensions.identity == 1 + work_unit = user.user_extensions.school.name unless user.user_extensions.school.nil? + elsif user.user_extensions.identity == 3 + work_unit = user.user_extensions.occupation + elsif user.user_extensions.identity == 2 + work_unit = user.firstname + end + work_unit + end + + #获取用户地区 + def get_user_location user + location = "" + location << (user.user_extensions.location || '') + location << (user.user_extensions.location_city || '') + location + end + + #课程通知列表 + def course_news_list params + if params[:course_id] && @course==nil + @course = Course.find(params[:course_id]) + end + scope = @course ? @course.news.course_visible : News.course_visible + news = [] + scope.each do |n| + news << {:title => n.title,:author_name => n.author.name,:author_id => n.author.id, :description => n.description,:created_on => format_time(n.created_on),:comments_count => n.comments_count} + end + news + end + + #查看新闻权限验证 + def show_course_news_authorize(current_user) + unless current_user.allowed_to?({:controller => 'news', :action => 'show'}, false) + raise '403' + end + end + + #显示课程通知(包括评论) 需验证权限 + def show_course_news params,current_user + @news = News.find(params[:id]) + @comments = @news.comments + @comments.reverse! if current_user.wants_comments_in_reverse_order? + {:news => @news,:comments => @comments} + #comments = [] + #@comments.each do |comment| + # comments << {:author_id => comment.author_id,:author_name => comment.author.name,:commont_content => comment.comments,:time => format_time(comment.created_on)} + #end + #{:title => @news.title,:author_name => @news.author.name,:author_id => @news.author.id, :description => @news.description,:created_on => format_time(@news.created_on), + # :comments_count => @news.comments_count,:comments => comments} + end + + + + #显示课程 + def show_course(params,currnet_user) + course = Course.find(params[:id]) + unless (course.is_public == 1 || currnet_user.member_of_course?(@course)|| currnet_user.admin?) + raise '403' + end + course + end + + #创建课程 + #current_user当前用户对象(不是id) + # params[:course][:name]:课程名称 + #params[:course][:password]:密码 + #params[:course][:description]:描述 + #params[:course][:is_public]:是否公开1公开,0私有 + #params[:course][:open_student]:是否公开学生列表1公开,0不公开,不公开时非课程成员无法看到学生列表 + #params[:course][:course_type]:暂时默认给1值。 + #params[:term]:学期(秋季学期或春季学期) + #params[:time]: 年份(例:2014) + #params[:setup_time]:暂不传(貌似已经没用了) + #params[:endup_time]: 暂不传(貌似已经没用了) + #params[:class_period]:学时总数 + def create_course(params,current_user) + if current_user.user_extensions.identity + @course = Course.new + @course.extra = 'course' + DateTime.parse(Time.now.to_s).strftime('%Y-%m-%d_%H-%M-%S').to_s + @course.send(:safe_attributes=, params[:course], current_user) + #@course.safe_attributes(current_user,params[:course]) + @course.tea_id = current_user.id + @course.term = params[:term] + @course.time = params[:time] + #@course.school_id = params[:occupation] + @course.school_id = current_user.user_extensions.school_id + @course.setup_time = params[:setup_time] + @course.endup_time = params[:endup_time] + @course.class_period = params[:class_period] + end + + @issue_custom_fields = IssueCustomField.sorted.all + @trackers = Tracker.sorted.all + + if @course.save + #unless User.current.admin? + r = Role.givable.find_by_id(Setting.new_project_user_role_id.to_i) || Role.givable.first + m = Member.new(:user => current_user, :roles => [r]) + m.project_id = -1 + course = CourseInfos.new(:user_id => current_user.id, :course_id => @course.id) + #user_grades = UserGrade.create(:user_id => User.current.id, :course_id => @course.id) + if params[:course][:is_public] == '1' + course_status = CourseStatus.create(:course_id => @course.id, :watchers_count => 0, :changesets_count => 0, :grade => 0, :course_type => @course_tag) + end + @course.members << m + @course.course_infos << course + end + @course + end + + #验证编辑课程的权限 + #当前 + def edit_course_authorize(current_user,course) + unless current_user.allowed_to?({:controller => 'courses', :action => 'update'}, course) + raise '403' + end + end + + #编辑课程 需验证权限 + # params[:course][:name]:课程名称 + #params[:course][:password]:密码 + #params[:course][:description]:描述 + #params[:course][:is_public]:是否公开1公开,0私有 + #params[:course][:open_student]:是否公开学生列表1公开,0不公开,不公开时非课程成员无法看到学生列表 + #params[:course][:course_type]:暂时默认给1值。 + #params[:term]:学期(秋季学期或春季学期) + #params[:time]: 年份(例:2014) + #params[:class_period]:学时总数 + def edit_course(params,course,current_user) + course.send(:safe_attributes=, params[:course], current_user) + #course.safe_attributes = params[:course] + course.time = params[:time] + course.term = params[:term] + course.class_period = params[:class_period] + if course.save + if params[:course][:is_public] == '0' + course_status = CourseStatus.find_by_course_id(course.id) + course_status.destroy if course_status + elsif params[:course][:is_public] == '1' + course_status = CourseStatus.find_by_course_id(course.id) + course_status.destroy if course_status + course_status = CourseStatus.create(:course_id => course.id, :grade => 0) + end + end + course + end + + #退出课程 + #object_id: 课程id + #user:当前用户 + #@state == 0 退出成功 + #@state == 1 不在课程中 + #@state == 2 您还未登录 + #@state 其他 未知错误,请稍后再试 + def exit_course params,user + if user.nil? + @state = 2 + return @state + end + @member = Member.where('course_id = ? and user_id = ?', params[:object_id], user.id) + if @member.nil? || @member.count == 0 + @state = 1 + return @state + end + @member.first.destroy + joined = StudentsForCourse.where('student_id = ? and course_id = ?', user.id, params[:object_id]) + joined.each do |join| + join.delete + @state = 0 + end + @state + end + + #加入课程 + #object_id:课程id + #course_password :加入课程的密码 + #@state == 0 加入成功 + #@state == 1 密码错误 + #@state == 2 课程已过期 请联系课程管理员重启课程。(在配置课程处) + #@state == 3 您已经加入了课程 + #@state == 4 您加入的课程不存在 + #@state == 5 您还未登录 + #@state 其他 未知错误,请稍后再试 + def join_course params,current_user + course = Course.find_by_id params[:object_id] + @state = 10 + if course + if course_endTime_timeout? course + @state = 2 + else + if current_user.member_of_course?(course) + @state = 3 + else + if params[:course_password] == course.password + members = [] + members << Member.new(:role_ids => [10], :user_id => current_user.id) + course.members << members + StudentsForCourse.create(:student_id => current_user.id, :course_id => params[:object_id]) + @state = 0 + else + @state = 1 + end + end + end + else + @state = 4 + end + {:state => @state,:course => course} + end + + #作业列表 + #已提交的作业数量获取 bid.homeworks.count + #学生提问数量获取 bid.commit.nil? ? 0 : bid.commit + def homework_list params,current_user + course = Course.find(params[:id]) + if course.is_public != 0 || current_user.member_of_course?(course) + bids = course.homeworks.order('deadline DESC') + bids = bids.like(params[:name]) if params[:name].present? + homeworks = [] + bids.each do |bid| + homeworks << show_homework_info(course,bid,current_user,is_course_teacher(current_user,course)) + end + homeworks + else + raise '403' + end + end + + private + def show_homework_info course,bid,current_user,is_course_teacher + author = bid.author.lastname + bid.author.firstname + many_times = course.homeworks.index(bid) + 1 + name = bid.name + homework_count = bid.homeworks.count #已提交的作业数量 + student_questions_count = bid.commit.nil? ? 0 : bid.commit + description = bid.description + #if is_course_teacher(User.current, course) && @bid.open_anonymous_evaluation == 1 && @bid.homeworks.count >= 2 + state = bid.comment_status + unless is_course_teacher + homework_for_anonymous_comments = get_student_batch_homework_list bid,current_user + end + #end + open_anonymous_evaluation = bid.open_anonymous_evaluation + {:course_name => course.name,:id => bid.id, :course_teacher => 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,:homework_for_anonymous_comments => homework_for_anonymous_comments} + end + + #显示作业列表的同时显示分配给当前学生匿评的作业 + def show_homework_info_with_batch course,bid + author = bid.author.lastname + bid.author.firstname + many_times = course.homeworks.index(bid) + 1 + name = bid.name + homework_count = bid.homeworks.count #已提交的作业数量 + student_questions_count = bid.commit.nil? ? 0 : bid.commit + description = bid.description + #if is_course_teacher(User.current, course) && @bid.open_anonymous_evaluation == 1 && @bid.homeworks.count >= 2 + state = bid.comment_status + #end + open_anonymous_evaluation = bid.open_anonymous_evaluation + {:course_name => course.name,:id => bid.id, :course_teacher => 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} + end + +end \ No newline at end of file diff --git a/app/services/homework_service.rb b/app/services/homework_service.rb new file mode 100644 index 000000000..a2c063e15 --- /dev/null +++ b/app/services/homework_service.rb @@ -0,0 +1,248 @@ +#coding=utf-8 +class HomeworkService + include CoursesHelper + include AttachmentsHelper + include ApplicationHelper + include WordsHelper + include ApiHelper + include HomeworkAttachHelper + + # 作业详情(老师才显示启动匿评,学生不显示 ) + # many_times 第几次(作业) + # state=0 启动匿评 + # state=1 关闭匿评 + # state=2 匿评结束 + def show_homework params + @bid = Bid.find(params[:id]) + course = @bid.courses.first + author = @bid.author.lastname + @bid.author.firstname + many_times = course.homeworks.index(@bid) + 1 + name = @bid.name + homework_count = @bid.homeworks.count #已提交的作业数量 + student_questions_count = @bid.commit.nil? ? 0 : @bid.commit + description = @bid.description + #if is_course_teacher(User.current, course) && @bid.open_anonymous_evaluation == 1 && @bid.homeworks.count >= 2 + state = @bid.comment_status + #end + open_anonymous_evaluation = @bid.open_anonymous_evaluation + {:course_name => course.name,:id => @bid.id, :course_teacher => 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} + end + + # 启动作业匿评前提示信息 + def alert_homework_anonymous_comment params + @bid = Bid.find params[:id] + @course = @bid.courses.first + if @bid.comment_status == 0 + @totle_size = searchStudent(@course).size + @cur_size = @bid.homeworks.size + elsif @bid.comment_status == 1 + @totle_size = 0 + @bid.homeworks.map { |homework| @totle_size += homework.homework_evaluations.count} + teachers = "(" + teacher_members = searchTeacherAndAssistant(@course) + teacher_members.each do |member| + if member == teacher_members.last + teachers += member.user_id.to_s + ")" + else + teachers += member.user_id.to_s + "," + end + end + @cur_size = 0 + @bid.homeworks.map { |homework| @cur_size += homework.rates(:quality).where("seems_rateable_rates.rater_id not in #{teachers}").count} + end + @percent = format("%.2f",(@cur_size.to_f / ( @totle_size == 0 ? 1 : @totle_size)) * 100) + [@bid,@totle_size,@cur_size,@percent] + end + + #启动匿评 + #statue 1:启动成功,2:启动失败,作业总数大于等于2份时才能启动匿评,3:已开启匿评,请务重复开启 + def start_anonymous_comment params,current_user + @bid = Bid.find(params[:id]) + @course = @bid.courses.first + unless is_course_teacher(current_user,@course) || current_user.admin? + @statue = 4 + raise '403' + end + if(@bid.comment_status == 0) + homeworks = @bid.homeworks + if(homeworks && homeworks.size >= 2) + homeworks.each_with_index do |homework, index| + user = homework.user + n = @bid.evaluation_num + n = n < homeworks.size ? n : homeworks.size - 1 + assigned_homeworks = get_assigned_homeworks(homeworks, n, index) + assigned_homeworks.each do |h| + @homework_evaluation = HomeworkEvaluation.new(user_id: user.id, homework_attach_id: h.id) + @homework_evaluation.save + end + end + @bid.update_column('comment_status', 1) + @statue = 1 + else + @statue = 2 + end + else + @statue = 3 + end + @statue + end + #关闭匿评 + def stop_anonymous_comment params,current_user + @bid = Bid.find(params[:id]) + @course = @bid.courses.first + unless is_course_teacher(current_user,@course) || current_user.admin? + raise '403' + end + @bid.update_column('comment_status', 2) + end + + # 匿评作品详情 + # attachs 该作品的所有附件 + # filename 文件名 + # filedesc 文件描述 + def anonymous_works_show(params,current_user) + @homework = HomeworkAttach.find(params[:id]) + @bid = @homework.bid + @course = @bid.courses.first + if current_user.admin? || current_user.member_of_course?(@course) + @stars_reates = @homework.rates(:quality) + @is_teacher = is_course_teacher current_user,@course + @has_evaluation = @stars_reates.where("rater_id = #{current_user.id} and is_teacher_score=#{@is_teacher ? 1 : 0}").first + @m_score = @has_evaluation.nil? ? 0 : @has_evaluation.stars + @teacher_stars = @stars_reates.where("is_teacher_score = 1") #老师评分列表 + @student_stars = @stars_reates.where("is_teacher_score = 0") #学生评分列表 + @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_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)) + else + raise '403' + 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}] + #name = @homework.name + #desc = @homework.description + #datetime = @homework.created_at + #files = [] + #unless @homework.attachments.empty? + # attachs = @homework.attachments + # attachs.each do |attach| + # filename = attach.filename + # filedesc = attach.description unless attach.description.blank? + # end + #end + + #{:name => name, :description => desc, :datetime => format_time(datetime)} + end + + #作品打分/留言 + def add_score_and_jour params + @is_teacher,@is_anonymous_comments,@m_score = params[:is_teacher]=="true",params[:is_anonymous_comments]=="true",params[:stars_value] + @cur_page,@cur_type = params[:cur_page] || 1,params[:cur_type] || 5 + @homework = HomeworkAttach.find(params[:homework_id]) + #保存评分 + @homework.rate(@m_score.to_i,User.current.id,:quality) if @m_score + #保存评论 + @is_comprehensive_evaluation = @is_teacher ? 1 : (@is_anonymous_comments ? 2 : 3) #判断当前评论是老师评论?匿评?留言 + if params[:new_form] && params[:new_form][:user_message] && params[:new_form][:user_message] != "" #有没有留言 + @homework.addjours User.current.id, params[:new_form][:user_message],0,@is_comprehensive_evaluation + end + end + + #作品留言列表 + def get_works_jours_list params + @bid = Bid.find params[:id] + @user = @bid.author + @jours = @bid.journals_for_messages.where('m_parent_id IS NULL').order('created_on DESC') + @jour = paginateHelper @jours,10 + @jour + end + + # 学生匿评留言列表 + def anonymous_jour_list params + #jours留言 is null条件用以兼容历史数据 + jours = @homework.journals_for_messages.where("is_comprehensive_evaluation = 3 or is_comprehensive_evaluation is null").order("created_on DESC") + jours.each do |jour| + user = jour.user + img_url = url_to_avatar(jour.user) + datetime = jour.created_on + content = jour.notes + end + {:user => 'user', :img_url => 'img_url', :datetime => 'datetime', :content => 'content'} + end + + # 匿评教师留言/回复列表 + # 图像img_url = url_to_avatar(user) + # massage_user 留言者 + # parent_jour被回复的留言 + def teacher_jour_list params + @homework = HomeworkAttach.find(params[:homework_id]) + @stars_reates = @homework.rates(:quality) + @teacher_stars = @stars_reates.where("rater_id in (#{teachers})") #老师评分列表 + @teacher_stars.each do |ts| + #留言参数 + jour = get_homework_review @homework,true,massage_user + massage_content = jour.notes unless jour.nil? + massage_user = ts.rater + massage_score = ts.stars + #回复参数 + anonymous_repy(jour) + end + end + + # 学生匿评列表 + def student_jour_list params + @homework = HomeworkAttach.find(params[:homework_id]) + @stars_reates = @homework.rates(:quality) + @student_stars = @stars_reates.where("rater_id not in (#{teachers})") #学生评分列表 + @student_stars.each do |ss| + #留言参数 + massage_user = ss.rater + jour = get_homework_review @homework,false,massage_user + massage_score = ss.stars + massage_content = jour.notes unless jour.nil? + #回复参数 + anonymous_repy(jour) + end + end + + def anonymous_repy jour + fetch_user_leaveWord_reply(jour).each do |fulr| + parent_jour = JournalsForMessage.where("id = #{fulr.m_reply_id}").first + reply_name = fulr.user.name + parent_name = parent_jour.user.name if parent_jour + reply_content = fulr.notes + reply_time = fulr.created_on + end + end + + #我的作品列表 + def my_homework_list params,current_user + @user = User.find(params[:user_id]) + if !current_user.admin? && !@user.active? + raise '404' + return + end + if current_user == @user || current_user.admin? + membership = @user.coursememberships.all + else + membership = @user.coursememberships.all(:conditions => Course.visible_condition(current_user)) + end + membership.sort! {|older, newer| newer.created_on <=> older.created_on } + course_list = [] + membership.each do |mp| + my_homeworks = [] + mp.course.homeworks.each do |bid| + hw = bid.homeworks.where("user_id = #{current_user.id}") + my_homeworks << hw[0] unless (hw.nil? || hw[0].nil?) + end + course_list << {:course => mp.course,:img_url => url_to_avatar(mp.course),:my_homework => my_homeworks} + end + course_list + end +end \ No newline at end of file diff --git a/app/services/users_service.rb b/app/services/users_service.rb new file mode 100644 index 000000000..897171b55 --- /dev/null +++ b/app/services/users_service.rb @@ -0,0 +1,169 @@ +class UsersService + include ApplicationHelper + include AccountHelper + include AvatarHelper + include CoursesHelper + include ApiHelper + #将用户注册的功能函数写这里 + #参数约定 + #成功返回注册后的User实例,失败直接抛异常 + + def register(params) + @user = User.new + @user.admin = false + @user.register + @user.login = params[:login] + @user.mail = params[:mail] + password = params[:password] + password_confirmation = params[:password_confirmation] + should_confirmation_password = params[:should_confirmation_password] + if !password.blank? && !password_confirmation.blank? && should_confirmation_password + @user.password, @user.password_confirmation = password, password_confirmation + elsif !password.blank? && !should_confirmation_password + @user.password = password + else + @user.password = "" + end + case Setting.self_registration + when '1' + @user = email_activation_register(@user) + when '3' + @user = automatically_register(@user) + else + @user = administrator_manually__register(@user) + end + if @user.id != nil + ue = @user.user_extensions ||= UserExtensions.new + ue.user_id = @user.id + ue.save + end + @user + #img_url = url_to_avatar(@user) + #gender = @user.user_extensions.gender.nil? ? 0 : @user.user_extensions.gender + #work_unit = get_user_work_unit @user + #location = get_user_location @user + #{:id => @user.id, :img_url => img_url, :nickname => @user.login, :gender => gender, :work_unit => work_unit, :mail => @user.mail, :location => location, :brief_introduction => @user.user_extensions.brief_introduction} + end + + #显示用户 + #id用户id + def show_user(params) + @user = User.find(params[:id]) + img_url = url_to_avatar(@user) + gender = @user.user_extensions.gender.nil? ? 0 : @user.user_extensions.gender + work_unit = get_user_work_unit @user + location = get_user_location @user + {:id => @user.id, :img_url => img_url, :nickname => @user.login, :gender => gender, :work_unit => work_unit, :mail => @user.mail, :location => location, :brief_introduction => @user.user_extensions.brief_introduction} + end + + #编辑用户 + #gender 1:female 0:male 其他:male + def edit_user params + @user = User.find(params[:id]) + fileio = params[:file] + + @se = @user.extensions + if @user.user_extensions.identity == 0 || @user.user_extensions.identity == 1 + @se.school_id = params[:occupation] + elsif @user.user_extensions.identity == 3 + @se.occupation = params[:occupation] + elsif @user.user_extensions.identity == 2 + @user.firstname = params[:occupation] + end + @se.brief_introduction = params[:brief_introduction] + @se.gender = params[:gender] + @se.location = params[:province] if params[:province] + @se.location_city = params[:city] if params[:city] + raise @se.errors.full_message unless @se.save + unless fileio.nil? + file = fileio[:tempfile] + diskfile=disk_filename(@user.class.to_s, @user.id) + @image_file = fileio[:name] + @urlfile='/' << File.join("images", "avatars", avatar_directory(@user.class.to_s), avatar_filename(@user.id, @image_file)) + + path = File.dirname(diskfile) + unless File.directory?(path) + FileUtils.mkdir_p(path) + end + File.rename(file.path, @urlfile) + begin + f = Magick::ImageList.new(diskfile) + # gif格式不再做大小处理 + if f.format != 'GIF' + width = 300.0 + proportion = (width/f[0].columns) + height = (f[0].rows*proportion) + f.resize_to_fill!(width, height) + f.write(diskfile) + end + + rescue Exception => e + logger.error "[Error] avatar : users_service#edit_user ===> #{e}" + end + end + #img_url = url_to_avatar(@user) + #gender = @user.user_extensions.gender.nil? ? 0 : @user.user_extensions.gender + #work_unit = get_user_work_unit @user + #location = get_user_location @user + #{:id => @user.id, :img_url => img_url, :nickname => @user.login, :gender => gender, :work_unit => work_unit, :mail => @user.mail, :location => location, :brief_introduction => @user.user_extensions.brief_introduction} + @user + end + + + + + + #关注列表 + def user_watcher params + @user = User.find(params[:id]) + User.watched_by(@user.id) + end + + #用户课程列表 + def user_courses_list params,current_user + @user = User.find(params[:id]) + if !current_user.admin? && !@user.active? + raise '404' + return + end + if current_user == @user || current_user.admin? + membership = @user.coursememberships.all + else + membership = @user.coursememberships.all(:conditions => Course.visible_condition(current_user)) + end + membership.sort! {|older, newer| newer.created_on <=> older.created_on } + course_list = [] + membership.each do |mp| + course_list << {:course => mp.course,:img_url => url_to_avatar(mp.course)} + end + course_list + end + + #修改密码 + def change_password params + @current_user = User.find(params[:current_user_id]) + if @current_user.check_password?(params[:password]) + @current_user.password, @current_user.password_confirmation = params[:new_password], params[:new_password_confirmation] + @current_user.save + #raise @current_user.errors.full_message + #return @current_user + + else + raise 'wrong password' + end + @current_user + end + + #搜索用户 + def search_user params + @status = params[:status] || 1 + has = { + "show_changesets" => true + } + scope = User.logged.status(@status) + @search_by = params[:search_by] ? params[:search_by] : "0" + scope = scope.like(params[:name],@search_by) if params[:name].present? + scope + end + +end diff --git a/app/services/watches_service.rb b/app/services/watches_service.rb new file mode 100644 index 000000000..2b9bed3cd --- /dev/null +++ b/app/services/watches_service.rb @@ -0,0 +1,57 @@ +class WatchesService + def watch params + @current_user = User.find(params[:current_user_id]) + @watchables = find_watchables params + if @watchables.nil? + raise '404' + end + set_watcher(@watchables, @current_user, true) + end + + def unwatch params + @current_user = User.find(params[:current_user_id]) + @watchables = find_watchables params + if @watchables.nil? + raise '404' + end + set_watcher(@watchables, @current_user, false) + end + + def find_watchables params + #根据参数获取关注对象的类型(user、project) + klass = Object.const_get(params[:object_type].camelcase) rescue nil + #判断获取的对象类型能否响应‘watched_by’方法 + if klass && klass.respond_to?('watched_by') + @watchables = klass.find_all_by_id(Array.wrap(params[:object_id])) + raise Unauthorized if @watchables.any? {|w| w.respond_to?(:visible?) && !w.visible?} + end + @watchables.present? ? @watchables : nil + end + + def set_watcher(watchables, user, watching) + watchables.each do |watchable| + watchable.set_watcher(user, watching) + # @user = watchable # added by william + if watching + # 修改 user和project的状态 + if watchable.instance_of?(User) + #写user_statuses表 + UserStatus.find_by_user_id(watchable.id).update_watchers_count(1) + elsif watchable.instance_of?(Project) + #写project_statuese表 + ProjectStatus.find_by_project_id(watchable.id).update_watchers_count(1) + end + else + # 修改 user和project的状态 + if watchable.instance_of?(User) + #写user_statuses表 + UserStatus.find_by_user_id(watchable.id).update_watchers_count(-1) + elsif watchable.instance_of?(Project) + #写project_statuese表 :project_status + ProjectStatus.find_by_project_id(watchable.id).update_watchers_count(-1) + end + end + end + watchables + end +end \ No newline at end of file diff --git a/app/views/applied_project/applied_join_project.js.erb b/app/views/applied_project/applied_join_project.js.erb new file mode 100644 index 000000000..3f4f6aff7 --- /dev/null +++ b/app/views/applied_project/applied_join_project.js.erb @@ -0,0 +1,11 @@ +<% if @status == 0%> + alert("您申请的项目不存在"); +<% elsif @status == 1%> + alert("请勿重复申请加入该项目"); +<% elsif @status == 2%> + alert("申请成功"); +<% elsif @status == 3%> + alert("您已加入该项目"); +<%else%> + alert("申请失败"); +<%end%> \ No newline at end of file diff --git a/app/views/contests/new_contest.html.erb b/app/views/contests/new_contest.html.erb index 71c12fad4..0e1b83602 100644 --- a/app/views/contests/new_contest.html.erb +++ b/app/views/contests/new_contest.html.erb @@ -6,7 +6,7 @@ method: :post do |f| %>
<%= render :partial => 'form_contest', :locals => { :f => f } %> - <%= submit_tag l(:button_create) %> + <%= submit_tag l(:button_create), :style=> "margin-left: 100px;margin-top: 10px;" %> <%= javascript_tag "$('#bid_name').focus();" %> <% end %>
diff --git a/app/views/courses/_course_form.html.erb b/app/views/courses/_course_form.html.erb index d54741295..85ca24c1b 100644 --- a/app/views/courses/_course_form.html.erb +++ b/app/views/courses/_course_form.html.erb @@ -42,7 +42,7 @@ <%= l(:label_class_period) %> *   - + <%= text_field_tag :class_period, @course.class_period, :placeholder => "#{l(:lable_input_class)}", :maxlength => 5 %>   diff --git a/app/views/courses/_set_course_time.html.erb b/app/views/courses/_set_course_time.html.erb index f1eec891f..0c28b90a7 100644 --- a/app/views/courses/_set_course_time.html.erb +++ b/app/views/courses/_set_course_time.html.erb @@ -5,9 +5,9 @@ <% if display #如果课程已结束%> <% linkPath = course_endTime_timeout?(course) ? restartcourse_course_path(course) : finishcourse_course_path(course, format: :js) %> - <% desc = course_endTime_timeout?(course) ? '重启' : '关闭' %> + <% desc = course_endTime_timeout?(course) ? l(:label_course_reload) : l(:label_course_closed) %> - <%= link_to "#{desc}", linkPath, :remote => true, :method => :post, :id => id, :confirm => ("确定要#{desc}课程?") %> + <%= link_to "#{desc}", linkPath, :remote => true, :method => :post, :id => id, :confirm => l(:label_course_closed_tips, :desc => desc) %> <% else %> <% end %> diff --git a/app/views/courses/show.html.erb b/app/views/courses/show.html.erb index 9f0084019..9c91908d2 100644 --- a/app/views/courses/show.html.erb +++ b/app/views/courses/show.html.erb @@ -90,7 +90,7 @@ - + <%= l :label_create_time %>: <%= format_time(@course.created_at) %> diff --git a/app/views/files/_upload_show.html.erb b/app/views/files/_upload_show.html.erb index 65a662f10..91d050d93 100644 --- a/app/views/files/_upload_show.html.erb +++ b/app/views/files/_upload_show.html.erb @@ -5,7 +5,7 @@ <%= error_messages_for 'attachment' %> <%= form_tag(course_files_path(course), :multipart => true,:remote => true,:method => :post,:name=>"upload_form") do %> - + <%= render :partial => 'attachement_list',:locals => {:course => course} %>
<%= l(:button_confirm)%> diff --git a/app/views/layouts/_base_feedback.html.erb b/app/views/layouts/_base_feedback.html.erb index bf4b12daf..2039735bc 100644 --- a/app/views/layouts/_base_feedback.html.erb +++ b/app/views/layouts/_base_feedback.html.erb @@ -63,7 +63,7 @@ a:hover.opnionButton{ text-decoration:underline;} (function($){ $.fn.fix = function(options){ var defaults = { - float : 'left', + float : 'right', minStatue : false, skin : 'blue', durationTime : 1000 @@ -81,7 +81,7 @@ a:hover.opnionButton{ text-decoration:underline;} var defaultTop = thisBox.offset().top; //????????top thisBox.css(options.float, 0); - if(options.minStatue){ + if(options.minStatue == "true"){ $(".show_btn").css("float", options.float); sideContent.css('width', 0); show_btn.css('width', 25); @@ -106,15 +106,18 @@ a:hover.opnionButton{ text-decoration:underline;} closeBtn.bind("click",function(){ sideContent.animate({width: '0px'},"fast"); show_btn.stop(true, true).delay(300).animate({ width: '25px'},"fast"); + cookiesave('minStatue','true','','',''); }); //show??? - show_btn.click(function() { + show_btn.bind("click",function() { $(this).animate({width: '0px'},"fast"); sideContent.stop(true, true).delay(200).animate({ width: '154px'},"fast"); + cookiesave('minStatue','false','','',''); }); - }); //end this.each + + }); //end this.each }; })(jQuery); @@ -130,6 +133,38 @@ function f_submit() { $("#new_memo").submit(); } + +function cookiesave(n, v, mins, dn, path) +{ + if(n) + { + + if(!mins) mins = 365 * 24 * 60; + if(!path) path = "/"; + var date = new Date(); + + date.setTime(date.getTime() + (mins * 60 * 1000)); + + var expires = "; expires=" + date.toGMTString(); + + if(dn) dn = "domain=" + dn + "; "; + document.cookie = n + "=" + v + expires + "; " + dn + "path=" + path; + + } +} +function cookieget(n) +{ + var name = n + "="; + var ca = document.cookie.split(';'); + for(var i=0;i @@ -138,9 +173,9 @@ function f_submit() 意见反馈 - + -
+
@@ -171,7 +206,7 @@ function f_submit() $(function() { $("#scrollsidebar").fix({ float : 'right', //default.left or right - //minStatue : true, + minStatue : cookieget('minStatue'), skin : 'green', //default.gray or blue durationTime : 600 }); diff --git a/app/views/layouts/_base_footer.html.erb b/app/views/layouts/_base_footer.html.erb index 4050de3b7..4716ed25a 100644 --- a/app/views/layouts/_base_footer.html.erb +++ b/app/views/layouts/_base_footer.html.erb @@ -9,12 +9,12 @@

<% if @organizer.nil? %>

- 主办单位 - 国防科学技术大学并行与分布处理国家重点实验室 - 计算机科学与技术系 - 版权©2007~2014 - 联系我们 - 湘ICP备09019772 + <%= l(:label_hosted_organization) %> + <%= l(:label_hosted_by) %> + <%= l(:label_sponsor) %> + <%= l(:label_rights_reserved)%> + <%= l(:label_contact_us) %> + <%= l(:label_license) %>

<% else %> <%= @organizer.description.html_safe %> @@ -22,11 +22,11 @@