rails_wechat 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/app/apis/wechat/api/program/wxa.rb +15 -0
  3. data/app/apis/wechat/signature.rb +5 -1
  4. data/app/controllers/wechat/admin/apps_controller.rb +6 -4
  5. data/app/controllers/wechat/admin/wechat_users_controller.rb +1 -1
  6. data/app/controllers/wechat/controller/application.rb +2 -2
  7. data/app/controllers/wechat/my/users_controller.rb +1 -5
  8. data/app/controllers/wechat/panel/template_configs_controller.rb +0 -12
  9. data/app/controllers/wechat/platforms_controller.rb +1 -1
  10. data/app/controllers/wechat/program_users_controller.rb +16 -15
  11. data/app/controllers/wechat/wechat_controller.rb +1 -1
  12. data/app/controllers/wechat/wechats_controller.rb +2 -2
  13. data/app/helpers/wechat/application_helper.rb +31 -0
  14. data/app/jobs/wechat/ticket_clean_job.rb +9 -0
  15. data/app/models/oauth_user/wechat/wechat_user.rb +6 -0
  16. data/app/models/wechat/ext/member.rb +21 -0
  17. data/app/models/wechat/ext/organ.rb +1 -1
  18. data/app/models/wechat/ext/user.rb +2 -2
  19. data/app/models/wechat/ext/user_tag.rb +1 -1
  20. data/app/models/wechat/model/app/public_app.rb +3 -4
  21. data/app/models/wechat/model/app.rb +8 -4
  22. data/app/models/wechat/model/menu/click_menu.rb +1 -6
  23. data/app/models/wechat/model/menu/mini_program_menu.rb +1 -6
  24. data/app/models/wechat/model/menu/scan_push_menu.rb +1 -6
  25. data/app/models/wechat/model/menu/scan_wait_menu.rb +1 -6
  26. data/app/models/wechat/model/menu/view_menu.rb +1 -2
  27. data/app/models/wechat/model/menu.rb +1 -2
  28. data/app/models/wechat/model/oauth_user/program_user.rb +6 -4
  29. data/app/models/wechat/model/oauth_user/wechat_user.rb +26 -15
  30. data/app/models/wechat/model/receive.rb +2 -3
  31. data/app/models/wechat/model/reply/news_reply.rb +4 -0
  32. data/app/models/wechat/model/reply/success_reply.rb +4 -0
  33. data/app/models/wechat/model/reply.rb +4 -0
  34. data/app/models/wechat/model/request.rb +40 -7
  35. data/app/models/wechat/model/scene.rb +17 -4
  36. data/app/models/wechat/model/tag.rb +1 -1
  37. data/app/models/wechat/model/template_config/template_public.rb +1 -1
  38. data/app/models/wechat/model/template_config.rb +2 -0
  39. data/app/models/wechat/model/ticket.rb +5 -0
  40. data/app/models/wechat/model/user_tag.rb +2 -6
  41. data/app/views/admin/_wechat_nav.html.erb +2 -2
  42. data/app/views/application/_wx_open_subscribe.html.erb +15 -0
  43. data/app/views/my/_wechat_nav.html+phone.erb +2 -2
  44. data/app/views/panel/_wechat_nav.html.erb +2 -2
  45. data/app/views/wechat/admin/apps/_form.html.erb +1 -0
  46. data/app/views/wechat/admin/apps/_index_tbody.html.erb +4 -16
  47. data/app/views/wechat/admin/apps/_index_thead.html.erb +5 -2
  48. data/app/views/wechat/admin/apps/_index_tr.html.erb +27 -7
  49. data/app/views/wechat/admin/apps/_pay_form.html.erb +10 -7
  50. data/app/views/wechat/admin/apps/edit_cert.html.erb +2 -2
  51. data/app/views/wechat/admin/apps/edit_pay.html.erb +3 -0
  52. data/app/views/wechat/admin/apps/update_cert.turbo_stream.erb +3 -0
  53. data/app/views/wechat/admin/{menus → base}/_breadcrumb.html.erb +1 -0
  54. data/app/views/wechat/admin/base/_wechat_nav_user.html.erb +0 -8
  55. data/app/views/wechat/admin/extractors/_form.html.erb +2 -2
  56. data/app/views/wechat/admin/menus/_button.html.erb +3 -3
  57. data/app/views/wechat/admin/menus/_index_tbody.html.erb +2 -2
  58. data/app/views/wechat/admin/menus/_index_tr.html.erb +3 -3
  59. data/app/views/wechat/admin/registers/_button.html.erb +1 -1
  60. data/app/views/wechat/admin/registers/_index_tbody.html.erb +3 -3
  61. data/app/views/wechat/admin/registers/_index_tr.html.erb +6 -6
  62. data/app/views/wechat/admin/replies/_index_tbody.html.erb +2 -2
  63. data/app/views/wechat/admin/requests/_button.html.erb +1 -1
  64. data/app/views/wechat/admin/requests/_index_tr.html.erb +2 -2
  65. data/app/views/wechat/admin/responses/_index_tbody.html.erb +1 -1
  66. data/app/views/wechat/admin/responses/_index_thead.html.erb +1 -1
  67. data/app/views/wechat/admin/responses/_index_tr.html.erb +4 -4
  68. data/app/views/wechat/admin/responses/_show_table.html.erb +1 -1
  69. data/app/views/wechat/admin/tags/_button.html.erb +2 -2
  70. data/app/views/wechat/admin/tags/_index_tr.html.erb +3 -3
  71. data/app/views/wechat/admin/tags/index.html.erb +1 -0
  72. data/app/views/wechat/admin/templates/_button.html.erb +1 -1
  73. data/app/views/wechat/admin/templates/sync.turbo_stream.erb +3 -0
  74. data/app/views/wechat/admin/wechat_users/_filter_form.html.erb +2 -1
  75. data/app/views/wechat/admin/wechat_users/_index_tbody.html.erb +7 -1
  76. data/app/views/wechat/admin/wechat_users/_index_thead.html.erb +1 -1
  77. data/app/views/wechat/apps/login.html.erb +4 -1
  78. data/app/views/wechat/my/registers/_wechat_register.html.erb +3 -3
  79. data/app/views/wechat/my/registers/_wechat_register_done.html.erb +1 -1
  80. data/app/views/wechat/my/registers/index.html+phone.erb +1 -1
  81. data/app/views/wechat/my/registers/index.html.erb +4 -4
  82. data/app/views/wechat/my/subscribes/index.html.erb +4 -4
  83. data/app/views/wechat/my/users/_request.html.erb +26 -0
  84. data/app/views/wechat/my/users/invite_qrcode.html+phone.erb +4 -23
  85. data/app/views/wechat/panel/apps/_index_tbody.html.erb +4 -4
  86. data/app/views/wechat/panel/apps/_index_tr.html.erb +3 -3
  87. data/app/views/wechat/panel/menus/_button.html.erb +2 -2
  88. data/app/views/wechat/panel/menus/_index_tbody.html.erb +2 -2
  89. data/app/views/wechat/panel/menus/_index_tr.html.erb +3 -3
  90. data/app/views/wechat/panel/platforms/_index_tr.html.erb +5 -5
  91. data/app/views/wechat/share/apps/_index_tbody.html.erb +3 -3
  92. data/app/views/wechat/share/apps/_index_tr.html.erb +1 -1
  93. data/app/views/wechat/share/menus/_button.html.erb +3 -3
  94. data/app/views/wechat/share/menus/_index_tbody.html.erb +3 -3
  95. data/app/views/wechat/share/menus/_index_tr.html.erb +3 -3
  96. data/app/views/wechat/share/scenes/_index_tr.html.erb +6 -6
  97. data/app/views/wechat/share/wechat_users/_index_tr.html.erb +2 -2
  98. data/config/locales/zh.controller.yml +4 -0
  99. data/config/locales/zh.enum.yml +4 -3
  100. data/config/routes.rb +2 -2
  101. data/lib/rails_wechat/config.rb +6 -9
  102. data/lib/rails_wechat.rb +0 -1
  103. metadata +36 -19
  104. data/app/jobs/wechat/user_tag_remove_job.rb +0 -11
  105. data/app/views/wechat/admin/requests/_breadcrumb.html.erb +0 -7
  106. data/app/views/wechat/admin/templates/_breadcrumb.html.erb +0 -7
  107. data/app/views/wechat/my/users/requests.html+phone.erb +0 -53
  108. data/lib/rails_wechat/helpers.rb +0 -32
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fb5dc5c123e370fc9df6aa2f03e3fd2e355b2de056068a3b1e1f024de72f67e1
4
- data.tar.gz: f65253d5f0262f894244b54b58855e24dca8cc15324251fb61a4a7dd8eccc7f5
3
+ metadata.gz: e6ff548ec2afb5fb4031d9cb0119fb904af927aed69a3483e298a70f4662eabd
4
+ data.tar.gz: d98fc0cc0d9a2195849cb721b72be5df21b7359e7eb39bd6f58c44681d99b250
5
5
  SHA512:
6
- metadata.gz: 635043ed780b4fdc0a3cd2f8519eef57326dffca8cc85e75c97050c00e378322b6d779807e0c00f83cdd190412b6908a8778858f8f59ac09b0b6e50ebb04dab7
7
- data.tar.gz: e1793cc252e7679fdae54f22d1504624548afdd5c2ea0a1c876b048a0fcb4e399c5e73a32911b76a146fa5985ede9dc2b80a46a49e75b20a69b8f46a5793505d
6
+ metadata.gz: 93f4d5d76117ee36cd9a6e6c13dae50af23d0e1684d28216eabc4f2d6fe1b21824038205826c0b5373ffcb233ccf5ce01645035f91ed1f3f731e92cb03beabb3
7
+ data.tar.gz: 58f0bd26eaec2712b88578f177efc43ca48a40cc3110ca9c34ae5fa8e26dc285c441cb31f39ee1d897ea11f7db59e2c470616917c9cb4cd6081b73c3e88721ba
@@ -17,5 +17,20 @@ module Wechat::Api
17
17
  post 'getwxacodeunlimit', **p, base: BASE
18
18
  end
19
19
 
20
+ def generate_url(path: '/pages/index/index', **options)
21
+ post 'generate_urllink', path: path, **options, base: BASE
22
+ end
23
+
24
+ def generate_scheme(path: '/pages/index/index', **options)
25
+ p = {
26
+ jump_wxa: {
27
+ path: path,
28
+ **options.slice(:query, :env_version)
29
+ },
30
+ **options.slice(:is_expire, :expire_type, :expire_time, :expire_interval)
31
+ }
32
+ post 'generatescheme', **p, base: BASE
33
+ end
34
+
20
35
  end
21
36
  end
@@ -24,7 +24,11 @@ module Wechat
24
24
  jsapi_ticket: ticket,
25
25
  url: url
26
26
  }
27
- result = Digest::SHA1.hexdigest params.to_qeury
27
+ pairs = params.sort.map do |key, value|
28
+ "#{key}=#{value}"
29
+ end.join('&')
30
+
31
+ result = Digest::SHA1.hexdigest pairs
28
32
  params.merge(signature: result)
29
33
  end
30
34
 
@@ -1,11 +1,11 @@
1
1
  module Wechat
2
2
  class Admin::AppsController < Admin::BaseController
3
- before_action :set_app, only: [:show, :info, :edit, :edit_cert, :update_cert, :update, :destroy]
3
+ before_action :set_app, only: [:show, :info, :edit, :edit_pay, :edit_cert, :update_cert, :update, :destroy]
4
4
 
5
5
  def index
6
6
  q_params = {}
7
7
  q_params.merge! default_params
8
- q_params.merge! params.permit(:id)
8
+ q_params.merge! params.permit(:id, :type)
9
9
 
10
10
  @apps = App.default_where(q_params).order(id: :asc).page(params[:page])
11
11
  end
@@ -33,7 +33,7 @@ module Wechat
33
33
  end
34
34
 
35
35
  def update_cert
36
- pkcs12 = WxPay.set_apiclient_by_pkcs12(params[:cert].read, @app.mch_id)
36
+ pkcs12 = WxPay::Utils.set_apiclient_by_pkcs12(params[:cert].read, @app.mch_id)
37
37
 
38
38
  @app.apiclient_cert = pkcs12.certificate
39
39
  @app.apiclient_key = pkcs12.key
@@ -50,6 +50,7 @@ module Wechat
50
50
  :type,
51
51
  :name,
52
52
  :enabled,
53
+ :inviting,
53
54
  :appid,
54
55
  :secret,
55
56
  :agentid,
@@ -57,7 +58,8 @@ module Wechat
57
58
  :key,
58
59
  :key_v3,
59
60
  :encrypt_mode,
60
- :serial_no
61
+ :serial_no,
62
+ :domain
61
63
  )
62
64
  p.merge! default_form_params
63
65
  end
@@ -5,7 +5,7 @@ module Wechat
5
5
 
6
6
  def index
7
7
  q_params = {}
8
- q_params.merge! params.permit('wechat_user_tags.tag_id', :name)
8
+ q_params.merge! params.permit('wechat_user_tags.tag_id', :name, :uid)
9
9
 
10
10
  @wechat_users = @app.wechat_users.default_where(q_params).order(id: :desc).page(params[:page])
11
11
  end
@@ -21,7 +21,7 @@ module Wechat
21
21
  end
22
22
 
23
23
  if redirect_url
24
- logger.debug " \e[35mRedirect to: #{redirect_url}\e[0m"
24
+ logger.debug "\e[35m Redirect to: #{redirect_url} \e[0m"
25
25
  end
26
26
 
27
27
  redirect_to redirect_url
@@ -30,7 +30,7 @@ module Wechat
30
30
  def current_wechat_app
31
31
  return @current_wechat_app if defined?(@current_wechat_app)
32
32
  @current_wechat_app = current_organ_domain&.wechat_app
33
- logger.debug " \e[35mCurrent Wechat App is #{@current_wechat_app&.id}\e[0m"
33
+ logger.debug "\e[35m Current Wechat App is #{@current_wechat_app&.id} \e[0m"
34
34
  @current_wechat_app
35
35
  end
36
36
 
@@ -3,12 +3,8 @@ module Wechat
3
3
 
4
4
  def invite_qrcode
5
5
  @scene = current_user.invite_scene(current_wechat_app)
6
- end
7
-
8
- def requests
9
- @scene = current_user.invite_scene(current_wechat_app)
10
6
  if @scene.tag
11
- @requests = @scene.tag.requests.includes(:wechat_user).page(params[:page])
7
+ @requests = @scene.tag.requests.includes(:wechat_user).page(params[:page])
12
8
  else
13
9
  @requests = Request.none.page(params[:page])
14
10
  end
@@ -6,18 +6,6 @@ module Wechat
6
6
  @template_configs = TemplateConfig.includes(:template_key_words).page(params[:page])
7
7
  end
8
8
 
9
- def new
10
- @template_config = TemplateConfig.new
11
- end
12
-
13
- def create
14
- @template_config = TemplateConfig.new(template_config_params)
15
-
16
- unless @template_config.save
17
- render :new, locals: { model: @template_config }, status: :unprocessable_entity
18
- end
19
- end
20
-
21
9
  private
22
10
  def set_template_config
23
11
  @template_config = TemplateConfig.find(params[:id])
@@ -1,6 +1,6 @@
1
1
  module Wechat
2
2
  class PlatformsController < BaseController
3
- skip_before_action :verify_authenticity_token, raise: false
3
+ skip_before_action :verify_authenticity_token, raise: false if respond_to? :verify_authenticity_token
4
4
  before_action :set_platform, only: [:show, :message, :callback]
5
5
 
6
6
  # 授权事件接收URL: platforms/notice
@@ -3,19 +3,17 @@ module Wechat
3
3
  before_action :set_app, only: [:create]
4
4
  before_action :require_authorized_token, only: [:info, :mobile]
5
5
  before_action :set_wechat_program_user, only: [:info, :mobile]
6
- skip_before_action :verify_authenticity_token
6
+ skip_before_action :verify_authenticity_token if respond_to? :verify_authenticity_token
7
7
 
8
8
  def create
9
9
  info = @app.api.jscode2session(session_params[:code])
10
- @program_user = ProgramUser.create_or_find_by!(uid: info['openid']) do |program_user|
11
- program_user.appid = params[:appid]
12
- program_user.identity = info['openid']
13
- program_user.unionid = info['unionId']
14
- end
15
- token = @program_user.auth_token(info['session_key'])
10
+ @program_user = ProgramUser.create_or_find_by!(uid: info['openid'])
11
+ @program_user.appid = params[:appid]
12
+ @program_user.unionid = info['unionid']
13
+ auth_token = @program_user.auth_token(info['session_key'])
16
14
 
17
- headers['Auth-Token'] = token
18
- render json: { auth_token: token }
15
+ headers['Auth-Token'] = auth_token.token
16
+ render json: { auth_token: auth_token.token, account: @program_user.account, user: @program_user.user }
19
17
  end
20
18
 
21
19
  def info
@@ -28,7 +26,6 @@ module Wechat
28
26
  province: userinfo_params[:province],
29
27
  country: userinfo_params[:country]
30
28
  }
31
-
32
29
  @program_user.save
33
30
 
34
31
  render json: { program_user: @program_user.as_json(only: [:id, :identity, :name, :avatar_url]) }
@@ -40,13 +37,17 @@ module Wechat
40
37
  phone_number = @program_user.get_phone_number(params[:encryptedData], params[:iv], session_key)
41
38
  if phone_number
42
39
  @program_user.identity = phone_number
43
- @account = @program_user.account || @program_user.build_account
40
+ @account = @program_user.account || @program_user.build_account(type: 'Auth::MobileAccount')
44
41
  @account.confirmed = true
45
- #@account.join(name: @program_user.name, invited_code: params[:invited_code])
46
- @program_user.save
47
- @account.save
42
+ @account.user || @account.build_user
43
+ @account.user.assign_attributes name: @program_user.name, invited_code: params[:invited_code]
44
+
45
+ @program_user.class.transaction do
46
+ @program_user.save!
47
+ @account.save!
48
+ end
48
49
 
49
- render json: { program_user: @program_user.as_json(only: [:id, :identity]) }
50
+ render json: { program_user: @program_user.as_json(only: [:id, :identity]), user: @program_user.user }
50
51
  else
51
52
  current_authorized_token.destroy # 触发重新授权逻辑
52
53
  render :mobile_err, locals: { model: @program_user }, status: :unprocessable_entity
@@ -1,6 +1,6 @@
1
1
  module Wechat
2
2
  class WechatController < BaseController
3
- skip_before_action :verify_authenticity_token
3
+ skip_before_action :verify_authenticity_token if respond_to? :verify_authenticity_token
4
4
 
5
5
  def auth
6
6
  @wechat_user = WechatUser.find_or_initialize_by(uid: params[:openid])
@@ -1,6 +1,6 @@
1
1
  module Wechat
2
2
  class WechatsController < BaseController
3
- skip_before_action :verify_authenticity_token, raise: false
3
+ skip_before_action :verify_authenticity_token, raise: false if respond_to? :verify_authenticity_token
4
4
  before_action :set_app
5
5
  before_action :verify_signature
6
6
 
@@ -28,7 +28,7 @@ module Wechat
28
28
 
29
29
  private
30
30
  def set_app
31
- @app = App.valid.find(params[:id])
31
+ @app = App.enabled.find(params[:id])
32
32
  end
33
33
 
34
34
  def verify_signature
@@ -0,0 +1,31 @@
1
+ module Wechat
2
+ module ApplicationHelper
3
+
4
+ def wechat_raw_config_js(debug: false, apis: [])
5
+ page_url = controller.request.original_url
6
+ page_url.delete_suffix!('#')
7
+ js_hash = Wechat::Signature.signature(current_wechat_app.jsapi_ticket, page_url)
8
+ logger.debug "\e[35m Current page is: #{page_url}, Hash: #{js_hash.inspect} \e[0m"
9
+
10
+ <<-WECHAT_CONFIG_JS
11
+ wx.config({
12
+ debug: #{debug},
13
+ appId: '#{current_wechat_app.appid}',
14
+ timestamp: '#{js_hash[:timestamp]}',
15
+ nonceStr: '#{js_hash[:noncestr]}',
16
+ signature: '#{js_hash[:signature]}',
17
+ jsApiList: ['#{apis.join("','")}'],
18
+ openTagList: ['wx-open-subscribe']
19
+ })
20
+ WECHAT_CONFIG_JS
21
+ rescue => e
22
+ logger.debug e.message
23
+ end
24
+
25
+ def wechat_config_js(debug: false, apis: [])
26
+ config_js = wechat_raw_config_js(debug: debug, apis: apis)
27
+ javascript_tag config_js, type: 'application/javascript', nonce: true
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,9 @@
1
+ module Wechat
2
+ class TicketCleanJob < ApplicationJob
3
+
4
+ def perform(ticket)
5
+ Ticket.where(appid: ticket.appid).where.not(id: ticket.id).delete_all
6
+ end
7
+
8
+ end
9
+ end
@@ -1,5 +1,11 @@
1
1
  module Wechat
2
+ if defined? RailsAuth
2
3
  class WechatUser < ::Auth::OauthUser
3
4
  include Model::OauthUser::WechatUser
4
5
  end
6
+ else
7
+ class WechatUser < ApplicationRecord
8
+ include Model::OauthUser::WechatUser
9
+ end
10
+ end
5
11
  end
@@ -0,0 +1,21 @@
1
+ module Wechat
2
+ module Ext::Member
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ has_many :wechat_users, class_name: 'Wechat::WechatUser', through: :account, source: :oauth_users
7
+ has_many :program_users, class_name: 'Wechat::ProgramUser', through: :account, source: :oauth_users
8
+ has_many :medias, class_name: 'Wechat::Media'
9
+ has_many :subscribes, ->{ where(sending_at: nil).order(id: :asc) }, class_name: 'Wechat::Subscribe', through: :program_users
10
+ end
11
+
12
+ def invite_scene(app, prefix = 'invite_member')
13
+ scene = Scene.find_or_initialize_by(appid: app.appid, match_value: "#{prefix}_#{id}")
14
+ scene.expire_seconds ||= 2592000
15
+ scene.organ_id = app.organ_id
16
+ scene.save
17
+ scene
18
+ end
19
+
20
+ end
21
+ end
@@ -5,7 +5,7 @@ module Wechat
5
5
  included do
6
6
  attribute :limit_wechat, :integer, default: 1
7
7
  attribute :limit_wechat_menu, :integer, default: 1
8
- has_many :apps, class_name: 'Wechat::App', dependent: :destroy
8
+ has_many :apps, class_name: 'Wechat::App', dependent: :destroy_async
9
9
 
10
10
  validates :limit_wechat_menu, inclusion: { in: [1, 2, 3] }
11
11
  end
@@ -3,8 +3,8 @@ module Wechat
3
3
  extend ActiveSupport::Concern
4
4
 
5
5
  included do
6
- has_many :wechat_users, class_name: 'Wechat::WechatUser', through: :accounts
7
- has_many :program_users, class_name: 'Wechat::ProgramUser'
6
+ has_many :wechat_users, class_name: 'Wechat::WechatUser', through: :accounts, source: :oauth_users
7
+ has_many :program_users, class_name: 'Wechat::ProgramUser', through: :accounts, source: :oauth_users
8
8
  has_many :medias, class_name: 'Wechat::Media'
9
9
  has_many :subscribes, ->{ where(sending_at: nil).order(id: :asc) }, class_name: 'Wechat::Subscribe', through: :program_users
10
10
  end
@@ -3,7 +3,7 @@ module Wechat
3
3
  extend ActiveSupport::Concern
4
4
 
5
5
  included do
6
- has_many :tags, class_name: 'Wechat::Tag', dependent: :destroy
6
+ has_many :tags, class_name: 'Wechat::Tag', dependent: :destroy_async
7
7
 
8
8
  after_save_commit :sync_tag_later, if: -> { saved_change_to_name? }
9
9
  end
@@ -2,18 +2,17 @@ module Wechat
2
2
  module Model::App::PublicApp
3
3
 
4
4
  def sync_templates
5
- templates = api.templates
6
- templates.each do |template|
5
+ api.templates.each do |template|
7
6
  template = templates.find_or_initialize_by(template_id: template['template_id'])
8
7
  template.assign_attributes template.slice('title', 'content', 'example')
9
8
  template.save
10
9
  end
11
10
  end
12
11
 
13
- def oauth2_url(scope = 'snsapi_userinfo', state: SecureRandom.hex(16), **host_options)
12
+ def oauth2_url(scope = 'snsapi_userinfo', state: SecureRandom.hex(16), host: self.host, **host_options)
14
13
  h = {
15
14
  appid: appid,
16
- redirect_uri: Rails.application.routes.url_for(controller: 'wechat/apps', action: 'login', id: id, **host_options),
15
+ redirect_uri: Rails.application.routes.url_for(controller: 'wechat/apps', action: 'login', id: id, host: host, **host_options),
17
16
  response_type: 'code',
18
17
  scope: scope,
19
18
  state: state
@@ -6,7 +6,9 @@ module Wechat
6
6
  attribute :type, :string, default: 'Wechat::PublicApp'
7
7
  attribute :name, :string
8
8
  attribute :enabled, :boolean, default: true
9
- attribute :shared, :boolean, default: false
9
+ attribute :shared, :boolean, default: false, comment: '可与其他或下级机构公用'
10
+ attribute :oauth_enable, :boolean, default: true
11
+ attribute :inviting, :boolean, default: false, comment: '可邀请加入'
10
12
  attribute :appid, :string
11
13
  attribute :secret, :string
12
14
  attribute :token, :string, default: -> { SecureRandom.hex }
@@ -22,10 +24,11 @@ module Wechat
22
24
  attribute :oauth2_state, :string
23
25
  attribute :jsapi_ticket_expires_at, :datetime
24
26
  attribute :user_name, :string
25
- attribute :oauth_enable, :boolean, default: true
26
27
  attribute :apiclient_cert, :string
27
28
  attribute :apiclient_key, :string
28
29
  attribute :serial_no, :string
30
+ attribute :domain, :string
31
+ attribute :url_link, :string
29
32
 
30
33
  belongs_to :organ, class_name: 'Org::Organ', optional: true
31
34
 
@@ -41,8 +44,9 @@ module Wechat
41
44
  has_many :tags, foreign_key: :appid, primary_key: :appid
42
45
  has_many :templates, foreign_key: :appid, primary_key: :appid
43
46
 
44
- scope :valid, -> { where(enabled: true) }
47
+ scope :enabled, -> { where(enabled: true) }
45
48
  scope :shared, -> { where(shared: true) }
49
+ scope :inviting, -> { where(inviting: true) }
46
50
 
47
51
  validates :appid, presence: true, uniqueness: true
48
52
 
@@ -190,7 +194,7 @@ module Wechat
190
194
 
191
195
  def host
192
196
  if oauth_enable
193
- organ_domain&.identifier || organ_domains.first&.identifier
197
+ domain.presence || organ_domain&.identifier || organ_domains.first&.identifier
194
198
  end
195
199
  end
196
200
 
@@ -1,14 +1,9 @@
1
1
  module Wechat
2
2
  module Model::Menu::ClickMenu
3
- extend ActiveSupport::Concern
4
-
5
- included do
6
- attribute :menu_type, :string, default: 'click'
7
- end
8
3
 
9
4
  def as_json
10
5
  {
11
- type: menu_type,
6
+ type: 'click',
12
7
  name: name,
13
8
  key: value
14
9
  }
@@ -1,14 +1,9 @@
1
1
  module Wechat
2
2
  module Model::Menu::MiniProgramMenu
3
- extend ActiveSupport::Concern
4
-
5
- included do
6
- attribute :menu_type, :string, default: 'miniprogram'
7
- end
8
3
 
9
4
  def as_json
10
5
  {
11
- type: menu_type,
6
+ type: 'miniprogram',
12
7
  name: name,
13
8
  url: value,
14
9
  appid: mp_appid,
@@ -1,14 +1,9 @@
1
1
  module Wechat
2
2
  module Model::Menu::ScanPushMenu
3
- extend ActiveSupport::Concern
4
-
5
- included do
6
- attribute :menu_type, :string, default: 'scancode_push'
7
- end
8
3
 
9
4
  def as_json
10
5
  {
11
- type: menu_type,
6
+ type: 'scancode_push',
12
7
  name: name,
13
8
  key: value
14
9
  }
@@ -1,14 +1,9 @@
1
1
  module Wechat
2
2
  module Model::Menu::ScanWaitMenu
3
- extend ActiveSupport::Concern
4
-
5
- included do
6
- attribute :menu_type, :string, default: 'scancode_waitmsg'
7
- end
8
3
 
9
4
  def as_json
10
5
  {
11
- type: menu_type,
6
+ type: 'scancode_waitmsg',
12
7
  name: name,
13
8
  key: value
14
9
  }
@@ -3,7 +3,6 @@ module Wechat
3
3
  extend ActiveSupport::Concern
4
4
 
5
5
  included do
6
- attribute :menu_type, :string, default: 'view'
7
6
  after_initialize if: :new_record? do
8
7
  self.value ||= host
9
8
  end
@@ -11,7 +10,7 @@ module Wechat
11
10
 
12
11
  def as_json
13
12
  {
14
- type: menu_type,
13
+ type: 'view',
15
14
  name: name,
16
15
  url: url
17
16
  }
@@ -4,7 +4,6 @@ module Wechat
4
4
 
5
5
  included do
6
6
  attribute :type, :string
7
- attribute :menu_type, :string
8
7
  attribute :name, :string
9
8
  attribute :value, :string
10
9
  attribute :appid, :string
@@ -16,7 +15,7 @@ module Wechat
16
15
  belongs_to :parent, class_name: self.base_class.name, optional: true
17
16
  has_many :children, class_name: self.base_class.name, foreign_key: :parent_id, dependent: :nullify
18
17
 
19
- has_many :scene_menus, dependent: :destroy
18
+ has_many :scene_menus, dependent: :destroy_async
20
19
  accepts_nested_attributes_for :scene_menus, allow_destroy: true
21
20
 
22
21
  scope :roots, -> { where(parent_id: nil) }
@@ -4,8 +4,6 @@ module Wechat
4
4
 
5
5
  included do
6
6
  attribute :provider, :string, default: 'wechat_program'
7
-
8
- belongs_to :app, foreign_key: :appid, primary_key: :appid
9
7
  end
10
8
 
11
9
  def get_phone_number(encrypted_data, iv, session_key)
@@ -20,9 +18,13 @@ module Wechat
20
18
 
21
19
  def auth_token(session_key = nil)
22
20
  at = authorized_tokens.valid.take || authorized_tokens.build
21
+ at.identity = identity if identity.present?
23
22
  at.session_key = session_key if session_key.present?
24
- at.save
25
- at.token
23
+ self.class.transaction do
24
+ self.save!
25
+ at.save!
26
+ end
27
+ at
26
28
  end
27
29
 
28
30
  end
@@ -5,20 +5,30 @@ module Wechat
5
5
  included do
6
6
  attribute :provider, :string, default: 'wechat'
7
7
  attribute :remark, :string
8
-
9
- belongs_to :request, optional: true
10
- belongs_to :app, foreign_key: :app_id, primary_key: :appid, optional: true
11
-
12
- has_many :requests, foreign_key: :open_id, primary_key: :uid
8
+ attribute :name, :string
9
+ attribute :avatar_url, :string
10
+ attribute :appid, :string
11
+ attribute :uid, :string, index: true
12
+ attribute :unionid, :string, index: true
13
+ attribute :access_token, :string
14
+ attribute :expires_at, :datetime
15
+ attribute :refresh_token, :string
16
+
17
+ belongs_to :app, foreign_key: :appid, primary_key: :appid, optional: true
18
+ belongs_to :user_inviter, class_name: 'Auth::User', optional: true
19
+ belongs_to :member_inviter, class_name: 'Org::Member', optional: true
20
+
21
+ has_one :request, -> { where(init_wechat_user: true) }, foreign_key: :open_id, primary_key: :uid
22
+ has_many :requests, foreign_key: :open_id, primary_key: :uid, dependent: :destroy_async
13
23
  has_many :subscribes, dependent: :delete_all
14
- has_many :user_tags, foreign_key: :open_id, primary_key: :uid, dependent: :destroy
24
+ has_many :user_tags, foreign_key: :open_id, primary_key: :uid, dependent: :destroy_async
15
25
  has_many :tags, through: :user_tags
16
26
  has_many :notices, foreign_key: :open_id, primary_key: :uid
17
27
 
18
28
  after_save_commit :sync_remark_later, if: -> { saved_change_to_remark? }
19
29
  after_save_commit :sync_user_info_later, if: -> { saved_change_to_access_token? && (attributes['name'].blank? && attributes['avatar_url'].blank?) }
20
- after_save_commit :sync_inviter, if: -> { request && saved_change_to_request_id? }
21
- after_create_commit :auto_link, if: -> { unionid.present? }
30
+ after_save_commit :auto_join_organ, if: -> { member_inviter && saved_change_to_identity? }
31
+ after_save_commit :auto_link, if: -> { unionid.present? && saved_change_to_unionid? }
22
32
  end
23
33
 
24
34
  def name
@@ -31,15 +41,16 @@ module Wechat
31
41
 
32
42
  def auto_link
33
43
  if self.unionid && self.same_oauth_user
34
- self.account ||= same_oauth_user.account
44
+ self.identity ||= same_oauth_user.identity
45
+ self.name ||= same_oauth_user.name
46
+ self.avatar_url ||= same_oauth_user.avatar_url
35
47
  end
36
48
  self.save
37
49
  end
38
50
 
39
- def sync_inviter
40
- inviter_id = request.body.delete_prefix 'invite_by_'
41
- self.account&.update inviter_id: inviter_id
42
- self.user&.update inviter_id: inviter_id
51
+ def auto_join_organ
52
+ member = members.find_by(organ_id: member_inviter.organ_id) || members.build(organ_id: member_inviter.organ_id)
53
+ member.save
43
54
  end
44
55
 
45
56
  def sync_remark_later
@@ -77,7 +88,7 @@ module Wechat
77
88
 
78
89
  def refresh_access_token
79
90
  params = {
80
- appid: app_id,
91
+ appid: appid,
81
92
  grant_type: 'refresh_token',
82
93
  refresh_token: refresh_token
83
94
  }
@@ -97,7 +108,7 @@ module Wechat
97
108
 
98
109
  raw_info = oauth_params.dig('extra', 'raw_info') || {}
99
110
  self.unionid = raw_info['unionid']
100
- self.app_id ||= raw_info['app_id']
111
+ self.appid ||= raw_info['app_id']
101
112
 
102
113
  credential_params = oauth_params.fetch('credentials', {})
103
114
  self.access_token = credential_params['token']
@@ -77,13 +77,11 @@ module Wechat
77
77
  end
78
78
 
79
79
  def parse_content
80
- build_request(type: compute_type)
80
+ request || build_request(type: compute_type)
81
81
  request.appid = appid
82
82
  request.open_id = open_id
83
- request.generate_wechat_user # Should before get reply
84
83
  request.msg_type = msg_type
85
84
  request.raw_body = message_hash.except('ToUserName', 'FromUserName', 'CreateTime', 'MsgType')
86
-
87
85
  case msg_type
88
86
  when 'text'
89
87
  request.body = message_hash['Content']
@@ -108,6 +106,7 @@ module Wechat
108
106
  else
109
107
  warn "Don't know how to parse message as #{message_hash['MsgType']}", uplevel: 1
110
108
  end
109
+ request.generate_wechat_user # Should before get reply
111
110
 
112
111
  self.save # will auto save wechat request
113
112
  end