Commit 2e37142b by liangyuzhe

代码重构

parent d2b2b524
...@@ -37,3 +37,5 @@ ...@@ -37,3 +37,5 @@
# Ignore master key for decrypting credentials and more. # Ignore master key for decrypting credentials and more.
/config/master.key /config/master.key
/config/database.yml
ruby-2.6.0 ruby-2.6.5
\ No newline at end of file \ No newline at end of file
...@@ -2,12 +2,13 @@ source 'https://gems.ruby-china.com' ...@@ -2,12 +2,13 @@ source 'https://gems.ruby-china.com'
git_source(:github) { |repo| "https://github.com/#{repo}.git" } git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby '2.6.0' ruby '2.6.5'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 5.2.2', '>= 5.2.2.1' gem 'rails', '~> 6.0.1'
# Use sqlite3 as the database for Active Record # Use sqlite3 as the database for Active Record
gem 'sqlite3' # gem 'sqlite3'
gem 'mysql2', '~> 0.5.3'
# Use Puma as the app server # Use Puma as the app server
gem 'puma', '~> 3.11' gem 'puma', '~> 3.11'
# Use SCSS for stylesheets # Use SCSS for stylesheets
......
GEM GEM
remote: https://gems.ruby-china.com/ remote: https://gems.ruby-china.com/
specs: specs:
actioncable (5.2.3) actioncable (6.0.1)
actionpack (= 5.2.3) actionpack (= 6.0.1)
nio4r (~> 2.0) nio4r (~> 2.0)
websocket-driver (>= 0.6.1) websocket-driver (>= 0.6.1)
actionmailer (5.2.3) actionmailbox (6.0.1)
actionpack (= 5.2.3) actionpack (= 6.0.1)
actionview (= 5.2.3) activejob (= 6.0.1)
activejob (= 5.2.3) activerecord (= 6.0.1)
activestorage (= 6.0.1)
activesupport (= 6.0.1)
mail (>= 2.7.1)
actionmailer (6.0.1)
actionpack (= 6.0.1)
actionview (= 6.0.1)
activejob (= 6.0.1)
mail (~> 2.5, >= 2.5.4) mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 2.0) rails-dom-testing (~> 2.0)
actionpack (5.2.3) actionpack (6.0.1)
actionview (= 5.2.3) actionview (= 6.0.1)
activesupport (= 5.2.3) activesupport (= 6.0.1)
rack (~> 2.0) rack (~> 2.0)
rack-test (>= 0.6.3) rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0) rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.2) rails-html-sanitizer (~> 1.0, >= 1.2.0)
actionview (5.2.3) actiontext (6.0.1)
activesupport (= 5.2.3) actionpack (= 6.0.1)
activerecord (= 6.0.1)
activestorage (= 6.0.1)
activesupport (= 6.0.1)
nokogiri (>= 1.8.5)
actionview (6.0.1)
activesupport (= 6.0.1)
builder (~> 3.1) builder (~> 3.1)
erubi (~> 1.4) erubi (~> 1.4)
rails-dom-testing (~> 2.0) rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.3) rails-html-sanitizer (~> 1.1, >= 1.2.0)
activejob (5.2.3) activejob (6.0.1)
activesupport (= 5.2.3) activesupport (= 6.0.1)
globalid (>= 0.3.6) globalid (>= 0.3.6)
activemodel (5.2.3) activemodel (6.0.1)
activesupport (= 5.2.3) activesupport (= 6.0.1)
activerecord (5.2.3) activerecord (6.0.1)
activemodel (= 5.2.3) activemodel (= 6.0.1)
activesupport (= 5.2.3) activesupport (= 6.0.1)
arel (>= 9.0) activestorage (6.0.1)
activestorage (5.2.3) actionpack (= 6.0.1)
actionpack (= 5.2.3) activejob (= 6.0.1)
activerecord (= 5.2.3) activerecord (= 6.0.1)
marcel (~> 0.3.1) marcel (~> 0.3.1)
activesupport (5.2.3) activesupport (6.0.1)
concurrent-ruby (~> 1.0, >= 1.0.2) concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2) i18n (>= 0.7, < 2)
minitest (~> 5.1) minitest (~> 5.1)
tzinfo (~> 1.1) tzinfo (~> 1.1)
addressable (2.6.0) zeitwerk (~> 2.2)
public_suffix (>= 2.0.2, < 4.0) addressable (2.7.0)
airbrussh (1.3.1) public_suffix (>= 2.0.2, < 5.0)
airbrussh (1.4.0)
sshkit (>= 1.6.1, != 1.7.0) sshkit (>= 1.6.1, != 1.7.0)
archive-zip (0.12.0) archive-zip (0.12.0)
io-like (~> 0.3.0) io-like (~> 0.3.0)
arel (9.0.0) bindex (0.8.1)
bindex (0.7.0) bootsnap (1.4.5)
bootsnap (1.4.4)
msgpack (~> 1.0) msgpack (~> 1.0)
builder (3.2.3) builder (3.2.3)
byebug (11.0.1) byebug (11.0.1)
capistrano (3.11.0) capistrano (3.11.2)
airbrussh (>= 1.0.0) airbrussh (>= 1.0.0)
i18n i18n
rake (>= 10.0.0) rake (>= 10.0.0)
sshkit (>= 1.9.0) sshkit (>= 1.9.0)
capistrano-bundler (1.5.0) capistrano-bundler (1.6.0)
capistrano (~> 3.1) capistrano (~> 3.1)
capistrano-rails (1.4.0) capistrano-rails (1.4.0)
capistrano (~> 3.1) capistrano (~> 3.1)
...@@ -67,23 +80,22 @@ GEM ...@@ -67,23 +80,22 @@ GEM
capistrano-rvm (0.1.2) capistrano-rvm (0.1.2)
capistrano (~> 3.0) capistrano (~> 3.0)
sshkit (~> 1.2) sshkit (~> 1.2)
capistrano-sidekiq (1.0.2) capistrano-sidekiq (1.0.3)
capistrano (>= 3.9.0) capistrano (>= 3.9.0)
sidekiq (>= 3.4) sidekiq (>= 3.4, < 6.0)
capistrano3-puma (3.1.1) capistrano3-puma (3.1.1)
capistrano (~> 3.7) capistrano (~> 3.7)
capistrano-bundler capistrano-bundler
puma (~> 3.4) puma (~> 3.4)
capybara (3.20.2) capybara (3.29.0)
addressable addressable
mini_mime (>= 0.1.3) mini_mime (>= 0.1.3)
nokogiri (~> 1.8) nokogiri (~> 1.8)
rack (>= 1.6.0) rack (>= 1.6.0)
rack-test (>= 0.6.3) rack-test (>= 0.6.3)
regexp_parser (~> 1.2) regexp_parser (~> 1.5)
xpath (~> 3.2) xpath (~> 3.2)
childprocess (1.0.1) childprocess (3.0.0)
rake (< 13.0)
chromedriver-helper (2.1.1) chromedriver-helper (2.1.1)
archive-zip (~> 0.10) archive-zip (~> 0.10)
nokogiri (~> 1.8) nokogiri (~> 1.8)
...@@ -96,17 +108,17 @@ GEM ...@@ -96,17 +108,17 @@ GEM
coffee-script-source (1.12.2) coffee-script-source (1.12.2)
concurrent-ruby (1.1.5) concurrent-ruby (1.1.5)
connection_pool (2.2.2) connection_pool (2.2.2)
crass (1.0.4) crass (1.0.5)
erubi (1.8.0) erubi (1.9.0)
execjs (2.7.0) execjs (2.7.0)
ffi (1.11.1) ffi (1.11.3)
globalid (0.4.2) globalid (0.4.2)
activesupport (>= 4.2.0) activesupport (>= 4.2.0)
god (0.13.7) god (0.13.7)
httparty (0.13.7) httparty (0.13.7)
json (~> 1.8) json (~> 1.8)
multi_xml (>= 0.5.2) multi_xml (>= 0.5.2)
i18n (1.6.0) i18n (1.7.0)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
igetui-ruby (1.2.2) igetui-ruby (1.2.2)
json (~> 1.8, >= 1.8.1) json (~> 1.8, >= 1.8.1)
...@@ -119,7 +131,7 @@ GEM ...@@ -119,7 +131,7 @@ GEM
rb-fsevent (~> 0.9, >= 0.9.4) rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7) rb-inotify (~> 0.9, >= 0.9.7)
ruby_dep (~> 1.2) ruby_dep (~> 1.2)
loofah (2.2.3) loofah (2.4.0)
crass (~> 1.0.2) crass (~> 1.0.2)
nokogiri (>= 1.5.9) nokogiri (>= 1.5.9)
mail (2.7.1) mail (2.7.1)
...@@ -128,62 +140,65 @@ GEM ...@@ -128,62 +140,65 @@ GEM
mimemagic (~> 0.3.2) mimemagic (~> 0.3.2)
method_source (0.9.2) method_source (0.9.2)
mimemagic (0.3.3) mimemagic (0.3.3)
mini_mime (1.0.1) mini_mime (1.0.2)
mini_portile2 (2.4.0) mini_portile2 (2.4.0)
minitest (5.11.3) minitest (5.13.0)
msgpack (1.2.10) msgpack (1.3.1)
multi_xml (0.6.0) multi_xml (0.6.0)
net-scp (1.2.1) mysql2 (0.5.3)
net-ssh (>= 2.6.5) net-scp (2.0.0)
net-ssh (5.1.0) net-ssh (>= 2.6.5, < 6.0.0)
nio4r (2.3.1) net-ssh (5.2.0)
nokogiri (1.10.3) nio4r (2.5.2)
nokogiri (1.10.7)
mini_portile2 (~> 2.4.0) mini_portile2 (~> 2.4.0)
public_suffix (3.0.3) public_suffix (4.0.1)
puma (3.12.1) puma (3.12.2)
rack (2.0.7) rack (2.0.7)
rack-protection (2.0.5) rack-protection (2.0.7)
rack rack
rack-test (1.1.0) rack-test (1.1.0)
rack (>= 1.0, < 3) rack (>= 1.0, < 3)
rails (5.2.3) rails (6.0.1)
actioncable (= 5.2.3) actioncable (= 6.0.1)
actionmailer (= 5.2.3) actionmailbox (= 6.0.1)
actionpack (= 5.2.3) actionmailer (= 6.0.1)
actionview (= 5.2.3) actionpack (= 6.0.1)
activejob (= 5.2.3) actiontext (= 6.0.1)
activemodel (= 5.2.3) actionview (= 6.0.1)
activerecord (= 5.2.3) activejob (= 6.0.1)
activestorage (= 5.2.3) activemodel (= 6.0.1)
activesupport (= 5.2.3) activerecord (= 6.0.1)
activestorage (= 6.0.1)
activesupport (= 6.0.1)
bundler (>= 1.3.0) bundler (>= 1.3.0)
railties (= 5.2.3) railties (= 6.0.1)
sprockets-rails (>= 2.0.0) sprockets-rails (>= 2.0.0)
rails-dom-testing (2.0.3) rails-dom-testing (2.0.3)
activesupport (>= 4.2.0) activesupport (>= 4.2.0)
nokogiri (>= 1.6) nokogiri (>= 1.6)
rails-html-sanitizer (1.0.4) rails-html-sanitizer (1.3.0)
loofah (~> 2.2, >= 2.2.2) loofah (~> 2.3)
rails_param (0.10.2) rails_param (0.10.2)
railties (5.2.3) railties (6.0.1)
actionpack (= 5.2.3) actionpack (= 6.0.1)
activesupport (= 5.2.3) activesupport (= 6.0.1)
method_source method_source
rake (>= 0.8.7) rake (>= 0.8.7)
thor (>= 0.19.0, < 2.0) thor (>= 0.20.3, < 2.0)
rake (12.3.2) rake (13.0.1)
rb-fsevent (0.10.3) rb-fsevent (0.10.3)
rb-inotify (0.10.0) rb-inotify (0.10.0)
ffi (~> 1.0) ffi (~> 1.0)
redis (3.3.5) redis (3.3.5)
redis-actionpack (5.0.2) redis-actionpack (5.1.0)
actionpack (>= 4.0, < 6) actionpack (>= 4.0, < 7)
redis-rack (>= 1, < 3) redis-rack (>= 1, < 3)
redis-store (>= 1.1.0, < 2) redis-store (>= 1.1.0, < 2)
redis-activesupport (5.0.7) redis-activesupport (5.2.0)
activesupport (>= 3, < 6) activesupport (>= 3, < 7)
redis-store (>= 1.3, < 2) redis-store (>= 1.3, < 2)
redis-rack (2.0.5) redis-rack (2.0.6)
rack (>= 1.5, < 3) rack (>= 1.5, < 3)
redis-store (>= 1.2, < 2) redis-store (>= 1.2, < 2)
redis-rails (5.0.2) redis-rails (5.0.2)
...@@ -192,32 +207,31 @@ GEM ...@@ -192,32 +207,31 @@ GEM
redis-store (>= 1.2, < 2) redis-store (>= 1.2, < 2)
redis-store (1.6.0) redis-store (1.6.0)
redis (>= 2.2, < 5) redis (>= 2.2, < 5)
regexp_parser (1.5.0) regexp_parser (1.6.0)
ruby-protocol-buffers (1.6.1) ruby-protocol-buffers (1.6.1)
ruby_dep (1.5.0) ruby_dep (1.5.0)
rubyzip (1.2.2) rubyzip (2.0.0)
sass (3.7.4) sass (3.7.4)
sass-listen (~> 4.0.0) sass-listen (~> 4.0.0)
sass-listen (4.0.0) sass-listen (4.0.0)
rb-fsevent (~> 0.9, >= 0.9.4) rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7) rb-inotify (~> 0.9, >= 0.9.7)
sass-rails (5.0.7) sass-rails (5.1.0)
railties (>= 4.0.0, < 6) railties (>= 5.2.0)
sass (~> 3.1) sass (~> 3.1)
sprockets (>= 2.8, < 4.0) sprockets (>= 2.8, < 4.0)
sprockets-rails (>= 2.0, < 4.0) sprockets-rails (>= 2.0, < 4.0)
tilt (>= 1.1, < 3) tilt (>= 1.1, < 3)
selenium-webdriver (3.142.2) selenium-webdriver (3.142.6)
childprocess (>= 0.5, < 2.0) childprocess (>= 0.5, < 4.0)
rubyzip (~> 1.2, >= 1.2.2) rubyzip (>= 1.2.2)
settingslogic (2.0.9) settingslogic (2.0.9)
sidekiq (4.2.10) sidekiq (4.2.10)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
connection_pool (~> 2.2, >= 2.2.0) connection_pool (~> 2.2, >= 2.2.0)
rack-protection (>= 1.5.0) rack-protection (>= 1.5.0)
redis (~> 3.2, >= 3.2.1) redis (~> 3.2, >= 3.2.1)
spring (2.0.2) spring (2.1.0)
activesupport (>= 4.2)
spring-watcher-listen (2.0.1) spring-watcher-listen (2.0.1)
listen (>= 2.7, < 4.0) listen (>= 2.7, < 4.0)
spring (>= 1.2, < 3.0) spring (>= 1.2, < 3.0)
...@@ -228,30 +242,30 @@ GEM ...@@ -228,30 +242,30 @@ GEM
actionpack (>= 4.0) actionpack (>= 4.0)
activesupport (>= 4.0) activesupport (>= 4.0)
sprockets (>= 3.0.0) sprockets (>= 3.0.0)
sqlite3 (1.4.1) sshkit (1.20.0)
sshkit (1.18.0)
net-scp (>= 1.1.2) net-scp (>= 1.1.2)
net-ssh (>= 2.8.0) net-ssh (>= 2.8.0)
thor (0.20.3) thor (0.20.3)
thread_safe (0.3.6) thread_safe (0.3.6)
tilt (2.0.9) tilt (2.0.10)
turbolinks (5.2.0) turbolinks (5.2.1)
turbolinks-source (~> 5.2) turbolinks-source (~> 5.2)
turbolinks-source (5.2.0) turbolinks-source (5.2.0)
tzinfo (1.2.5) tzinfo (1.2.5)
thread_safe (~> 0.1) thread_safe (~> 0.1)
uglifier (4.1.20) uglifier (4.2.0)
execjs (>= 0.3.0, < 3) execjs (>= 0.3.0, < 3)
web-console (3.7.0) web-console (4.0.1)
actionview (>= 5.0) actionview (>= 6.0.0)
activemodel (>= 5.0) activemodel (>= 6.0.0)
bindex (>= 0.4.0) bindex (>= 0.4.0)
railties (>= 5.0) railties (>= 6.0.0)
websocket-driver (0.7.0) websocket-driver (0.7.1)
websocket-extensions (>= 0.1.0) websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.3) websocket-extensions (0.1.4)
xpath (3.2.0) xpath (3.2.0)
nokogiri (~> 1.8) nokogiri (~> 1.8)
zeitwerk (2.2.2)
PLATFORMS PLATFORMS
ruby ruby
...@@ -272,8 +286,9 @@ DEPENDENCIES ...@@ -272,8 +286,9 @@ DEPENDENCIES
igetui-ruby igetui-ruby
jbuilder (~> 2.5) jbuilder (~> 2.5)
listen (>= 3.0.5, < 3.2) listen (>= 3.0.5, < 3.2)
mysql2 (~> 0.5.3)
puma (~> 3.11) puma (~> 3.11)
rails (~> 5.2.2, >= 5.2.2.1) rails (~> 6.0.1)
rails_param (~> 0.10.2) rails_param (~> 0.10.2)
redis-rails (~> 5.0, >= 5.0.2) redis-rails (~> 5.0, >= 5.0.2)
sass-rails (~> 5.0) sass-rails (~> 5.0)
...@@ -282,14 +297,13 @@ DEPENDENCIES ...@@ -282,14 +297,13 @@ DEPENDENCIES
sidekiq (~> 4.1, >= 4.1.2) sidekiq (~> 4.1, >= 4.1.2)
spring spring
spring-watcher-listen (~> 2.0.0) spring-watcher-listen (~> 2.0.0)
sqlite3
turbolinks (~> 5) turbolinks (~> 5)
tzinfo-data tzinfo-data
uglifier (>= 1.3.0) uglifier (>= 1.3.0)
web-console (>= 3.3.0) web-console (>= 3.3.0)
RUBY VERSION RUBY VERSION
ruby 2.6.0p0 ruby 2.6.5p114
BUNDLED WITH BUNDLED WITH
1.17.2 1.17.3
GEM
remote: https://gems.ruby-china.com/
specs:
actioncable (5.2.3)
actionpack (= 5.2.3)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
actionmailer (5.2.3)
actionpack (= 5.2.3)
actionview (= 5.2.3)
activejob (= 5.2.3)
mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 2.0)
actionpack (5.2.3)
actionview (= 5.2.3)
activesupport (= 5.2.3)
rack (~> 2.0)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.2)
actionview (5.2.3)
activesupport (= 5.2.3)
builder (~> 3.1)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.3)
activejob (5.2.3)
activesupport (= 5.2.3)
globalid (>= 0.3.6)
activemodel (5.2.3)
activesupport (= 5.2.3)
activerecord (5.2.3)
activemodel (= 5.2.3)
activesupport (= 5.2.3)
arel (>= 9.0)
activestorage (5.2.3)
actionpack (= 5.2.3)
activerecord (= 5.2.3)
marcel (~> 0.3.1)
activesupport (5.2.3)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
tzinfo (~> 1.1)
addressable (2.6.0)
public_suffix (>= 2.0.2, < 4.0)
airbrussh (1.3.1)
sshkit (>= 1.6.1, != 1.7.0)
archive-zip (0.12.0)
io-like (~> 0.3.0)
arel (9.0.0)
bindex (0.7.0)
bootsnap (1.4.4)
msgpack (~> 1.0)
builder (3.2.3)
byebug (11.0.1)
capistrano (3.11.0)
airbrussh (>= 1.0.0)
i18n
rake (>= 10.0.0)
sshkit (>= 1.9.0)
capistrano-bundler (1.5.0)
capistrano (~> 3.1)
capistrano-rails (1.4.0)
capistrano (~> 3.1)
capistrano-bundler (~> 1.1)
capistrano-rvm (0.1.2)
capistrano (~> 3.0)
sshkit (~> 1.2)
capistrano-sidekiq (1.0.2)
capistrano (>= 3.9.0)
sidekiq (>= 3.4)
capistrano3-puma (3.1.1)
capistrano (~> 3.7)
capistrano-bundler
puma (~> 3.4)
capybara (3.20.2)
addressable
mini_mime (>= 0.1.3)
nokogiri (~> 1.8)
rack (>= 1.6.0)
rack-test (>= 0.6.3)
regexp_parser (~> 1.2)
xpath (~> 3.2)
childprocess (1.0.1)
rake (< 13.0)
chromedriver-helper (2.1.1)
archive-zip (~> 0.10)
nokogiri (~> 1.8)
coffee-rails (4.2.2)
coffee-script (>= 2.2.0)
railties (>= 4.0.0)
coffee-script (2.4.1)
coffee-script-source
execjs
coffee-script-source (1.12.2)
concurrent-ruby (1.1.5)
connection_pool (2.2.2)
crass (1.0.4)
erubi (1.8.0)
execjs (2.7.0)
ffi (1.11.1)
globalid (0.4.2)
activesupport (>= 4.2.0)
god (0.13.7)
httparty (0.13.7)
json (~> 1.8)
multi_xml (>= 0.5.2)
i18n (1.6.0)
concurrent-ruby (~> 1.0)
igetui-ruby (1.2.2)
json (~> 1.8, >= 1.8.1)
ruby-protocol-buffers (~> 1.5, >= 1.5.1)
io-like (0.3.0)
jbuilder (2.9.1)
activesupport (>= 4.2.0)
json (1.8.6)
listen (3.1.5)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
ruby_dep (~> 1.2)
loofah (2.2.3)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
mail (2.7.1)
mini_mime (>= 0.1.1)
marcel (0.3.3)
mimemagic (~> 0.3.2)
method_source (0.9.2)
mimemagic (0.3.3)
mini_mime (1.0.1)
mini_portile2 (2.4.0)
minitest (5.11.3)
msgpack (1.2.10)
multi_xml (0.6.0)
mysql2 (0.5.2)
net-scp (1.2.1)
net-ssh (>= 2.6.5)
net-ssh (5.1.0)
nio4r (2.3.1)
nokogiri (1.10.3)
mini_portile2 (~> 2.4.0)
public_suffix (3.0.3)
puma (3.12.1)
rack (2.0.7)
rack-protection (2.0.5)
rack
rack-test (1.1.0)
rack (>= 1.0, < 3)
rails (5.2.3)
actioncable (= 5.2.3)
actionmailer (= 5.2.3)
actionpack (= 5.2.3)
actionview (= 5.2.3)
activejob (= 5.2.3)
activemodel (= 5.2.3)
activerecord (= 5.2.3)
activestorage (= 5.2.3)
activesupport (= 5.2.3)
bundler (>= 1.3.0)
railties (= 5.2.3)
sprockets-rails (>= 2.0.0)
rails-dom-testing (2.0.3)
activesupport (>= 4.2.0)
nokogiri (>= 1.6)
rails-html-sanitizer (1.0.4)
loofah (~> 2.2, >= 2.2.2)
rails_param (0.10.2)
railties (5.2.3)
actionpack (= 5.2.3)
activesupport (= 5.2.3)
method_source
rake (>= 0.8.7)
thor (>= 0.19.0, < 2.0)
rake (12.3.2)
rb-fsevent (0.10.3)
rb-inotify (0.10.0)
ffi (~> 1.0)
redis (3.3.5)
redis-actionpack (5.0.2)
actionpack (>= 4.0, < 6)
redis-rack (>= 1, < 3)
redis-store (>= 1.1.0, < 2)
redis-activesupport (5.0.7)
activesupport (>= 3, < 6)
redis-store (>= 1.3, < 2)
redis-rack (2.0.5)
rack (>= 1.5, < 3)
redis-store (>= 1.2, < 2)
redis-rails (5.0.2)
redis-actionpack (>= 5.0, < 6)
redis-activesupport (>= 5.0, < 6)
redis-store (>= 1.2, < 2)
redis-store (1.6.0)
redis (>= 2.2, < 5)
regexp_parser (1.5.0)
ruby-protocol-buffers (1.6.1)
ruby_dep (1.5.0)
rubyzip (1.2.2)
sass (3.7.4)
sass-listen (~> 4.0.0)
sass-listen (4.0.0)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
sass-rails (5.0.7)
railties (>= 4.0.0, < 6)
sass (~> 3.1)
sprockets (>= 2.8, < 4.0)
sprockets-rails (>= 2.0, < 4.0)
tilt (>= 1.1, < 3)
selenium-webdriver (3.142.2)
childprocess (>= 0.5, < 2.0)
rubyzip (~> 1.2, >= 1.2.2)
settingslogic (2.0.9)
sidekiq (4.2.10)
concurrent-ruby (~> 1.0)
connection_pool (~> 2.2, >= 2.2.0)
rack-protection (>= 1.5.0)
redis (~> 3.2, >= 3.2.1)
spring (2.0.2)
activesupport (>= 4.2)
spring-watcher-listen (2.0.1)
listen (>= 2.7, < 4.0)
spring (>= 1.2, < 3.0)
sprockets (3.7.2)
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
sprockets-rails (3.2.1)
actionpack (>= 4.0)
activesupport (>= 4.0)
sprockets (>= 3.0.0)
sshkit (1.18.0)
net-scp (>= 1.1.2)
net-ssh (>= 2.8.0)
thor (0.20.3)
thread_safe (0.3.6)
tilt (2.0.9)
turbolinks (5.2.0)
turbolinks-source (~> 5.2)
turbolinks-source (5.2.0)
tzinfo (1.2.5)
thread_safe (~> 0.1)
uglifier (4.1.20)
execjs (>= 0.3.0, < 3)
web-console (3.7.0)
actionview (>= 5.0)
activemodel (>= 5.0)
bindex (>= 0.4.0)
railties (>= 5.0)
websocket-driver (0.7.0)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.3)
xpath (3.2.0)
nokogiri (~> 1.8)
PLATFORMS
ruby
DEPENDENCIES
bootsnap (>= 1.1.0)
byebug
capistrano (~> 3.11)
capistrano-rails (~> 1.4)
capistrano-rvm (~> 0.1.2)
capistrano-sidekiq (~> 1.0, >= 1.0.2)
capistrano3-puma (~> 3.1, >= 3.1.1)
capybara (>= 2.15)
chromedriver-helper
coffee-rails (~> 4.2)
god (~> 0.13.7)
httparty (~> 0.13.7)
igetui-ruby
jbuilder (~> 2.5)
listen (>= 3.0.5, < 3.2)
mysql2
puma (~> 3.11)
rails (~> 5.2.2, >= 5.2.2.1)
rails_param (~> 0.10.2)
redis-rails (~> 5.0, >= 5.0.2)
sass-rails (~> 5.0)
selenium-webdriver
settingslogic (~> 2.0, >= 2.0.9)
sidekiq (~> 4.1, >= 4.1.2)
spring
spring-watcher-listen (~> 2.0.0)
turbolinks (~> 5)
tzinfo-data
uglifier (>= 1.3.0)
web-console (>= 3.3.0)
RUBY VERSION
ruby 2.6.0p0
BUNDLED WITH
1.17.2
class ApplicationController < ActionController::Base class ApplicationController < ActionController::Base
rescue_from StandardError, with: :rescue_all rescue_from StandardError, with: :rescue_all
include Token
def rescue_all(e) def rescue_all(e)
ErrorLog.error(e) ErrorLog.error(e)
......
module Token module Token
extend ActiveSupport::Concern
ACCESS_TOEKN_EXPIRE_TIME = 7200 ACCESS_TOEKN_EXPIRE_TIME = 7200
class << self
def key(app_name) def validate_token(app_name, token)
"push:api:#{app_name}:access_token" !! (token == get_token(app_name))
end end
def token_ttl(app_name)
$redis.ttl(tkey(app_name))
end
def generate_token(app_name) def generate_token(app_name)
token = SecureRandom.hex(32) token = SecureRandom.hex(32)
$redis.set(key(app_name), token, ex: ACCESS_TOEKN_EXPIRE_TIME) $redis.set(tkey(app_name), token, ex: ACCESS_TOEKN_EXPIRE_TIME)
token token
end end
def token(app_name) private
$redis.get(key(app_name))
end
def ttl(app_name) def tkey(app_name)
$redis.ttl(key(app_name)) "push:api:#{app_name}:access_token"
end
end end
def get_token(app_name)
$redis.get(tkey(app_name))
end
end end
\ No newline at end of file
...@@ -9,44 +9,113 @@ class PushsController < ApplicationController ...@@ -9,44 +9,113 @@ class PushsController < ApplicationController
app_setting = Settings.send(params[:app_name].to_sym) rescue {} app_setting = Settings.send(params[:app_name].to_sym) rescue {}
if app_setting['app_id'] == params[:app_id] && app_setting['app_secret'] == params[:app_secret] if app_setting['app_id'] == params[:app_id] && app_setting['app_secret'] == params[:app_secret]
render json: { code: 0, message: 'success', token: Token.generate_token(params[:app_name]), ttl: Token.ttl(params[:app_name])} render json: { code: 0, message: 'success', token: generate_token(params[:app_name]), ttl: token_ttl(params[:app_name])}
else else
render json: { code: -1, message: '应用不存在或者app_id/app_secret不匹配'} render json: { code: -1, message: '应用不存在或者app_id/app_secret不匹配'}
end end
end end
# app_name 应用名称 def single
# user_device_ids 设备ids
# message 推送信息的json 字符串
# igetui_opts 个推推送的额外选项
def push
param! :app_name, String, required: true param! :app_name, String, required: true
param! :device_ids_opts, String, required: true # param! :device_ids_opts, String, required: true
param! :message, String, required: true param! :message, String, required: true
param! :igetui_opts, String param! :igetui_opts, String
param! :app_type, String param! :app_type, String
param! :sync_push, String param! :sync_push, String
param! :user_id, String, required: true
igetui_opts = JSON.parse(params[:igetui_opts]) rescue {}
message = JSON.parse(params[:message]) rescue {}
user_id = JSON.parse(params[:user_id]) rescue {}
user_device_exist = UserDevice.where(user_id: user_id).exists?
unless user_device_exist
render json: { code: -1, message: 'user_device找不到,user_id错误'}
end
token = token_and_options(request).first
if validate_token(params[:app_name], token)
push_sync(params[:sync_push], {user_ids: Array.new(user_id), message: message, igetui_opts: igetui_opts.merge(pusher_type: 'push_message_to_single')})
render json: { code: 0, message: 'success', describe: '异步任务正在处理'}
else
render json: { code: -1, message: 'token 错误/过期'}
end
end
def batch
param! :app_name, String, required: true
# param! :device_ids_opts, String, required: true
param! :message, String, required: true
param! :igetui_opts, String
param! :app_type, String
param! :sync_push, String
param! :user_ids, Array, required: true
igetui_opts = JSON.parse(params[:igetui_opts]) rescue {} igetui_opts = JSON.parse(params[:igetui_opts]) rescue {}
message = JSON.parse(params[:message]) rescue {} message = JSON.parse(params[:message]) rescue {}
device_ids_opts = JSON.parse(params[:device_ids_opts]) rescue {} user_ids = JSON.parse(params[:user_ids]) rescue {}
user_devices_exists = UserDevice.where(user_id: user_ids).exists?
unless user_devices_exists
render json: { code: -1, message: 'user_device找不到,user_ids错误'}
end
token = token_and_options(request).first token = token_and_options(request).first
if token == Token.token(params[:app_name]) if validate_token(params[:app_name], token)
if params.has_key?(:sync_push) push_sync(params[:sync_push], {user_ids: user_ids, message: message, igetui_opts: igetui_opts.merge(pusher_type: 'push_message_to_list')})
timeout_seconds = $redis.get('push_timeout').to_i
if timeout_seconds > 0
Timeout.timeout(timeout_seconds) {
::PushWorker.new.perform(device_ids_opts, message, igetui_opts, params[:app_type])
}
else
::PushWorker.new.perform(device_ids_opts, message, igetui_opts, params[:app_type])
end
else
::PushWorker.perform_async(device_ids_opts, message, igetui_opts, params[:app_type])
end
render json: { code: 0, message: 'success', describe: '异步任务正在处理'} render json: { code: 0, message: 'success', describe: '异步任务正在处理'}
else else
render json: { code: -1, message: 'token 错误/过期'} render json: { code: -1, message: 'token 错误/过期'}
end end
end
# app_name 应用名称
# user_device_ids 设备ids
# message 推送信息的json 字符串
# # igetui_opts 个推推送的额外选项
# def push
# param! :app_name, String, required: true
# # param! :device_ids_opts, String, required: true
# param! :message, String, required: true
# param! :igetui_opts, String
# param! :app_type, String
# param! :sync_push, String
# param! :user_ids, Array, required: true
#
# igetui_opts = JSON.parse(params[:igetui_opts]) rescue {}
# message = JSON.parse(params[:message]) rescue {}
# user_ids = JSON.parse(params[:user_ids]) rescue {}
#
# token = token_and_options(request).first
# if token == Token.token(params[:app_name])
# push_sync(params[:sync_push], {user_ids: user_ids, message: message, igetui_opts: igetui_opts})
#
# render json: { code: 0, message: 'success', describe: '异步任务正在处理'}
# else
# render json: { code: -1, message: 'token 错误/过期'}
# end
# end
private
def push_sync(sync_push, opts={})
if sync_push
timeout_seconds = $redis.get('push_timeout').to_i
if timeout_seconds > 0
Timeout.timeout(timeout_seconds) {
::PushWorker.new.perform(opts)
}
else
::PushWorker.new.perform(opts)
end
else
::PushWorker.perform_async(opts)
end
end end
end end
class UserDevice < ApplicationRecord
# 当前app端传递的platform的值:
# android: igetui, xiaomi, huawei
# iso: igetui 目前还不清楚为啥不用apns,暂时不修改
enum platform: %i[igetui apns xiaomi huawei]
enum device_platform: %i[ios android]
# 用于区分当前的应用,为了推送准备, 因为推送需要根据不同的应用使用不同的 id,secret等。
enum app_type: %i[ik_duli lx_duli lx_yun]
end
\ No newline at end of file
module Push module Huawei
module Huawei module Base
ACCESS_TOKEN_KEY = "push:huawei_push:access_token".freeze ACCESS_TOKEN_KEY = "push:huawei_push:access_token".freeze
TOKEN_URL = 'https://login.cloud.huawei.com/oauth2/v2/token'.freeze TOKEN_URL = 'https://login.cloud.huawei.com/oauth2/v2/token'.freeze
PUSH_URL = 'https://api.push.hicloud.com/pushsend.do'.freeze PUSH_URL = 'https://api.push.hicloud.com/pushsend.do'.freeze
...@@ -7,87 +7,87 @@ module Push ...@@ -7,87 +7,87 @@ module Push
BATCH_PUSH_MAX = 80 BATCH_PUSH_MAX = 80
class << self class << self
# 4a7d376b47c847634571a86b37e93272 测试使用的device_token # 4a7d376b47c847634571a86b37e93272 测试使用的device_token
def push(device_tokens, message) def perform(device_tokens, message)
handle_token_res if access_token.blank? handle_token_res if access_token.blank?
device_tokens.each_slice(BATCH_PUSH_MAX) do |device_token_array| device_tokens.each_slice(BATCH_PUSH_MAX) do |device_token_array|
res = res_push(message, device_token_array) res = res_push(message, device_token_array)
# 容错处理,华为的token异常问题,重新获取发送。 # 容错处理,华为的token异常问题,重新获取发送。
if %w(80300002 80200001).include? res['code'] if %w(80300002 80200001).include? res['code']
handle_token_res handle_token_res
res_push(message, device_token_array) res_push(message, device_token_array)
end
end end
rescue StandardError => err
Push::Log.error(err)
end end
rescue StandardError => err
::Log.error(err)
end
def res_push(message, device_tokens) def res_push(message, device_tokens)
body = message(message, device_tokens) body = message(message, device_tokens)
nsp_ctx = { nsp_ctx = {
ver: '1', ver: '1',
appId: Settings.platform_settings.huawei['app_id'] appId: Settings.platform_settings.huawei['app_id']
} }
url = PUSH_URL + "?nsp_ctx=#{CGI::escape(nsp_ctx.to_json)}" url = PUSH_URL + "?nsp_ctx=#{CGI::escape(nsp_ctx.to_json)}"
post(url, body) post(url, body)
end end
# 推送信息 # 推送信息
def message(message, device_tokens) def message(message, device_tokens)
payload = { payload = {
hps: { hps: {
msg: { msg: {
type: 1, type: 1,
body: message body: message
}
} }
} }
Push::Log.info("huawei_payload: #{payload}, device_tokens: #{device_tokens}") }
params = { ::Log.info("huawei_payload: #{payload}, device_tokens: #{device_tokens}")
access_token: CGI.escape(access_token), params = {
nsp_svc: CGI.escape('openpush.message.api.send'), access_token: CGI.escape(access_token),
nsp_ts: CGI.escape(Time.now.to_i.to_s), nsp_svc: CGI.escape('openpush.message.api.send'),
device_token_list: CGI.escape(device_tokens.to_s), nsp_ts: CGI.escape(Time.now.to_i.to_s),
payload: CGI.escape(payload.to_json) device_token_list: CGI.escape(device_tokens.to_s),
} payload: CGI.escape(payload.to_json)
params_str = '' }
params.each_with_index do |(key,value), index| params_str = ''
params_str += "#{key}=#{value}" params.each_with_index do |(key,value), index|
params_str += '&' if index + 1 < params.size params_str += "#{key}=#{value}"
end params_str += '&' if index + 1 < params.size
params_str
end end
params_str
end
def handle_token_res def handle_token_res
loop do loop do
res = req_token res = req_token
if res['error'].blank? && res['access_token'].present? if res['error'].blank? && res['access_token'].present?
$redis.set(ACCESS_TOKEN_KEY, res['access_token'], ex: ACCESS_TOEKN_EXPIRE_TIME) $redis.set(ACCESS_TOKEN_KEY, res['access_token'], ex: ACCESS_TOEKN_EXPIRE_TIME)
break break
end
end end
end end
end
def req_token def req_token
body = { body = {
grant_type: 'client_credentials', grant_type: 'client_credentials',
client_id: Settings.platform_settings.huawei['app_id'], client_id: Settings.platform_settings.huawei['app_id'],
client_secret: Settings.platform_settings.huawei['app_secret'] client_secret: Settings.platform_settings.huawei['app_secret']
} }
post(TOKEN_URL, body) post(TOKEN_URL, body)
end end
def access_token def access_token
$redis.get(ACCESS_TOKEN_KEY) $redis.get(ACCESS_TOKEN_KEY)
end end
def post(url, body) def post(url, body)
headers = { 'Content-Type' => 'application/x-www-form-urlencoded' } headers = { 'Content-Type' => 'application/x-www-form-urlencoded' }
response = HTTParty.post(url, body: body, headers: headers, timeout: 5) response = HTTParty.post(url, body: body, headers: headers, timeout: 5)
Push::Log.info("huawei_push: \n access_token: #{access_token} expire_time: #{$redis.ttl(Push::Huawei::ACCESS_TOKEN_KEY)}\n url: #{url}\n body: #{body}\n response: #{response}") ::Log.info("huawei_push: \n access_token: #{access_token} expire_time: #{$redis.ttl(Push::Huawei::ACCESS_TOKEN_KEY)}\n url: #{url}\n body: #{body}\n response: #{response}")
JSON.parse(response.body) JSON.parse(response.body)
end
end end
end end
end
end end
module Igetui
class AndroidPusher
include Singleton
def self.pusher
$android_pusher ||=
IGeTui.pusher(
Settings.platform_settings.igetui.android['app_id'],
Settings.platform_settings.igetui.android['app_key'],
Settings.platform_settings.igetui.android['master_secret']
)
end
end
end
\ No newline at end of file
module Igetui
class Base
def initialize(user_device_ids, opts)
opts = HashWithIndifferentAccess.new(opts)
@template_data = opts[:template_data]
@igetui_opts = opts[:igetui_opts]
@user_device_ids = user_device_ids
@pusher = pusher(opts[:device_platform])
@pusher_type = opts[:pusher_type]
end
def perform
@template_data[:push_type] ||= config[:push_type]
@igetui_opts[:transmission_type] ||= 0
@igetui_opts[:transmission_content] = @template_data.as_json
template_type = 'TransmissionTemplate'
template_data = @igetui_opts
result = push_message_to(@pusher, @pusher_type, template_type, template_data, @user_device_ids)
::Log.info("igetui_push: \n template_data: #{template_data}\n user_device_ids: #{@user_device_ids}\n response: #{result}")
end
private
def pusher(device_platform)
case device_platform
when 'android'
Igetui::AndroidPusher.pusher
when 'ios'
Igetui::IosPusher.pusher
end
end
def push_message_to(pusher, pusher_type, template_type, template_data, client_id)
client_id_list = Array(client_id)
template = set_template_data(template_type, template_data)
case pusher_type
when 'push_message_to_single'
message = IGeTui::SingleMessage.new
message.data = template
client_id_list.map do |client_id|
client = IGeTui::Client.new(client_id)
pusher.push_message_to_single(message, client)
end
when 'push_message_to_list'
message = IGeTui::ListMessage.new
message.data = template
content_id = pusher.get_content_id(message)
clients = client_id_list.map { |client_id| IGeTui::Client.new(client_id) }
pusher.push_message_to_list(content_id, clients)
when 'push_message_to_app'
message = IGeTui::AppMessage.new
message.data = template
message.app_id_list = client_id_list
pusher.push_message_to_app(message)
end
end
def set_template_data(template_type, template_data)
@template ||= "IGeTui::#{template_type}".constantize.new
case template_type
when 'NotificationTemplate', 'NotyPopLoadTemplate', 'LinkTemplate'
template_data.reverse_merge!(Settings.platform_settings.igetui['template_base'])
template_data.each do |k, v|
@template.send("#{k}=", v)
end
@template.set_push_info(*template_data[:push_info]) if template_data.key? :push_info
when 'TransmissionTemplate'
@template.transmission_content = template_data[:transmission_content].is_a?(Hash) ? template_data[:transmission_content].to_json : template_data[:transmission_content]
@template.transmission_type = template_data[:transmission_type] if template_data.key?(:transmission_type)
@template.set_push_info(*template_data[:push_info]) if template_data.key? :push_info
end
end
end
end
module Igetui
class IosPusher
include Singleton
def self.pusher
$android_pusher ||=
IGeTui.pusher(
Settings.platform_settings.igetui.ios['app_id'],
Settings.platform_settings.igetui.ios['app_key'],
Settings.platform_settings.igetui.ios['master_secret']
)
end
end
end
\ No newline at end of file
module Push module Log
module Log class << self
class << self def info(info)
def info(info) logger.tagged(Time.zone.now) { logger.info info }
logger.tagged(Time.zone.now) { logger.info info } end
end
def error(e) def error(e)
logger.tagged(Time.zone.now) { logger.error e.message.to_s } logger.tagged(Time.zone.now) { logger.error e.message.to_s }
e.backtrace.each { |message| logger.tagged(Time.zone.now) { logger.error message.to_s } } e.backtrace.each { |message| logger.tagged(Time.zone.now) { logger.error message.to_s } }
end end
private private
def logger def logger
@logger ||= ActiveSupport::TaggedLogging.new(::Logger.new("#{Rails.root}/log/various_push.log", 'weekly')) @logger ||= ActiveSupport::TaggedLogging.new(::Logger.new("#{Rails.root}/log/various_push.log", 'weekly'))
end
end end
end end
end end
\ No newline at end of file
module Push
module Igetui
class << self
def push(user_device_ids, template_data = {}, opts = {})
# 包装成igetui 真正需要的参数格式
opts[:transmission_content] = template_data
if user_device_ids.size > 1
push_transmission_to_list_igetui(user_device_ids, opts)
else
push_transmission_to_igetui(user_device_ids, opts)
end
rescue StandardError => err
::Push::Log.error(err)
end
def config
{
push_type: 2
}
end
def push_transmission_to_igetui(user_device_id, template_data = {})
template_data = handle_template_data(template_data)
push_igetui_with_asnyc(
user_device_id,
template_data,
template_type: 'TransmissionTemplate'
)
end
def push_transmission_to_list_igetui(user_device_ids, template_data = {})
template_data = handle_template_data(template_data)
push_list_igetui_with_asnyc(
user_device_ids,
template_data,
template_type: 'TransmissionTemplate', pusher_type: 'push_message_to_list'
)
end
private
def handle_template_data(template_data)
template_data = HashWithIndifferentAccess.new(template_data)
transmission_content = HashWithIndifferentAccess.new(template_data.delete(:transmission_content))
transmission_content[:push_type] ||= config[:push_type]
template_data[:transmission_type] ||= 0
template_data[:transmission_content] = transmission_content.as_json
template_data
end
def push_igetui_with_asnyc(user_device_id, template_data = {}, opts = nil)
return if template_data.blank?
opts ||= HashWithIndifferentAccess.new(template_type: 'TransmissionTemplate')
template_data = HashWithIndifferentAccess.new(template_data)
perform(template_data, opts, user_device_id)
end
def push_list_igetui_with_asnyc(user_device_ids, template_data = {}, opts = { pusher_type: 'push_message_to_list' })
return if user_device_ids.blank? || template_data.blank?
opts ||= HashWithIndifferentAccess.new(template_type: 'TransmissionTemplate')
perform(template_data, opts, user_device_ids)
end
def perform(template_data, opts, user_device_ids)
opts = HashWithIndifferentAccess.new(opts)
igetui = Igetui::Push.new(template_data, opts)
result = igetui.push_message_to(user_device_ids)
::Push::Log.info("igetui_push: \n template_data: #{template_data}\n opts: #{opts}\n user_device_ids: #{user_device_ids}\n response: #{result}")
end
end
end
end
\ No newline at end of file
module Push
module Igetui
class Push
attr_accessor :pusher, :pusher_type, :template_type, :template, :template_data
PUSHERTYPES = %w[push_message_to_single push_message_to_list push_message_to_app].freeze
TEMPLATETYPES = %w[LinkTemplate NotificationTemplate TransmissionTemplate NotyPopLoadTemplate].freeze
DEVICEPLATFORMS = %w[android ios].freeze
def initialize(template_data, opts = {})
opts = HashWithIndifferentAccess.new(opts)
@template_data = HashWithIndifferentAccess.new(template_data || {})
@pusher_type = PUSHERTYPES.include?((opts[:pusher_type]).to_s) ? opts[:pusher_type] : 'push_message_to_single'
@template_type = TEMPLATETYPES.include?((opts[:template_type]).to_s) ? opts[:template_type] : 'NotificationTemplate'
::Push::Log.info("@template_data is #{@template_data.to_json}")
set_message
set_template_data
@message.data = @template
end
def push_message_to(client_id)
client_id_list = Array(client_id)
case pusher_type
when 'push_message_to_single'
client_id_list.map do |client_id|
client = IGeTui::Client.new(client_id)
pusher.push_message_to_single(@message, client)
end
when 'push_message_to_list'
content_id = pusher.get_content_id(@message)
clients = client_id_list.map { |client_id| IGeTui::Client.new(client_id) }
pusher.push_message_to_list(content_id, clients)
when 'push_message_to_app'
@message.app_id_list = client_id_list
pusher.push_message_to_app(@message)
end
end
private
def pusher
@pusher ||=
if DEVICEPLATFORMS.include?((@template_data['device_platform'].to_s))
case @template_data['device_platform'].to_s
when 'android'
IGeTui.pusher(
Settings.platform_settings.igetui.android['app_id'],
Settings.platform_settings.igetui.android['app_key'],
Settings.platform_settings.igetui.android['master_secret']
)
when 'ios'
IGeTui.pusher(
Settings.platform_settings.igetui.ios['app_id'],
Settings.platform_settings.igetui.ios['app_key'],
Settings.platform_settings.igetui.ios['master_secret']
)
end
else
::Push::Log.info("设备类型不正确#{@device_platform}")
raise "Failed to create pusher"
end
end
def set_message
@message = case pusher_type
when 'push_message_to_single'
IGeTui::SingleMessage.new
when 'push_message_to_list'
IGeTui::ListMessage.new
when 'push_message_to_app'
IGeTui::AppMessage.new
end
end
def set_template_data
@template = "IGeTui::#{template_type}".constantize.new
case template_type
when 'NotificationTemplate', 'NotyPopLoadTemplate', 'LinkTemplate'
@template_data.reverse_merge!(Settings.platform_settings.igetui['template_base'])
@template_data.each do |k, v|
@template.send("#{k}=", v)
end
@template.set_push_info(*@template_data[:push_info]) if @template_data.key? :push_info
when 'TransmissionTemplate'
@template.transmission_content = @template_data[:transmission_content].is_a?(Hash) ? @template_data[:transmission_content].to_json : @template_data[:transmission_content]
@template.transmission_type = @template_data[:transmission_type] if @template_data.key?(:transmission_type)
@template.set_push_info(*@template_data[:push_info]) if @template_data.key? :push_info
end
end
end
end
end
#push功能的代理选择用哪种推送工具1.个推 2.小米 3.华为
class PushToolClient
def initialize(opts={})
@user_ids = opts[:user_ids]
@opts = opts
end
def do_push
@push_device_collections ||= UserDevice.where(user_id: @user_ids).group_by(&:platform)
@igetui_push_device_collections ||= @push_device_collections.group_by(&:device_platform)
Igetui::Base.new(@igetui_push_device_collections['android'].map(&:device_id), @opts.merge(device_platform: 'android')).perform
Igetui::Base.new(@igetui_push_device_collections['ios'].map(&:device_id), @opts.merge(device_platform: 'ios')).perform
#现在好像不用了
# Push::IgetuiIos.push(@push_collections[:igetui_ios], @opts) if @push_collections[:apns].present?
# Push::IgetuiAndroid.push(@push_collections[:igetui_android], @opts) if @push_collections[:apns].present?
Xiaomi::Base.perform(@push_device_collections['xiaomi'].map(&:device_id), @opts[:message]) if @push_device_collections[:xiaomi].present?
Huawei::Base.perform(@push_device_collections['huawei'].map(&:device_id), @opts[:message]) if @push_device_collections[:huawei].present?
end
end
\ No newline at end of file
module Push module Xiaomi
module Xiaomi module Base
PUSH_URL = 'https://api.xmpush.xiaomi.com/v3/message/regid'.freeze PUSH_URL = 'https://api.xmpush.xiaomi.com/v3/message/regid'.freeze
BATCH_PUSH_MAX = 80 BATCH_PUSH_MAX = 80
class << self class << self
def push(registration_ids, payload) def perform(registration_ids, payload)
registration_ids.each_slice(BATCH_PUSH_MAX) do |registration_ids_array| registration_ids.each_slice(BATCH_PUSH_MAX) do |registration_ids_array|
registration_id = registration_ids_array.join(',') registration_id = registration_ids_array.join(',')
post(message(payload, registration_id)) post(message(payload, registration_id))
end
rescue StandardError => err
Push::Log.error(err)
end end
rescue StandardError => err
::Log.error(err)
end
def message(payload, registration_id) def message(payload, registration_id)
message = config message = config
message[:registration_id] = registration_id message[:registration_id] = registration_id
message[:payload] = payload.to_json message[:payload] = payload.to_json
message message
end end
# notify_type # notify_type
# DEFAULT_ALL = -1; # DEFAULT_ALL = -1;
# DEFAULT_SOUND = 1; // 使用默认提示音提示; # DEFAULT_SOUND = 1; // 使用默认提示音提示;
# DEFAULT_VIBRATE = 2; // 使用默认震动提示; # DEFAULT_VIBRATE = 2; // 使用默认震动提示;
# DEFAULT_LIGHTS = 4; // 使用默认led灯光提示; # DEFAULT_LIGHTS = 4; // 使用默认led灯光提示;
# pass_through # pass_through
# 0 表示通知栏消息, 1 表示透传消息 # 0 表示通知栏消息, 1 表示透传消息
def config def config
{ {
restricted_package_name: Settings.platform_settings.xiaomi['package_name'], restricted_package_name: Settings.platform_settings.xiaomi['package_name'],
pass_through: 1, pass_through: 1,
title: 'xiaomi push', title: 'xiaomi push',
description: 'xiaomi push', description: 'xiaomi push',
notify_type: 1 notify_type: 1
} }
end end
def post(params) def post(params)
response = HTTParty.post(PUSH_URL, query: params, response = HTTParty.post(PUSH_URL, query: params,
headers: { headers: {
'Accept' => 'application/json;', 'Accept' => 'application/json;',
"Authorization": "key=#{Settings.platform_settings.xiaomi['app_secret']}" "Authorization": "key=#{Settings.platform_settings.xiaomi['app_secret']}"
}, },
timeout: 5) timeout: 5)
Push::Log.info("xiaomi_push: \n url: #{PUSH_URL}\n params: #{params}\n response: #{response}") ::Log.info("xiaomi_push: \n url: #{PUSH_URL}\n params: #{params}\n response: #{response}")
response response
end end
end end
end end
end end
...@@ -2,8 +2,9 @@ class PushWorker ...@@ -2,8 +2,9 @@ class PushWorker
include Sidekiq::Worker include Sidekiq::Worker
sidekiq_options queue: :push sidekiq_options queue: :push
def perform(device_ids_opts, message, igetui_opts, platform = nil) def perform(opts)
Push.push(device_ids_opts, message, igetui_opts, platform) ::PushToolClient.do_push(opts)
# Push.push(user_ids, message, igetui_opts, platform)
rescue StandardError => e rescue StandardError => e
ErrorLog.error(e) ErrorLog.error(e)
end end
......
...@@ -5,13 +5,17 @@ ...@@ -5,13 +5,17 @@
# gem 'sqlite3' # gem 'sqlite3'
# #
default: &default default: &default
adapter: sqlite3 adapter: mysql2
encoding: utf8
host: rm-m5ef10gzq1n5e7b9abo.mysql.rds.aliyuncs.com
username: crm_rw
password: pHB+!*Uv9Rl9
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
timeout: 5000 timeout: 5000
development: development:
<<: *default <<: *default
database: db/development.sqlite3 database: crm_dev
# Warning: The database defined as "test" will be erased and # Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake". # re-generated from your development database when you run "rake".
......
default: &default
adapter: mysql2
encoding: utf8
host: rm-m5ef10gzq1n5e7b9abo.mysql.rds.aliyuncs.com
username: crm_rw
password: pHB+!*Uv9Rl9
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
timeout: 5000
development:
<<: *default
database: crm_dev
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
<<: *default
database: db/test.sqlite3
production:
<<: *default
database: db/production.sqlite3
Rails.application.routes.draw do Rails.application.routes.draw do
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
post 'api/v1/token', to: 'pushs#token' post 'api/v1/token', to: 'pushs#token'
post 'api/v1/push', to: 'pushs#push' post 'api/v1/single', to: 'pushs#single'
post 'api/v1/batch', to: 'pushs#batch'
require 'sidekiq/web' require 'sidekiq/web'
mount Sidekiq::Web => '/sidekiq' mount Sidekiq::Web => '/sidekiq'
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment